branch: scratch/javaimp-wip commit aa0f9324cddc5cb13f9f4239b52cf6182e13a7c1 Author: Filipp Gunbin <fgun...@fastmail.fm> Commit: Filipp Gunbin <fgun...@fastmail.fm>
wip --- javaimp-parse.el | 51 +++++++++++++++++++++++++++++++++------------------ javaimp-util.el | 7 ++++--- javaimp.el | 21 ++++++--------------- 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/javaimp-parse.el b/javaimp-parse.el index ca8a77c..55c89f2 100644 --- a/javaimp-parse.el +++ b/javaimp-parse.el @@ -59,6 +59,10 @@ present." st) "Enables parsing angle brackets as lists") +(defvar-local javaimp--parse-dirty-pos nil + "Buffer position after which all parsed information should be +considered as stale. Usually set by modification change hooks.") + (defmacro javaimp--parse-with-arglist-syntax (beg &rest body) (declare (debug t)) (let ((begin (make-symbol "begin"))) @@ -420,33 +424,34 @@ nil then goes all the way up. Examines and sets property (setq tmp (cdr tmp)))) res)) - -;; Main - -(defun javaimp--parse-get-package () - (goto-char (point-max)) - (when (javaimp--parse-rsb-keyword - "^\\s-*package\\s-+\\([^;\n]+\\)\\s-*;" nil t 1) - (match-string 1))) - - (defun javaimp--parse-all-scopes () - "Parses all scopes in a buffer." + "Parses all scopes in this buffer, but only after +`javaimp--parse-dirty-pos' if it is non-nil." + (when javaimp--parse-dirty-pos + (remove-text-properties javaimp--parse-dirty-pos (point-max) + '(javaimp-parse-scope nil))) (goto-char (point-max)) (let ((parse-sexp-ignore-comments t) ; FIXME remove with major mode (parse-sexp-lookup-properties nil)) - (while (javaimp--parse-rsb-keyword "{" nil t) + (while (javaimp--parse-rsb-keyword "{" javaimp--parse-dirty-pos t) (save-excursion (forward-char) ;; Set props at this brace and all the way up - (javaimp--parse-scopes nil))))) + (javaimp--parse-scopes nil)))) + (setq javaimp--parse-dirty-pos nil)) -(defun javaimp--parse-clean-all-scopes () - (remove-text-properties (point-min) (point-max) - '(javaimp-parse-scope nil))) + +;; Functions intended to be called from other parts of javaimp. + +(defun javaimp--parse-get-package () + (goto-char (point-max)) + (when (javaimp--parse-rsb-keyword + "^\\s-*package\\s-+\\([^;\n]+\\)\\s-*;" nil t 1) + (match-string 1))) (defun javaimp--parse-get-file-classes () + (javaimp--parse-all-scopes) (goto-char (point-max)) (let (match res) (while (setq match (text-property-search-backward @@ -457,15 +462,19 @@ nil then goes all the way up. Examines and sets property ".") res))))) -(defun javaimp--parse-get-all-scopes() +(defun javaimp--parse-get-all-scopes (&optional reparse) + (when reparse + (setq javaimp--parse-dirty-pos (point-min))) + (javaimp--parse-all-scopes) (goto-char (point-max)) - (let (res) + (let (match res) (while (setq match (text-property-search-backward 'javaimp-parse-scope nil nil)) (push (prop-match-value match) res)) res)) (defun javaimp--parse-get-forest-for-imenu () + (javaimp--parse-all-scopes) (goto-char (point-max)) (let (match methods classes top-classes) (while (setq match (text-property-search-backward @@ -490,4 +499,10 @@ nil then goes all the way up. Examines and sets property (equal el (javaimp-scope-parent tested))))) top-classes))) +(defun javaimp--parse-update-dirty-pos (beg _end _old-len) + "Function to add to `after-change-functions' hook." + (when (or (not javaimp--parse-dirty-pos) + (< beg javaimp--parse-dirty-pos)) + (setq javaimp--parse-dirty-pos beg))) + (provide 'javaimp-parse) diff --git a/javaimp-util.el b/javaimp-util.el index 5e63c01..f2b4dda 100644 --- a/javaimp-util.el +++ b/javaimp-util.el @@ -187,7 +187,8 @@ PARENT-NODE is indented for recursive calls." tree))) (apply #'seq-concatenate 'list (mapcar (lambda (child) - (javaimp--collect-nodes-from-tree child predicate)) + (javaimp--collect-nodes-from-tree + child predicate unwrap)) (javaimp-node-children tree)))))) (defun javaimp--map-nodes (mapper forest &optional unwrap) @@ -203,9 +204,9 @@ PARENT-NODE is indented for recursive calls." (make-javaimp-node :parent (javaimp-node-parent tree) :children (javaimp-node-children tree) - :contents mapped))) + :contents contents))) (mapcar (lambda (child) - (javaimp--map-nodes-from-tree child mapper)) + (javaimp--map-nodes-from-tree child mapper unwrap)) (javaimp-node-children tree))))) (defun javaimp--get-root (node) diff --git a/javaimp.el b/javaimp.el index 5b887fb..dade07e 100644 --- a/javaimp.el +++ b/javaimp.el @@ -443,16 +443,13 @@ prefix arg is given, don't do this filtering." (directory-files-recursively dir "\\.java\\'"))))) (defun javaimp--get-file-classes (file) - ;; TODO per-file cache (check file modification ts) (with-temp-buffer (insert-file-contents file) (let ((package (javaimp--parse-get-package))) (mapcar (lambda (class) (if package (concat package "." class))) - (progn - (javaimp--parse-all-scopes) - (javaimp--parse-get-file-classes)))))) + (javaimp--parse-get-file-classes))))) ;; Organizing imports @@ -577,8 +574,6 @@ is `ordinary' or `static'. Interactively, NEW-IMPORTS is nil." ;;;###autoload (defun javaimp-imenu-create-index () (let ((forest (save-excursion - (javaimp--parse-clean-all-scopes) - (javaimp--parse-all-scopes) (javaimp--parse-get-forest-for-imenu)))) (cond ((not javaimp-imenu-group-methods) ;; just plain list of methods @@ -607,7 +602,7 @@ is `ordinary' or `static'. Interactively, NEW-IMPORTS is nil." ;; this will be a sub-alist's car (javaimp-scope-name scope)) ((eq (javaimp-scope-type scope) 'method) - (javaimp-menu--make-entry scope)))) + (javaimp-imenu--make-entry scope)))) forest t))))) (defun javaimp-imenu--make-entry (scope) @@ -672,16 +667,12 @@ start (`javaimp-scope-start') instead." (defun javaimp-help-show-scopes (arg) - "Shows scopes in a *javaimp-scopes* buffer, -which is first cleared. With a prefix arg, cleans all previously -parsed scopes." + "Show scopes in a *javaimp-scopes* buffer, +which is first cleared. With a prefix arg, first reset parsed +scopes cache." (interactive "P") - (when arg - (save-excursion - (javaimp--parse-clean-all-scopes) - (javaimp--parse-all-scopes))) (let ((scopes (save-excursion - (javaimp--parse-get-all-scopes))) + (javaimp--parse-get-all-scopes arg))) (file buffer-file-name) (buf (get-buffer-create "*javaimp-scopes*"))) (with-current-buffer buf