emacs-elpa-diffs
[Top][All Lists]
Advanced

[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)))))
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]