Skip to content

Commit

Permalink
Merge pull request #35 from emacs-lsp/use-protocol
Browse files Browse the repository at this point in the history
Use lsp-protocol
  • Loading branch information
ericdallo authored Jun 4, 2020
2 parents 7bc9d49 + d9ba2ce commit 7703507
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 181 deletions.
41 changes: 19 additions & 22 deletions lsp-dart-closing-labels.el
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

(require 'lsp-mode)

(require 'lsp-dart-protocol)

(defcustom lsp-dart-closing-labels t
"Enable the analysis server closing labels feature.
When set to non-nil, dart/textDocument/publishClosingLabel notifications will
Expand All @@ -38,28 +40,23 @@ be sent with information to render editor closing labels."
:type 'float
:group 'lsp-dart)

(defun lsp-dart-closing-labels-handle (_workspace params)
"Closing labels notification handling.
PARAMS closing labels notification data sent from WORKSPACE."
(-let* (((&hash "uri" "labels") params)
(buffer (lsp--buffer-for-file (lsp--uri-to-path uri))))
(when buffer
(with-current-buffer buffer
(remove-overlays (point-min) (point-max) 'lsp-dart-closing-labels t)
(seq-doseq (label-ht labels)
(save-excursion
(-let* ((label (gethash "label" label-ht))
(range (gethash "range" label-ht))
((beg . end) (lsp--range-to-region range))
(end-line (progn
(goto-char end)
(line-end-position)))
(overlay (make-overlay beg end-line buffer)))
(overlay-put overlay 'lsp-dart-closing-labels t)
(overlay-put overlay 'after-string (propertize (concat lsp-dart-closing-labels-prefix " " label)
'display `((height ,lsp-dart-closing-labels-size))
'cursor t
'font-lock-face 'font-lock-comment-face)))))))))
(lsp-defun lsp-dart-closing-labels-handle (_workspace (&ClosingLabelsNotification :uri :labels))
"Closing labels notification handler."
(when-let (buffer (lsp--buffer-for-file (lsp--uri-to-path uri)))
(with-current-buffer buffer
(remove-overlays (point-min) (point-max) 'lsp-dart-closing-labels t)
(seq-doseq (label labels)
(save-excursion
(-let* (((beg . end) (lsp--range-to-region (lsp:closing-label-range label)))
(end-line (progn
(goto-char end)
(line-end-position)))
(overlay (make-overlay beg end-line buffer)))
(overlay-put overlay 'lsp-dart-closing-labels t)
(overlay-put overlay 'after-string (propertize (concat lsp-dart-closing-labels-prefix " " (lsp:closing-label-label label))
'display `((height ,lsp-dart-closing-labels-size))
'cursor t
'font-lock-face 'font-lock-comment-face))))))))

(provide 'lsp-dart-closing-labels)
;;; lsp-dart-closing-labels.el ends here
62 changes: 30 additions & 32 deletions lsp-dart-code-lens.el
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
(require 'dash)
(require 'ht)

(require 'lsp-dart-protocol)
(require 'lsp-dart-dap)
(require 'lsp-dart-test-support)

Expand All @@ -45,14 +46,14 @@

;; Internal

(defun lsp-dart-code-lens--find-main-outline (children)
"Return the main outline if exists in CHILDREN."
(if-let (main (seq-find (-lambda ((&hash "element" (&hash "name")))
(defun lsp-dart-code-lens--find-main-outline (outlines)
"Return the main outline if exists in OUTLINES."
(if-let (main (seq-find (-lambda ((&Outline :element (&Element :name)))
(string= name "main"))
children))
outlines))
main
(->> children
(seq-map (-lambda ((&hash "children"))
(->> outlines
(seq-map (-lambda ((&Outline :children))
(when children
(lsp-dart-code-lens--find-main-outline children))))
-first-item)))
Expand Down Expand Up @@ -94,11 +95,11 @@ If TEST-FILE? debug tests otherwise debug application."
(lsp-dart-dap-debug-flutter path)
(lsp-dart-dap-debug-dart path))))

(defun lsp-dart-code-lens--build-main-overlay (buffer main-outline)
"Build main overlay code lens for BUFFER from MAIN-OUTLINE."
(-let* (((&hash "range") main-outline)
(beg-position (gethash "character" (gethash "start" range)))
((beg . end) (lsp--range-to-region range))
(lsp-defun lsp-dart-code-lens--build-main-overlay (buffer (&Outline :range
(range &as &Range :start
(&Position :character beg-position))))
"Build main overlay code lens for BUFFER from main outline."
(-let* (((beg . end) (lsp--range-to-region range))
(beg-line (progn (goto-char beg)
(line-beginning-position)))
(overlay (make-overlay beg-line end buffer))
Expand Down Expand Up @@ -127,12 +128,12 @@ If TEST-FILE? debug tests otherwise debug application."
test-file?)
"\n"))))

(defun lsp-dart-code-lens--build-test-overlay (buffer names kind range test-range)
(lsp-defun lsp-dart-code-lens--build-test-overlay (buffer names kind test-range (range &as &Range :start
(&Position :character beg-position)))
"Build an overlay in BUFFER for a test NAMES of KIND.
RANGE is the overlay range to build.
TEST-RANGE is the test method range."
(-let* ((beg-position (gethash "character" (gethash "start" range)))
((beg . end) (lsp--range-to-region range))
TEST-RANGE is the test method range.
RANGE is the overlay range to build."
(-let* (((beg . end) (lsp--range-to-region range))
(beg-line (progn (goto-char beg)
(line-beginning-position)))
(spaces (make-string beg-position ?\s))
Expand Down Expand Up @@ -164,24 +165,23 @@ TEST-RANGE is the test method range."
"Add test code lens to BUFFER for ITEMS.
NAMES arg is optional and are the group of tests representing a test name."
(seq-doseq (item items)
(-let* (((&hash "children" "codeRange" test-range "element"
(&hash "kind" "name" "range")) item)
(-let* (((&Outline :children :code-range test-range :element
(&Element :kind :name :range)) item)
(test-kind? (lsp-dart-test--test-kind-p kind))
(concatened-names (if test-kind?
(append names (list name))
names)))
(when test-kind?
(lsp-dart-code-lens--build-test-overlay buffer (append names (list name)) kind range test-range))
(lsp-dart-code-lens--build-test-overlay buffer (append names (list name)) kind test-range range))
(unless (seq-empty-p children)
(lsp-dart-code-lens--add-test buffer children concatened-names)))))


;; Public

(defun lsp-dart-code-lens-check-main (uri outline)
"Check URI and OUTLINE for main method adding lens to it."
(-let* (((&hash "children") outline)
(buffer (lsp--buffer-for-file (lsp--uri-to-path uri)))
(lsp-defun lsp-dart-code-lens-check-main (uri (&Outline :children))
"Check URI and outline for main method adding lens to it."
(-let* ((buffer (lsp--buffer-for-file (lsp--uri-to-path uri)))
(main-outline (lsp-dart-code-lens--find-main-outline children)))
(when buffer
(with-current-buffer buffer
Expand All @@ -190,16 +190,14 @@ NAMES arg is optional and are the group of tests representing a test name."
(when main-outline
(lsp-dart-code-lens--build-main-overlay buffer main-outline)))))))

(defun lsp-dart-code-lens-check-test (uri outline)
"Check URI and OUTLINE for test adding lens to it."
(lsp-defun lsp-dart-code-lens-check-test (uri (&Outline :children))
"Check URI and outline for test adding lens to it."
(when (lsp-dart-test-file-p uri)
(-let* (((&hash "children") outline)
(buffer (lsp--buffer-for-file (lsp--uri-to-path uri))))
(when buffer
(with-current-buffer buffer
(remove-overlays (point-min) (point-max) 'lsp-dart-test-code-lens t)
(save-excursion
(lsp-dart-code-lens--add-test buffer children)))))))
(when-let (buffer (lsp--buffer-for-file (lsp--uri-to-path uri)))
(with-current-buffer buffer
(remove-overlays (point-min) (point-max) 'lsp-dart-test-code-lens t)
(save-excursion
(lsp-dart-code-lens--add-test buffer children))))))

(provide 'lsp-dart-code-lens)
;;; lsp-dart-code-lens.el ends here
101 changes: 49 additions & 52 deletions lsp-dart-flutter-widget-guide.el
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@

(require 'dash)
(require 'ht)

(require 'lsp-mode)

(require 'lsp-dart-protocol)

(defcustom lsp-dart-flutter-widget-guides t
"Enable showing ui guides for flutter widgets hierarchy."
:type 'boolean
Expand Down Expand Up @@ -64,45 +65,42 @@
(end-of-line)
(current-column)))

(defun lsp-dart-flutter-widget-guide--outline->guide (outline)
(lsp-defun lsp-dart-flutter-widget-guide--outline->guide ((&FlutterOutline :kind :children :range
(&Range :start
(&Position :line parent-line))))
"Build a widget guide from an OUTLINE.
Return nil if the widget guilde does not apply."
(-let* (((&hash "children" "kind" "range") outline))
(when (string= kind "NEW_INSTANCE")
(-let* ((parent-line (->> range (gethash "start") (gethash "line")))
(children-start (unless (seq-empty-p children)
(->> children
(--map (->> it
(gethash "range")
(gethash "start")
(gethash "line")))
(--filter (> it parent-line))))))
(when children-start
(let ((start-pos (lsp-dart-flutter-widget-guide--first-non-whitespace-pos parent-line)))
(->> children-start
(--map (ht ("start" start-pos)
("end" (lsp-dart-flutter-widget-guide--first-non-whitespace-pos it))))
(-flatten))))))))

(defun lsp-dart-flutter-widget-guide--outline->guides (outline)
(when (string= kind "NEW_INSTANCE")
(-let* ((children-start (unless (seq-empty-p children)
(->> children
(-map (-lambda ((&Outline :range (&Range :start (&Position :line))))
line))
(--filter (> it parent-line))))))
(when children-start
(let ((start-pos (lsp-dart-flutter-widget-guide--first-non-whitespace-pos parent-line)))
(->> children-start
(--map (ht ("start" start-pos)
("end" (lsp-dart-flutter-widget-guide--first-non-whitespace-pos it))))
(-flatten)))))))

(lsp-defun lsp-dart-flutter-widget-guide--outline->guides ((outline &as &FlutterOutline :children))
"Build the widget guides from OUTLINE recursively."
(-let* (((&hash "children") outline))
(unless (seq-empty-p children)
(let ((ext-children (->> children
(--map (lsp-dart-flutter-widget-guide--outline->guides it))
(-non-nil)
(-flatten)))
(ext-outline (lsp-dart-flutter-widget-guide--outline->guide outline)))
(if ext-outline
(-concat ext-outline ext-children)
ext-children)))))
(unless (seq-empty-p children)
(let ((ext-children (->> children
(--map (lsp-dart-flutter-widget-guide--outline->guides it))
(-non-nil)
(-flatten)))
(ext-outline (lsp-dart-flutter-widget-guide--outline->guide outline)))
(if ext-outline
(-concat ext-outline ext-children)
ext-children))))

(defun lsp-dart-flutter-widget-guide--guides->guides-by-line (guides)
"Convert a widget guide GUIDES to a map by line."
(let ((guides-by-line (ht-create)))
(seq-doseq (guide guides)
(-let* (((&hash "start" (&hash "line" start-line)
"end" (&hash "line" end-line)) guide))
(-let (((&Range :start (&Position :line start-line)
:end (&Position :line end-line)) guide))
(while (<= start-line end-line)
(if-let ((cur-guides (ht-get guides-by-line start-line)))
(ht-set! guides-by-line start-line (append cur-guides (list guide)))
Expand All @@ -117,8 +115,8 @@ LAST-LINE-CHAR is the last column position of LINE.
ANCHOR is the anchor point of the widget guide at LINE."
(let ((chars (make-list size lsp-dart-flutter-widget-guide-space)))
(seq-doseq (guide guide-lines)
(-let* (((&hash "start" (&hash "character" start-char)
"end" (&hash "line" end-line "character" end-char)) guide)
(-let* (((&Range :start (&Position :character start-char)
:end (&Position :line end-line :character end-char)) guide)
(start-char-at (nth start-char chars)))
(if (not (= line end-line))
(if (string= lsp-dart-flutter-widget-guide-space start-char-at)
Expand All @@ -133,31 +131,30 @@ ANCHOR is the anchor point of the widget guide at LINE."
(setf (nth char chars) lsp-dart-flutter-widget-guide-horizontal-line)
(setq chars (append chars (list lsp-dart-flutter-widget-guide-horizontal-line)))))
(setq char (1+ char)))))))
(-let (((&hash "character" first-non-whitespace-index) (lsp-dart-flutter-widget-guide--first-non-whitespace-pos line)))
(-let (((&Position :character first-non-whitespace-index) (lsp-dart-flutter-widget-guide--first-non-whitespace-pos line)))
(->> chars
(--map-indexed (if (and (>= it-index first-non-whitespace-index)
(<= it-index last-line-char)) lsp-dart-flutter-widget-guide-space it))
(--map-indexed (if (>= it-index anchor) it ""))
(--filter (not (string= "" it)))))))

(defun lsp-dart-flutter-widget-guide-check (outline-params)
(lsp-defun lsp-dart-flutter-widget-guide-check ((&FlutterOutlineNotification :uri :outline))
"Check if there is any widget guide on buffer from uri of OUTLINE-PARAMS."
(let* ((buffer (lsp--buffer-for-file (lsp--uri-to-path (gethash "uri" outline-params)))))
(when buffer
(with-current-buffer buffer
(remove-overlays (point-min) (point-max) 'category 'lsp-dart-flutter-widget-guide)
(let* ((guides (lsp-dart-flutter-widget-guide--outline->guides (gethash "outline" outline-params)))
(guides-by-line (lsp-dart-flutter-widget-guide--guides->guides-by-line guides)))
(ht-each (lambda (line guide-lines)
(let* ((first-guide-char (-min (--map (min (gethash "character" (gethash "start" it))
(gethash "character" (gethash "end" it))) guide-lines)))
(last-guide-char (-max (--map (max (gethash "character" (gethash "start" it))
(gethash "character" (gethash "end" it))) guide-lines)))
(last-line-char (lsp-dart-flutter-widget-guide--last-col-at line))
(anchor (max 0 (if (< last-line-char first-guide-char) 0 first-guide-char)))
(chars (lsp-dart-flutter-widget-guide--build-chars line guide-lines last-guide-char last-line-char anchor)))
(--each-indexed chars (lsp-dart-flutter-widget-guide--add-overlay-to buffer line (+ it-index anchor) it))))
guides-by-line))))))
(-when-let (buffer (lsp--buffer-for-file (lsp--uri-to-path uri)))
(with-current-buffer buffer
(remove-overlays (point-min) (point-max) 'category 'lsp-dart-flutter-widget-guide)
(let* ((guides (lsp-dart-flutter-widget-guide--outline->guides outline))
(guides-by-line (lsp-dart-flutter-widget-guide--guides->guides-by-line guides)))
(ht-each (lambda (line guide-lines)
(let* ((first-guide-char (-min (--map (min (-> it lsp:range-start lsp:position-character)
(-> it lsp:range-end lsp:position-character)) guide-lines)))
(last-guide-char (-max (--map (max (-> it lsp:range-start lsp:position-character)
(-> it lsp:range-end lsp:position-character)) guide-lines)))
(last-line-char (lsp-dart-flutter-widget-guide--last-col-at line))
(anchor (max 0 (if (< last-line-char first-guide-char) 0 first-guide-char)))
(chars (lsp-dart-flutter-widget-guide--build-chars line guide-lines last-guide-char last-line-char anchor)))
(--each-indexed chars (lsp-dart-flutter-widget-guide--add-overlay-to buffer line (+ it-index anchor) it))))
guides-by-line)))))

(provide 'lsp-dart-flutter-widget-guide)
;;; lsp-dart-flutter-widget-guide.el ends here
Loading

0 comments on commit 7703507

Please sign in to comment.