branch: elpa/dart-mode
commit c4a5045b173d1ae29d43c79befe1d31c4e479f08
Author: Natalie Weizenbaum <[email protected]>
Commit: Natalie Weizenbaum <[email protected]>
Add support for navigation
---
CHANGELOG.md | 3 +++
README.md | 8 ++++++++
dart-mode.el | 38 +++++++++++++++++++++++++++++++++++---
3 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd5321e..277544e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,5 +3,8 @@
* Added a `dart-show-hover` command bound to `C-c ?` which displays information
about the Dart API under the cursor.
+* Added a `dart-goto` command bound to `C-c C-g` which takes the user to the
+ definition of the Dart API under the cursor.
+
* `dart-executable-path`'s default value is now set correctly even if the
executable named `dart` on the user's path is a symlink or a wrapper script.
diff --git a/README.md b/README.md
index 6de7985..5c79c34 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@
* [Dart Analyzer](#dart-analyzer)
* [Error Checking](#error-checking)
* [Seeing Information](#seeing-information)
+ * [Navigation](#navigation)
## Installation
@@ -45,3 +46,10 @@ extra information if it's available.
Sometimes there's just too much documentation to fit down there, or you want to
keep the documentation open as you're working. In that case, you can run `C-u
C-c ?` instead to open the information in a new window to read at your leisure.
+
+### Navigation
+
+When your cursor is on an identifier, you can press `C-c C-g` to go to the
exact
+location that identifier was originally defined. This can even take you to the
+Dart SDK's sources, or to packages that your library imports. Be careful when
+you're there, though: any edits may corrupt your package cache!
diff --git a/dart-mode.el b/dart-mode.el
index 2132599..d6aa345 100644
--- a/dart-mode.el
+++ b/dart-mode.el
@@ -197,6 +197,14 @@ FIELDS may be either identifiers or (ELISP-IDENTIFIER
JSON-IDENTIFIER) pairs."
,@body
(put-text-property ,start (point) 'face ,face))))
+(defun dart--flash-highlight (offset length)
+ "Briefly highlights the text defined by OFFSET and LENGTH.
+OFFSET and LENGTH are expected to come from the analysis server,
+rather than Elisp."
+ (lexical-let ((overlay (make-overlay (+ 1 offset) (+ 1 offset length))))
+ (overlay-put overlay 'face 'highlight)
+ (run-at-time "1 sec" nil (lambda () (delete-overlay overlay)))))
+
(defun dart--read-file (filename)
"Returns the contents of FILENAME."
(with-temp-buffer
@@ -405,6 +413,7 @@ Any stderr is logged using dart-log. Returns nil if the
exit code is non-0."
(defvar dart-mode-map (c-make-inherited-keymap)
"Keymap used in dart-mode buffers.")
(define-key dart-mode-map (kbd "C-c ?") 'dart-show-hover)
+(define-key dart-mode-map (kbd "C-c C-g") 'dart-goto)
;;; CC indentation support
@@ -1015,9 +1024,7 @@ minibuffer."
;; Briefly highlight the region that's being shown.
(with-current-buffer buffer
- (lexical-let ((overlay (make-overlay (+ 1 offset) (+ 1 offset
length))))
- (overlay-put overlay 'face 'highlight)
- (run-at-time "1 sec" nil (lambda () (delete-overlay
overlay)))))
+ (dart--flash-highlight offset length))
(with-temp-buffer
(when is-deprecated
@@ -1123,6 +1130,31 @@ minibuffer."
(buffer-string)))
+;;;; Navigation
+
+(defun dart-goto ()
+ (interactive)
+ (-when-let (filename (buffer-file-name))
+ (dart--analysis-server-send
+ "analysis.getNavigation"
+ `(("file" . ,filename) ("offset" . ,(point)) ("length" . 0))
+ (lambda (response)
+ (-when-let (result (cdr (assoc 'result response)))
+ (dart--json-let result (files targets regions)
+ (unless (eq (length regions) 0)
+ (let* ((region (elt regions 0))
+ (target-index (elt (cdr (assoc 'targets region)) 0))
+ (target (elt targets target-index))
+
+ (file-index (cdr (assoc 'fileIndex target)))
+ (offset (cdr (assoc 'offset target)))
+ (length (cdr (assoc 'length target)))
+
+ (file (elt files file-index)))
+ (find-file file)
+ (goto-char (+ 1 offset))
+ (dart--flash-highlight offset length)))))))))
+
;;; Formatting
(defcustom dartfmt-command "dartfmt"