branch: scratch/javaimp-wip
commit 606cb3f08a10bf5e6571657fbec6b13f019a5ead
Author: Filipp Gunbin <fgun...@okko.tv>
Commit: Filipp Gunbin <fgun...@okko.tv>
    *** empty log message ***
---
 javaimp-parse.el |  4 +--
 javaimp-util.el  |  7 +++++
 javaimp.el       | 86 ++++++++++++++++++++++++++++++++++++--------------------
 3 files changed, 65 insertions(+), 32 deletions(-)

diff --git a/javaimp-parse.el b/javaimp-parse.el
index a07c059267..89b296b2b5 100644
--- a/javaimp-parse.el
+++ b/javaimp-parse.el
@@ -547,8 +547,8 @@ them should move point."
     res))
 
 (defun javaimp--parse-get-enclosing-scope (&optional pred parent-pred)
-  "Return innermost enclosing scope at point which satisfies PRED,
-with parents filtered by PARENT-PRED."
+  "Return innermost enclosing scope at point, optionally checking
+it with PRED, and its parents with PARENT-PRED."
   (save-excursion
     (javaimp--parse-all-scopes))
   (when-let ((scope (javaimp--parse-enclosing-scope pred)))
diff --git a/javaimp-util.el b/javaimp-util.el
index 0379a9e308..df9913a9ef 100644
--- a/javaimp-util.el
+++ b/javaimp-util.el
@@ -153,6 +153,13 @@ left."
       (setq res (memq (javaimp-scope-type scope) parent-types)))
     res))
 
+(defun javaimp--defun-scope-pred (&optional only-classes)
+  (let ((leaf-types (append javaimp--classlike-scope-types
+                            (unless only-classes '(method)))))
+    (lambda (s)
+      (javaimp-test-scope-type s
+        leaf-types javaimp--classlike-scope-types))))
+
 
 ;; Tree
 
diff --git a/javaimp.el b/javaimp.el
index 81d9d6d11d..082773d7b4 100644
--- a/javaimp.el
+++ b/javaimp.el
@@ -573,7 +573,7 @@ If there's no such directive, then the last resort is just
   "Return fully-qualified names of all class-like scopes in the
 current buffer."
   (let ((package (javaimp--parse-get-package))
-        (scopes (javaimp--get-defun-scopes t)))
+        (scopes (javaimp--parse-get-all-scopes (javaimp--defun-scope-pred t)))
     (mapcar (lambda (class)
               (if package
                   (concat package "." class)
@@ -717,7 +717,8 @@ in a major mode hook."
               entries)))))
 
 (defun javaimp-imenu--get-forest ()
-  (let* ((defun-scopes (javaimp--get-defun-scopes))
+  (let* ((defun-scopes
+          (javaimp--parse-get-all-scopes (javaimp--defun-scope-pred)))
          (methods (seq-filter
                    (lambda (scope)
                      (eq (javaimp-scope-type scope) 'method))
@@ -815,7 +816,7 @@ opening brace."
          (save-excursion
            (save-restriction
              (widen)
-             (javaimp--get-defun-scopes))))
+             (javaimp--parse-get-all-scopes (javaimp--defun-scope-pred)))))
         (source-buf (current-buffer))
         (source-default-dir default-directory)
         (buf (get-buffer-create "*javaimp-scopes*")))
@@ -878,29 +879,64 @@ opening brace."
 
 (defun javaimp-beginning-of-defun (arg)
   "Function to be used as `beginning-of-defun-function'."
-  (unless (zerop arg)
-    (let (enclosing scopes)
-      (save-excursion
-        (save-restriction
-          (widen)
-          ;; TODO pass pred
-          (setq enclosing (javaimp--parse-get-enclosing-scope)
-                ;; TODO leave only enclosing's siblings
-                scopes (javaimp--get-defun-scopes))))
-      ;; TODO leave siblings from enclosing in scopes; take ARGth
-      ;; relative sibling;
-
-      ;; ? if not found
-      (goto-char (if (< 0 arg)
-                     (point-min)
-                   (point-max)))
-    (zerop arg))))
+  (if (zerop arg)
+      t
+    (when (> arg 0) (setq arg (1- arg)))
+    (let (found)
+      (when-let* ((tmp (javaimp--get-sibling-defuns))
+                  (enc-idx (car tmp))
+                  (siblings (cdr tmp))
+                  (target-idx
+                   (let ((val (- enc-idx arg)))
+                     (cond ((< val 0)
+                            0)
+                           ((>= val (length siblings))
+                            (1- (length siblings)))
+                           (t
+                            (setq found t)
+                            val)))))
+        (goto-char (javaimp-scope-open-brace
+                    (nth target-idx siblings))))
+      found)))
 
 (defun javaimp-end-of-defun ()
   "Function to be used as `end-of-defun-function'."
   ;; TODO where we start?
   )
 
+(defun javaimp--get-sibling-defuns ()
+  "Return list of the form (ENCLOSING-INDEX . SIBLINGS), where
+SIBLINGS is a list of all sibling defun scopes.  ENCLOSING-INDEX,
+if non-nil, is an index of the enclosing scope in this list.  If
+it's nil then we're between top-level defuns."
+  (save-excursion
+    (save-restriction
+      (widen)
+      (let* ((defun-pred (javaimp--defun-scope-pred))
+             (enc (javaimp--parse-get-enclosing-scope defun-pred))
+             (sibling-pred
+              (if (and enc (javaimp-scope-parent enc))
+                  ;; scopes with same parent
+                  (lambda (s)
+                    (and (javaimp-scope-parent s)
+                         (= (javaimp-scope-open-brace (javaimp-scope-parent s))
+                            (javaimp-scope-open-brace (javaimp-scope-parent 
enc)))))
+                ;; we're in a top-level scope or outside it, and
+                ;; need other top-level scopes
+                (lambda (s)
+                  (not (javaimp-scope-parent s)))))
+             (siblings (javaimp--parse-get-all-scopes
+                        (lambda (s)
+                          (and (funcall defun-pred s)
+                               (funcall sibling-pred s))))))
+        (cons (and enc
+                   (seq-position
+                    siblings enc
+                    (lambda (s1 s2)
+                      (= (javaimp-scope-open-brace s1)
+                         (javaimp-scope-open-brace s2)))))
+              siblings)))))
+
 
 
 ;; Misc
@@ -911,16 +947,6 @@ opening brace."
   (setq javaimp-jar-file-cache nil
         javaimp-source-file-cache nil))
 
-
-;; TODO cache
-(defun javaimp--get-defun-scopes (&optional only-classes)
-  (let ((types (append javaimp--classlike-scope-types
-                       (unless only-classes '(method)))))
-    (javaimp--parse-get-all-scopes
-     (lambda (scope)
-       (javaimp-test-scope-type scope
-         types javaimp--classlike-scope-types)))))
-
 (provide 'javaimp)
 
 ;;; javaimp.el ends here

Reply via email to