[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/javaimp 9f8e85fd58: Make navigation functions move over
From: |
Filipp Gunbin |
Subject: |
[elpa] externals/javaimp 9f8e85fd58: Make navigation functions move over entire defun declaration |
Date: |
Wed, 11 May 2022 16:47:52 -0400 (EDT) |
branch: externals/javaimp
commit 9f8e85fd58e357441658137c35d4b81d12ad495e
Author: Filipp Gunbin <fgunbin@fastmail.fm>
Commit: Filipp Gunbin <fgunbin@fastmail.fm>
Make navigation functions move over entire defun declaration
---
javaimp-parse.el | 46 ++++++++++++++++++++++++++++++-
javaimp.el | 84 +++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 100 insertions(+), 30 deletions(-)
diff --git a/javaimp-parse.el b/javaimp-parse.el
index 5433bebe6a..a5aa0af599 100644
--- a/javaimp-parse.el
+++ b/javaimp-parse.el
@@ -91,6 +91,9 @@ anything in the buffer. A marker pointing nowhere means
everything's up-to-date.")
+
+;; Low-level subroutines
+
(defsubst javaimp-parse--substr-before-< (str)
(let ((end (string-search "<" str)))
(if end
@@ -246,6 +249,38 @@ is unchanged."
(goto-char pos)
nil)))
+(defun javaimp-parse--decl-prefix (&optional bound)
+ "Attempt to parse defun declaration prefix backwards from
+point (but not farther than BOUND). Matches inside comments /
+strings are skipped. Return the beginning of the match (then the
+point is also at that position) or nil (then the point is left
+unchanged)."
+ ;; If we skip a previous scope (including unnamed initializers), or
+ ;; reach enclosing scope start, we'll fail the check in the below
+ ;; loop. But a semicolon, which delimits statements, will just be
+ ;; skipped by scan-sexps, so find it and use as bound. If it is in
+ ;; another scope, that's not a problem, for the same reasons as
+ ;; described above.
+ (let* ((prev-semi (save-excursion
+ (javaimp-parse--rsb-keyword ";" bound t)))
+ (bound (when (or bound prev-semi)
+ (apply #'max
+ (delq nil
+ (list bound
+ (and prev-semi (1+ prev-semi)))))))
+ pos res)
+ (with-syntax-table javaimp--arglist-syntax-table
+ (while (and (ignore-errors
+ (setq pos (scan-sexps (point) -1)))
+ (or (not bound) (>= pos bound))
+ (or (member (char-after pos)
+ '(?@ ?\( ;annotation type / args
+ ?<)) ;generic type
+ ;; keyword / identifier first char
+ (= (char-syntax pos) ?w)))
+ (goto-char (setq res pos))))
+ res))
+
;;; Scopes
@@ -668,6 +703,15 @@ it with PRED, and its parents with PARENT-PRED."
(javaimp-scope-filter-parents scope parent-pred))
scope))
+(defun javaimp-parse-get-defun-decl-start (&optional bound)
+ "Return the position of the start of defun declaration at point,
+but not before BOUND. Point should be at defun name, but
+actually can be anywhere within the declaration, as long as it's
+outside paren constructs like arg-list."
+ (save-excursion
+ (javaimp-parse--all-scopes))
+ (javaimp-parse--decl-prefix bound))
+
(defun javaimp-parse-get-class-abstract-methods ()
"Return all scopes which are abstract methods in classes."
(javaimp-parse--all-scopes)
@@ -683,12 +727,12 @@ it with PRED, and its parents with PARENT-PRED."
(seq-mapcat #'javaimp-parse--interface-abstract-methods
interfaces)))
+
(defun javaimp-parse-fully-parsed-p ()
"Return non-nil if current buffer is fully parsed."
(and javaimp-parse--dirty-pos
(not (marker-position javaimp-parse--dirty-pos))))
-
(defmacro javaimp-parse-without-hook (&rest body)
"Execute BODY, temporarily removing
`javaimp-parse--update-dirty-pos' from `after-change-functions'
diff --git a/javaimp.el b/javaimp.el
index c68729864f..40c6b4dd01 100644
--- a/javaimp.el
+++ b/javaimp.el
@@ -1063,35 +1063,59 @@ buffer."
"Function to be used as `beginning-of-defun-function'."
(if (zerop arg)
t
- (when (> arg 0) (setq arg (1- arg)))
(let* ((ctx (javaimp--get-sibling-context))
- (prev-idx (or (nth 2 ctx) -1))
- (siblings (nthcdr 3 ctx))
- (target-idx (- prev-idx arg)))
+ (parent-beg (nth 0 ctx))
+ (parent-end (nth 1 ctx))
+ (offset-from-prev (if (> arg 0)
+ (1- arg)
+ arg))
+ (target-idx (- (nth 2 ctx) offset-from-prev))
+ (siblings (nthcdr 3 ctx)))
(cond ((or (not siblings) (< target-idx 0))
- (goto-char (nth 0 ctx))
- nil)
+ (when (= (abs arg) 1)
+ ;; Special case: ok to move to floor. If there's
+ ;; parent - try to skip its decl prefix too.
+ (goto-char (if parent-beg
+ (or (javaimp--beg-of-defun-decl parent-beg)
+ parent-beg)
+ (point-min)))))
((>= target-idx (length siblings))
- (goto-char (nth 1 ctx))
- nil)
+ (when (= (abs arg) 1)
+ ;; Special case: ok to move to ceil.
+ (goto-char (or parent-end (point-max)))))
(t
- (goto-char (javaimp-scope-open-brace
- (nth target-idx siblings))))))))
+ (let ((scope (nth target-idx siblings)))
+ (goto-char (or (javaimp--beg-of-defun-decl
+ (javaimp-scope-start scope) parent-beg)
+ (javaimp-scope-open-brace scope)))))))))
+
+(defun javaimp--beg-of-defun-decl (pos &optional bound)
+ "Subroutine of `javaimp-beginning-of-defun'."
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char pos)
+ (javaimp-parse-get-defun-decl-start bound))))
(defun javaimp-end-of-defun ()
"Function to be used as `end-of-defun-function'."
- (when (javaimp-scope-p
- (get-text-property (point) 'javaimp-parse-scope))
+ (when-let* ((brace-pos
+ (next-single-property-change (point) 'javaimp-parse-scope))
+ ((get-text-property brace-pos 'javaimp-parse-scope)))
(ignore-errors
(goto-char
- (scan-lists (point) 1 0)))))
+ (scan-lists brace-pos 1 0)))))
(defun javaimp--get-sibling-context ()
- "Return list of the form (FLOOR CEILING PREV-INDEX . SIBLINGS),
-where SIBLINGS is a list of all sibling defun scopes. PREV-INDEX
-is the index of the \"previous\" (relative to point) scope in
-this list, or nil. FLOOR and CEILING are positions before and
-after this group of defuns."
+ "Return list of the form (PARENT-BEG PARENT-END PREV-INDEX .
+ SIBLINGS), where SIBLINGS is a list of all sibling defun scopes.
+PREV-INDEX is the index of the \"previous\" (relative to point)
+scope in this list, or -1. PARENT-BEG and PARENT-END are the
+positions of beginning and end of parent defun, if any.
+
+Both when we're inside a method and between methods, the parent
+is the method's enclosing class. When we're inside the method,
+PREV-INDEX gives the index of the method itself."
(save-excursion
(save-restriction
(widen)
@@ -1109,10 +1133,9 @@ after this group of defuns."
;; defuns whose parent is enc.
enc))
(parent-beg (and parent (javaimp-scope-open-brace parent)))
- (parent-end (and parent
- (ignore-errors
- (scan-lists
- (javaimp-scope-open-brace parent) 1 0))))
+ (parent-end (when parent-beg
+ (ignore-errors
+ (scan-lists parent-beg 1 0))))
(sibling-pred (javaimp-scope-same-parent-p parent))
(siblings
(javaimp-parse-get-all-scopes
@@ -1131,13 +1154,16 @@ after this group of defuns."
(reverse siblings)))))
(nconc
(list
- (or parent-beg (point-min))
- (or parent-end (point-max))
- (and prev
- (seq-position siblings prev
- (lambda (s1 s2)
- (= (javaimp-scope-open-brace s1)
- (javaimp-scope-open-brace s2))))))
+ ;; Return start, not open brace, as this is where we'll go
+ ;; when no sibling
+ (and parent (javaimp-scope-start parent))
+ parent-end
+ (or (and prev
+ (seq-position siblings prev
+ (lambda (s1 s2)
+ (= (javaimp-scope-open-brace s1)
+ (javaimp-scope-open-brace s2)))))
+ -1))
siblings)))))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/javaimp 9f8e85fd58: Make navigation functions move over entire defun declaration,
Filipp Gunbin <=