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
 

Reply via email to