diff --git a/ccls-call-hierarchy.el b/ccls-call-hierarchy.el index aed15b9..c701c76 100644 --- a/ccls-call-hierarchy.el +++ b/ccls-call-hierarchy.el @@ -1,7 +1,7 @@ ;;; -*- lexical-binding: t; -*- ;; Copyright (C) 2017 Tobias Pisani -;; Copyright (C) 2018 Fangrui Song +;; Copyright (C) 2018-2020 Fangrui Song ;; Permission is hereby granted, free of charge, to any person obtaining a copy ;; of this software and associated documentation files (the "Software"), to deal @@ -59,14 +59,17 @@ name call-type) +(eval-when-compile + (lsp-interface + (CclsCall (:id :name :location :callType :numChildren :children) nil))) + (defun ccls-call-hierarchy--read-node (data &optional parent) "Construct a call tree node from hashmap DATA and give it the parent PARENT" - (-let* ((location (gethash "location" data)) - (filename (lsp--uri-to-path (gethash "uri" location))) - ((&hash "id" id "name" name "callType" call-type) data)) + (-let* (((&CclsCall :id :name :location :call-type :num-children) data) + (filename (lsp--uri-to-path (lsp:location-uri location)))) (make-ccls-tree-node - :location (cons filename (gethash "start" (gethash "range" location))) - :has-children (< 0 (gethash "numChildren" data)) + :location (cons filename (lsp:range-start (lsp:location-range location))) + :has-children (< 0 num-children) :parent parent :expanded nil :children nil @@ -79,15 +82,15 @@ "." (let ((id (ccls-call-hierarchy-node-id (ccls-tree-node-data node)))) (--map (ccls-call-hierarchy--read-node it node) - (gethash "children" - (lsp-request - "$ccls/call" - `(:id ,id - :callee ,callee - :callType 3 - :levels ,ccls-tree-initial-levels - :qualified ,(if ccls-call-hierarchy-qualified t :json-false) - :hierarchy t)))))) + (lsp:ccls-call-children + (lsp-request + "$ccls/call" + `(:id ,id + :callee ,callee + :callType 3 + :levels ,ccls-tree-initial-levels + :qualified ,(if ccls-call-hierarchy-qualified t :json-false) + :hierarchy t)))))) (defun ccls-call-hierarchy--request-init (callee) "." @@ -113,7 +116,7 @@ ('2 'ccls-call-hierarchy-node-derived-face))) (propertize (format " (%s:%s)" (file-name-nondirectory (car (ccls-tree-node-location node))) - (gethash "line" (cdr (ccls-tree-node-location node)))) + (lsp:position-line (cdr (ccls-tree-node-location node)))) 'face 'ccls-tree-mode-line-face))))) (defun ccls-call-hierarchy (callee) diff --git a/ccls-code-lens.el b/ccls-code-lens.el index 3804d6c..8452648 100644 --- a/ccls-code-lens.el +++ b/ccls-code-lens.el @@ -61,15 +61,16 @@ ;; - Add a global option to request code lenses on automatically ;; --------------------------------------------------------------------- -(defun ccls--make-code-lens-string (lpad command &optional rpad) +(defun ccls--make-code-lens-string (lpad command0 &optional rpad) "." - (let ((map (make-sparse-keymap))) + (-let ((map (make-sparse-keymap)) + ((&Command :title :command :arguments?) command0)) (define-key map [mouse-1] (lambda () (interactive) - (when-let ((xrefs (lsp--locations-to-xref-items - (lsp--send-execute-command (gethash "command" command) (gethash "arguments" command))))) - (xref--show-xrefs xrefs nil)))) - (propertize (concat lpad (gethash "title" command) rpad) + (xref--show-xrefs + (lambda () (lsp--locations-to-xref-items + (lsp--send-execute-command command arguments?))) nil))) + (propertize (concat lpad title rpad) 'face 'ccls-code-lens-face 'mouse-face 'ccls-code-lens-mouse-face 'local-map map))) @@ -85,17 +86,17 @@ (let ((xl (aref x 2)) (yl (aref y 2))) (if (/= xl yl) (< xl yl) (< (aref x 3) (aref y 3))))) (seq-map (lambda (lens) - (-let* (((&hash "command" command "range" range) lens) - ((&hash "start" start "end" end) range)) - (vector (gethash "line" start) (gethash "character" start) - (gethash "line" end) (gethash "character" end) command) + (-let* (((&CodeLens :command? :range) lens) + ((&Range :start :end) range)) + (vector (lsp:position-line start) (lsp:position-character start) + (lsp:position-line end) (lsp:position-character end) command?) )) result))) (save-excursion (widen) (goto-char 1) (let ((line 0) (col 0) ov) (seq-doseq (lens result) - (-let (([l0 c0 l1 c1 command] lens) (pad " ")) + (-let (([l0 c0 l1 c1 command?] lens) (pad " ")) (pcase ccls-code-lens-position ('end (forward-line (- l0 line)) @@ -108,7 +109,7 @@ (let ((p (point-at-eol))) (setq ov (make-overlay p (1+ p) nil 'front-advance)) (overlay-put ov 'ccls-code-lens t) - (overlay-put ov 'display (ccls--make-code-lens-string " " command)))) + (overlay-put ov 'display (ccls--make-code-lens-string " " command?)))) (setq line l0 col c0)) ('inplace (forward-line (- l1 line)) @@ -116,7 +117,7 @@ (setq line l1) (setq ov (make-overlay (point) (point))) (overlay-put ov 'ccls-code-lens t) - (overlay-put ov 'after-string (ccls--make-code-lens-string " " command))))) + (overlay-put ov 'after-string (ccls--make-code-lens-string " " command?))))) ) (when (and (eq ccls-code-lens-position 'end) ov) (overlay-put ov 'display (concat (overlay-get ov 'display) "\n")))))) diff --git a/ccls-common.el b/ccls-common.el index 938e94e..848ff21 100644 --- a/ccls-common.el +++ b/ccls-common.el @@ -24,6 +24,7 @@ ;;; Code: (require 'cc-mode) +(require 'lsp-protocol) (require 'lsp-mode) (require 'cl-lib) (require 'seq) diff --git a/ccls-inheritance-hierarchy.el b/ccls-inheritance-hierarchy.el index f425c75..bdb7ef3 100644 --- a/ccls-inheritance-hierarchy.el +++ b/ccls-inheritance-hierarchy.el @@ -1,7 +1,7 @@ ;;; -*- lexical-binding: t; -*- ;; Copyright (C) 2017 Tobias Pisani -;; Copyright (C) 2018 Fangrui Song +;; Copyright (C) 2018-2020 Fangrui Song ;; Permission is hereby granted, free of charge, to any person obtaining a copy ;; of this software and associated documentation files (the "Software"), to deal @@ -42,15 +42,18 @@ kind name) +(eval-when-compile + (lsp-interface + (CclsInheritance (:id :kind :name :location :numChildren :children) nil))) + (defun ccls-inheritance-hierarchy--read-node (data &optional parent) "Construct a call tree node from hashmap DATA and give it the parent PARENT" - (-let* ((location (gethash "location" data '(nil . nil))) - (filename (lsp--uri-to-path (gethash "uri" location))) - ((&hash "id" id "kind" kind "name" name) data) + (-let* (((&CclsInheritance :id :kind :name :location :num-children :children) data) + (filename (lsp--uri-to-path (lsp:location-uri location))) (node (make-ccls-tree-node - :location (cons filename (gethash "start" (gethash "range" location))) - :has-children (< 0 (gethash "numChildren" data)) + :location (cons filename (lsp:range-start (lsp:location-range location))) + :has-children (< 0 num-children) :parent parent :expanded nil :children nil @@ -60,7 +63,7 @@ :name name)))) (setf (ccls-tree-node-children node) (--map (ccls-inheritance-hierarchy--read-node it node) - (gethash "children" data))) + (lsp:ccls-inheritance-children data))) node)) (defun ccls-inheritance-hierarchy--request-children (derived node) @@ -68,15 +71,15 @@ (let ((id (ccls-inheritance-hierarchy-node-id (ccls-tree-node-data node))) (kind (ccls-inheritance-hierarchy-node-kind (ccls-tree-node-data node)))) (--map (ccls-inheritance-hierarchy--read-node it node) - (gethash "children" - (lsp-request - "$ccls/inheritance" - `(:id ,id :kind ,kind - :derived ,derived - :qualified ,(if ccls-inheritance-hierarchy-qualified t :json-false) - :levels ,ccls-tree-initial-levels - :hierarchy t - )))))) + (lsp:ccls-inheritance-children + (lsp-request + "$ccls/inheritance" + `(:id ,id :kind ,kind + :derived ,derived + :qualified ,(if ccls-inheritance-hierarchy-qualified t :json-false) + :levels ,ccls-tree-initial-levels + :hierarchy t + )))))) (defun ccls-inheritance-hierarchy--request-init (derived) "." diff --git a/ccls-member-hierarchy.el b/ccls-member-hierarchy.el index 3be1828..d21e70a 100644 --- a/ccls-member-hierarchy.el +++ b/ccls-member-hierarchy.el @@ -1,7 +1,7 @@ ;;; -*- lexical-binding: t; -*- ;; Copyright (C) 2017 Tobias Pisani -;; Copyright (C) 2018 Fangrui Song +;; Copyright (C) 2018-2020 Fangrui Song ;; Permission is hereby granted, free of charge, to any person obtaining a copy ;; of this software and associated documentation files (the "Software"), to deal @@ -40,15 +40,19 @@ field-name id) +(eval-when-compile + (lsp-interface + (CclsMember (:id :name :fieldName :location :numChildren :children) nil))) + (defun ccls-member-hierarchy--read-node (data &optional parent) "Construct a call tree node from hashmap DATA and give it the parent PARENT" - (-let* (((&hash "location" location "numChildren" nchildren "name" name "fieldName" field-name "id" id "children" children) data) - (filename (lsp--uri-to-path (gethash "uri" location))) + (-let* (((&CclsMember :id :name :field-name :location :num-children :children) data) + (filename (lsp--uri-to-path (lsp:location-uir location))) (node (make-ccls-tree-node - :location (cons filename (gethash "start" (gethash "range" location))) + :location (cons filename (lsp:range-start (lsp:location-range "range" location))) ;; With a little bit of luck, this only filters out enums - :has-children (not (or (>= 0 nchildren) + :has-children (not (or (>= 0 num-children) (null parent) (equal id (ccls-member-hierarchy-node-id (ccls-tree-node-data parent))))) :parent parent @@ -67,8 +71,7 @@ "." (let ((id (ccls-member-hierarchy-node-id (ccls-tree-node-data node)))) (--map (ccls-member-hierarchy--read-node it node) - (gethash - "children" + (lsp:ccls-member-children (lsp-request "$ccls/member" `(:id ,id :levels ,ccls-tree-initial-levels diff --git a/ccls-semantic-highlight.el b/ccls-semantic-highlight.el index eef58a3..7142e8e 100644 --- a/ccls-semantic-highlight.el +++ b/ccls-semantic-highlight.el @@ -1,7 +1,7 @@ ;;; -*- lexical-binding: t; -*- ;; Copyright (C) 2017 Tobias Pisani -;; Copyright (C) 2018 Fangrui Song +;; Copyright (C) 2018-2020 Fangrui Song ;; Permission is hereby granted, free of charge, to any person obtaining a copy ;; of this software and associated documentation files (the "Software"), to deal @@ -174,6 +174,13 @@ If nil, disable semantic highlight." (defvar-local ccls--skipped-ranges-overlays nil "Skipped ranges overlays.") (defvar-local ccls--sem-overlays nil "Semantic highlight overlays.") +(eval-when-compile + (lsp-interface + (CclsLR (:L :R) nil) + (CclsSemanticHighlightSymbol (:id :parentKind :kind :storage :ranges) nil) + (CclsSemanticHighlight (:uri :symbols) nil) + (CclsSkippedRanges (:uri :skippedRanges) nil))) + (defun ccls--clear-sem-highlights () "." (pcase ccls-sem-highlight-method @@ -186,8 +193,7 @@ If nil, disable semantic highlight." (defun ccls-sem--default-face (symbol) "Get semantic highlight face of SYMBOL." ;; https://github.com/ccls-project/ccls/blob/master/src/symbol.h - (-let* (((&hash "type" type "kind" kind "storage" storage - "parentKind" parent-kind "id" id) symbol) + (-let* (((&CclsSemanticHighlightSymbol :id :parent-kind :kind :storage) symbol) (fn0 (lambda (faces lo0 hi0) (let* ((n (length faces)) (lo (/ (* lo0 n) 1000)) @@ -232,25 +238,23 @@ If nil, disable semantic highlight." (22 `(,(funcall fn0 ccls-sem-variable-faces 0 1000) ccls-sem-member-face)) ; EnumMember - (_ (pcase type - (0 (funcall fn ccls-sem-type-faces)) - (1 (funcall fn ccls-sem-function-faces)) - (_ (funcall fn ccls-sem-variable-faces))))))) + (_ (funcall fn ccls-sem-variable-faces))))) (defun ccls--publish-semantic-highlight (_workspace params) "Publish semantic highlight information according to PARAMS." (when ccls-sem-highlight-method - (-when-let* ((file (lsp--uri-to-path (gethash "uri" params))) + (-when-let* (((&CclsSemanticHighlight :uri :symbols) params) + (file (lsp--uri-to-path uri)) (buffer (find-buffer-visiting file))) (with-current-buffer buffer (with-silent-modifications (ccls--clear-sem-highlights) (let (ranges point0 point1 (line 0) overlays) - (seq-doseq (symbol (gethash "symbols" params)) + (seq-doseq (symbol symbols) (-when-let* ((face (funcall ccls-sem-face-function symbol))) - (seq-doseq (range (gethash "ranges" symbol)) - (-let (((&hash "L" start "R" end) range)) - (push (list (1+ start) (1+ end) face) overlays))))) + (seq-doseq (range (lsp:ccls-semantic-highlight-symbol-ranges symbol)) + (-let (((&CclsLR :l :r) range)) + (push (list (1+ l) (1+ r) face) overlays))))) ;; The server guarantees the ranges are non-overlapping. (setq overlays (sort overlays (lambda (x y) (< (car x) (car y))))) (pcase ccls-sem-highlight-method @@ -294,18 +298,19 @@ If nil, disable semantic highlight." (defun ccls--publish-skipped-ranges (_workspace params) "Put overlays on (preprocessed) inactive regions according to PARAMS." - (-when-let* ((file (lsp--uri-to-path (gethash "uri" params))) - (buffer (find-buffer-visiting file))) - (with-current-buffer buffer + (-let* (((&CclsSkippedRanges :uri :skipped-ranges) params) + (file (lsp--uri-to-path (lsp:ccls-skipped-ranges-uri params)))) + (-when-let (buffer (find-buffer-visiting file)) + (with-current-buffer buffer (with-silent-modifications (ccls--clear-skipped-ranges) (when ccls-enable-skipped-ranges (overlay-recenter (point-max)) - (seq-doseq (range (gethash "skippedRanges" params) ) - (let ((ov (make-overlay (lsp--position-to-point (gethash "start" range)) - (lsp--position-to-point (gethash "end" range)) buffer))) + (seq-doseq (range skipped-ranges) + (let ((ov (make-overlay (lsp--position-to-point (lsp:range-start range)) + (lsp--position-to-point (lsp:range-end range)) buffer))) (overlay-put ov 'face 'ccls-skipped-range-face) (overlay-put ov 'ccls-inactive t) - (push ov ccls--skipped-ranges-overlays)))))))) + (push ov ccls--skipped-ranges-overlays))))))))) (provide 'ccls-semantic-highlight) diff --git a/ccls.el b/ccls.el index cbeecb1..3540227 100644 --- a/ccls.el +++ b/ccls.el @@ -84,6 +84,10 @@ ;; --------------------------------------------------------------------- ;; +(eval-when-compile + (lsp-interface + (CclsQueryFileDef (:path :args :language :dependencies :includes :skipped-ranges) nil))) + (defun ccls-info () (lsp-request "$ccls/info" (make-hash-table))) @@ -97,7 +101,7 @@ (lsp--cur-workspace-check) (-when-let* ((mode major-mode) (info (ccls-file-info)) - (args (seq-into (gethash "args" info) 'vector)) + (args (seq-into (lsp:ccls-query-file-def-args info) 'vector)) (new-args (let ((i 0) ret) (while (< i (length args)) (let ((arg (elt args i)))