branch: externals/javaimp commit 9efdf954d5d63ebb41c07fea91c3e70cd5ca9b71 Author: Filipp Gunbin <fgun...@okko.tv> Commit: Filipp Gunbin <fgun...@okko.tv>
Implement next-error support in javaimp-show-scopes-mode --- javaimp-util.el | 2 +- javaimp.el | 136 ++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 89 insertions(+), 49 deletions(-) diff --git a/javaimp-util.el b/javaimp-util.el index 639474a673..0379a9e308 100644 --- a/javaimp-util.el +++ b/javaimp-util.el @@ -40,7 +40,7 @@ array) javaimp--classlike-scope-types)) -(defconst javaimp--help-scope-type-abbrevs +(defconst javaimp--show-scopes-scope-type-abbrevs '((anonymous-class . "ac") (statement . "st") (simple-statement . "ss") diff --git a/javaimp.el b/javaimp.el index 3ce295a518..fe2d7d9510 100644 --- a/javaimp.el +++ b/javaimp.el @@ -92,9 +92,9 @@ ;; "scopes") parses in ~1.5 seconds, which is not that bad... ;; ;; Parsing is also used for Imenu support. A simple debug command, -;; `javaimp-help-show-scopes', lists all parsed "scopes" (blocks of -;; code in braces). As there's no minor/major mode (yet), you have to -;; set `imenu-create-index-function' in major mode hook yourself. See +;; `javaimp-show-scopes', lists all parsed "scopes" (blocks of code in +;; braces). As there's no minor/major mode (yet), you have to set +;; `imenu-create-index-function' in major mode hook yourself. See ;; example below. ;; ;; - `javaimp-imenu-use-sub-alists' - if non-nil then Imenu items are @@ -116,7 +116,7 @@ ;; ;; (local-set-key (kbd "C-c i") #'javaimp-add-import) ;; (local-set-key (kbd "C-c o") #'javaimp-organize-imports) -;; (local-set-key (kbd "C-c s") #'javaimp-help-show-scopes) +;; (local-set-key (kbd "C-c s") #'javaimp-show-scopes) ;; ;; To enable Imenu (overriding Imenu support from cc-mode): ;; @@ -769,44 +769,54 @@ in a major mode hook." (back-to-indentation)) -;; Help +;; Show scopes -(defvar javaimp-help-keymap +(put 'javaimp-show-scopes-mode 'mode-class 'special) +(define-derived-mode javaimp-show-scopes-mode special-mode "Javaimp Show Scopes" + (setq next-error-function #'javaimp-show-scopes-next-error)) + +(defvar javaimp-show-scopes-mode-map (let ((map (make-sparse-keymap))) - (define-key map "\C-m" #'javaimp-help-goto-scope) - (define-key map [mouse-2] #'javaimp-help-goto-scope-mouse) + (set-keymap-parent map text-mode-map) + (define-key map "\C-m" #'javaimp-show-scopes-goto-scope) + (define-key map [mouse-2] #'javaimp-show-scopes-goto-scope-mouse) + (define-key map "n" #'next-error-no-select) + (define-key map "p" #'previous-error-no-select) + (define-key map "l" #'recenter-current-error) map) - "Keymap for Javaimp help buffers.") + "Javaimp Show Scopes keymap.") -(defun javaimp-help-goto-scope (pos) +(defun javaimp-show-scopes-goto-scope (pos) "Go to scope at point in another window." (interactive "d") - (javaimp-help--goto-scope-1 pos)) + (javaimp-show-scopes--goto-scope-1 pos current-prefix-arg)) ;; TODO handle mouse-1 -(defun javaimp-help-goto-scope-mouse (event) +(defun javaimp-show-scopes-goto-scope-mouse (event) "Go to scope you click on in another window." (interactive "e") (let ((window (posn-window (event-end event))) (pos (posn-point (event-end event)))) (with-current-buffer (window-buffer window) - (javaimp-help--goto-scope-1 pos)))) + (javaimp-show-scopes--goto-scope-1 pos current-prefix-arg)))) -(defun javaimp-help--goto-scope-1 (pos) +(defun javaimp-show-scopes--goto-scope-1 (pos &optional to-start) "Go to the opening brace (`javaimp-scope-open-brace') of the -scope at POS. With prefix arg, go to scope +scope at POS. When TO-START is non-nil, go to scope start (`javaimp-scope-start') instead." - (let ((scope (get-text-property pos 'javaimp-help-scope)) - (file (get-text-property (point-min) 'javaimp-help-file))) - (when (and scope file) - (with-current-buffer (find-file-other-window file) - (goto-char (if current-prefix-arg - (javaimp-scope-start scope) - (javaimp-scope-open-brace scope))))))) - -(defun javaimp-help-show-scopes (&optional show-all) - "Show scopes in *javaimp-scopes* buffer, with clickable -text. By default, the scopes are only those which appear in + (when-let ((scope (get-text-property pos 'javaimp-show-scopes-scope)) + (file (get-text-property (point-min) 'javaimp-show-scopes-file)) + (buf (find-file-noselect file))) + (with-current-buffer buf + (goto-char (if to-start + (javaimp-scope-start scope) + (javaimp-scope-open-brace scope)))) + (pop-to-buffer buf))) + + +(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." (interactive "P") @@ -820,32 +830,62 @@ with prefix arg, show all scopes." (javaimp-test-scope-type scope '(class interface enum method) javaimp--classlike-scope-types))))))) - (file buffer-file-name) + (source-buf (current-buffer)) + (source-default-dir default-directory) (buf (get-buffer-create "*javaimp-scopes*"))) (with-current-buffer buf - (setq buffer-read-only nil) - (erase-buffer) - (insert (propertize (format "%s\n\n" file) - 'javaimp-help-file file)) - (dolist (scope scopes) - (let ((depth 0) - (tmp scope)) - (while (setq tmp (javaimp-scope-parent tmp)) - (setq depth (1+ depth))) - (insert (propertize - (format "%d %s: %s%s\n" - depth - (cdr (assq (javaimp-scope-type scope) - javaimp--help-scope-type-abbrevs)) - (make-string depth ? ) - (javaimp-scope-name scope)) - 'mouse-face 'highlight - 'help-echo "mouse-2: go to this scope" - 'javaimp-help-scope scope - 'keymap javaimp-help-keymap)))) - (setq buffer-read-only t)) + (setq default-directory source-default-dir) + (javaimp-show-scopes-mode) + (let ((inhibit-read-only t) + (buffer-undo-list t)) + (erase-buffer) + (insert (propertize (format "%s\n\n" (buffer-file-name source-buf)) + 'javaimp-show-scopes-file (buffer-file-name source-buf))) + (dolist (scope scopes) + (let ((depth 0) + (tmp scope)) + (while (setq tmp (javaimp-scope-parent tmp)) + (setq depth (1+ depth))) + (insert (propertize + (format "%5d %2d %s: %s%s\n" + (with-current-buffer source-buf + (line-number-at-pos (javaimp-scope-start scope))) + depth + (cdr (assq (javaimp-scope-type scope) + javaimp--show-scopes-scope-type-abbrevs)) + (make-string depth ? ) + (javaimp-scope-name scope)) + 'mouse-face 'highlight + 'help-echo "mouse-2: go to this scope" + 'javaimp-show-scopes-scope scope + 'follow-link t)))) + (insert (format "\nTotal: %d scopes\n" (length scopes))) + (goto-char (point-min)) + (setq next-error-last-buffer buf) + (setq buffer-read-only t) + (set-buffer-modified-p nil))) (display-buffer buf))) +(defun javaimp-show-scopes-next-error (&optional argp reset) + "Compatibility function for \\[next-error] invocations." + (interactive "p") + (or argp (setq argp 1)) + (when reset + (if-let ((pos (next-single-property-change + (point-min) 'javaimp-show-scopes-scope))) + (progn + (goto-char pos) + (forward-line -1)) + (user-error "No scopes"))) + (forward-line argp) + (unless (get-text-property (point) 'javaimp-show-scopes-scope) + (user-error "No more scopes")) + ;; In case the buffer is visible in a nonselected window. + (let ((win (get-buffer-window (current-buffer) t))) + (if win (set-window-point win (point)))) + (javaimp-show-scopes--goto-scope-1 (point))) + + ;; Misc