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