branch: scratch/javaimp-wip
commit 606cb3f08a10bf5e6571657fbec6b13f019a5ead
Author: Filipp Gunbin <[email protected]>
Commit: Filipp Gunbin <[email protected]>
*** 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