branch: scratch/javaimp-wip commit 52c6c71b93ee165b757aa7b22c6044621377d68f Author: Filipp Gunbin <fgun...@okko.tv> Commit: Filipp Gunbin <fgun...@okko.tv>
*** empty log message *** --- javaimp-parse.el | 45 +++++++++++++++++++++++++++++++++--- javaimp.el | 69 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 88 insertions(+), 26 deletions(-) diff --git a/javaimp-parse.el b/javaimp-parse.el index 65a31cb422..a07c059267 100644 --- a/javaimp-parse.el +++ b/javaimp-parse.el @@ -374,6 +374,7 @@ it's set to 'unknown' too." (javaimp-scope-start scope)) (goto-char (javaimp-scope-start scope))))) (setq state (syntax-ppss)))) + ;; FIXME don't do this every time (let (parent reset-tail) (while res (if reset-tail @@ -391,9 +392,9 @@ it's set to 'unknown' too." parent))) (defun javaimp--parse-all-scopes () - "Entry point to the scope parsing. Parses scopes in this buffer -which are after `javaimp--parse-dirty-pos', if it points -anywhere. Makes it point nowhere when done." + "Parses all scopes in this buffer which are after +`javaimp--parse-dirty-pos', if it points anywhere. Makes it +point nowhere when done." (unless javaimp--parse-dirty-pos (setq javaimp--parse-dirty-pos (point-min-marker)) (javaimp--parse-setup-buffer)) @@ -419,6 +420,33 @@ anywhere. Makes it point nowhere when done." (setq-local multibyte-syntax-as-symbol t) (add-hook 'after-change-functions #'javaimp--parse-update-dirty-pos)) +(defun javaimp--parse-enclosing-scope (&optional pred) + "Return innermost enclosing scope matching PRED. This function +is intended to use already set properties." + (when (or (not javaimp--parse-dirty-pos) + (marker-position javaimp--parse-dirty-pos)) + (error "Call javaimp--parse-all-scopes first")) + (with-syntax-table javaimp-syntax-table + (let ((state (syntax-ppss))) + ;; Move out of any comment/string + (when (nth 8 ppss) + (goto-char (nth 8 ppss)) + (setq state (syntax-ppss))) + ;; Go up until we get something + (catch 'found + (while t + (let ((res (save-excursion + (javaimp--parse-scopes nil)))) + (when (and (javaimp-scope-p res) + (or (null pred) + (funcall pred res))) + (throw 'found res)) + (if (nth 1 state) + (progn + (goto-char (nth 1 state)) + (setq state (syntax-ppss))) + (throw 'found nil)))))))) + (defun javaimp--parse-class-abstract-methods () (goto-char (point-max)) (let (res) @@ -518,6 +546,17 @@ them should move point." (push scope res))) 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." + (save-excursion + (javaimp--parse-all-scopes)) + (when-let ((scope (javaimp--parse-enclosing-scope pred))) + (setq scope (javaimp--copy-scope scope)) + (when parent-pred + (javaimp--filter-scope-parents scope parent-pred)) + scope)) + (defun javaimp--parse-get-class-abstract-methods () (javaimp--parse-all-scopes) (javaimp--parse-class-abstract-methods)) diff --git a/javaimp.el b/javaimp.el index 43b9cbd38b..81d9d6d11d 100644 --- a/javaimp.el +++ b/javaimp.el @@ -573,11 +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--parse-get-all-scopes - (lambda (scope) - (javaimp-test-scope-type scope - javaimp--classlike-scope-types - javaimp--classlike-scope-types))))) + (scopes (javaimp--get-defun-scopes t))) (mapcar (lambda (class) (if package (concat package "." class) @@ -721,19 +717,15 @@ in a major mode hook." entries))))) (defun javaimp-imenu--get-forest () - (let* ((scopes (javaimp--parse-get-all-scopes - (lambda (scope) - (javaimp-test-scope-type scope - `(,@ javaimp--classlike-scope-types method) - javaimp--classlike-scope-types)))) + (let* ((defun-scopes (javaimp--get-defun-scopes)) (methods (seq-filter (lambda (scope) (eq (javaimp-scope-type scope) 'method)) - scopes)) + defun-scopes)) (classes (seq-filter (lambda (scope) (not (eq (javaimp-scope-type scope) 'method))) - scopes)) + defun-scopes)) (top-classes (seq-filter (lambda (s) (null (javaimp-scope-parent s))) classes)) @@ -816,22 +808,14 @@ opening brace." (define-derived-mode javaimp-show-scopes-mode special-mode "Javaimp Show Scopes" (setq next-error-function #'javaimp-show-scopes-next-error)) -(defun javaimp-show-scopes (&optional show-all) - "Show scopes in *javaimp-scopes* buffer, with clickable text. -By default, the scopes are only those which appear in -Imenu (`javaimp-imenu-create-index' is responsible for that), but -with prefix arg, show all scopes." +(defun javaimp-show-scopes () + "Show scopes in *javaimp-scopes* buffer." (interactive "P") (let ((scopes (save-excursion (save-restriction (widen) - (javaimp--parse-get-all-scopes - (unless show-all - (lambda (scope) - (javaimp-test-scope-type scope - `(,@ javaimp--classlike-scope-types method) - javaimp--classlike-scope-types))))))) + (javaimp--get-defun-scopes)))) (source-buf (current-buffer)) (source-default-dir default-directory) (buf (get-buffer-create "*javaimp-scopes*"))) @@ -890,6 +874,35 @@ with prefix arg, show all scopes." +;; Navigation + +(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)))) + +(defun javaimp-end-of-defun () + "Function to be used as `end-of-defun-function'." + ;; TODO where we start? + ) + + + ;; Misc (defun javaimp-flush-cache () @@ -898,6 +911,16 @@ with prefix arg, show all scopes." (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