143 lines
4.9 KiB
EmacsLisp
143 lines
4.9 KiB
EmacsLisp
|
;;; lsp-ido.el --- `ido' integration -*- lexical-binding: t -*-
|
||
|
;;
|
||
|
;; Copyright (C) 2021 emacs-lsp maintainers
|
||
|
;;
|
||
|
;; This program is free software; you can redistribute it and/or modify
|
||
|
;; it under the terms of the GNU General Public License as published by
|
||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||
|
;; (at your option) any later version.
|
||
|
|
||
|
;; This program is distributed in the hope that it will be useful,
|
||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
;; GNU General Public License for more details.
|
||
|
|
||
|
;; You should have received a copy of the GNU General Public License
|
||
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
|
||
|
;;; Commentary:
|
||
|
|
||
|
;; This module provides an interactive ido interface to the workspace symbol
|
||
|
;; functionality offered by lsp-mode.
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
(require 'ido)
|
||
|
(require 'lsp-protocol)
|
||
|
(require 'lsp-mode)
|
||
|
|
||
|
(defgroup lsp-ido nil
|
||
|
"LSP support for ido-based symbol completion"
|
||
|
:group 'lsp-mode
|
||
|
:tag "LSP ido")
|
||
|
|
||
|
(defcustom lsp-ido-symbol-kind-to-string
|
||
|
[" " ; Unknown - 0
|
||
|
"File" ; File - 1
|
||
|
"Modu" ; Module - 2
|
||
|
"Nmsp" ; Namespace - 3
|
||
|
"Pack" ; Package - 4
|
||
|
"Clss" ; Class - 5
|
||
|
"Meth" ; Method - 6
|
||
|
"Prop" ; Property - 7
|
||
|
"Fld " ; Field - 8
|
||
|
"Cons" ; Constructor - 9
|
||
|
"Enum" ; Enum - 10
|
||
|
"Intf" ; Interface - 11
|
||
|
"Func" ; Function - 12
|
||
|
"Var " ; Variable - 13
|
||
|
"Cnst" ; Constant - 14
|
||
|
"Str " ; String - 15
|
||
|
"Num " ; Number - 16
|
||
|
"Bool " ; Boolean - 17
|
||
|
"Arr " ; Array - 18
|
||
|
"Obj " ; Object - 19
|
||
|
"Key " ; Key - 20
|
||
|
"Null" ; Null - 21
|
||
|
"EmMm" ; EnumMember - 22
|
||
|
"Srct" ; Struct - 23
|
||
|
"Evnt" ; Event - 24
|
||
|
"Op " ; Operator - 25
|
||
|
"TPar"] ; TypeParameter - 26
|
||
|
"A vector of 26 items representing the SymbolKind."
|
||
|
:group 'lsp-ido
|
||
|
:type 'vector)
|
||
|
|
||
|
(defcustom lsp-ido-show-symbol-filename
|
||
|
t
|
||
|
"Whether to show the project-relative path to a symbol's point of definition."
|
||
|
:group 'lsp-ido
|
||
|
:type 'boolean)
|
||
|
|
||
|
(defcustom lsp-ido-show-symbol-kind
|
||
|
t
|
||
|
"Whether to show the symbol's kind when showing lsp symbols."
|
||
|
:group 'lsp-ido
|
||
|
:type 'boolean)
|
||
|
|
||
|
(eval-when-compile
|
||
|
(lsp-interface
|
||
|
(lsp-ido:FormattedSymbolInformation
|
||
|
(:kind :name :location :textualRepresentation)
|
||
|
(:containerName :deprecated))))
|
||
|
|
||
|
(lsp-defun lsp-ido--transform-candidate
|
||
|
((symbol-information &as &SymbolInformation :kind :location (&Location :uri))
|
||
|
lsp-ido--results project-root)
|
||
|
(let* ((sanitized-kind (if (< kind (length lsp-ido-symbol-kind-to-string)) kind 0))
|
||
|
(type (elt lsp-ido-symbol-kind-to-string sanitized-kind))
|
||
|
(typestr (if lsp-ido-show-symbol-kind
|
||
|
(format "[%s] " type)
|
||
|
""))
|
||
|
(pathstr (if lsp-ido-show-symbol-filename
|
||
|
(propertize (format " . %s" (file-relative-name (lsp--uri-to-path uri) project-root))
|
||
|
'face 'font-lock-comment-face)
|
||
|
""))
|
||
|
(textual-representation
|
||
|
(lsp-render-symbol-information symbol-information "."))
|
||
|
(entry (concat typestr textual-representation pathstr)))
|
||
|
(puthash entry symbol-information lsp-ido--results)))
|
||
|
|
||
|
(lsp-defun lsp-ido--jump-selected-candidate
|
||
|
((&SymbolInformation
|
||
|
:location (&Location :uri :range (&Range :start (&Position :line :character)))))
|
||
|
"Jump to selected candidate."
|
||
|
(find-file (lsp--uri-to-path uri))
|
||
|
(goto-char (point-min))
|
||
|
(forward-line line)
|
||
|
(forward-char character))
|
||
|
|
||
|
(defun lsp-ido--workspace-symbol (workspaces query)
|
||
|
"Search against WORKSPACES based on QUERY."
|
||
|
(let* ((lsp-ido--results (make-hash-table :test 'equal))
|
||
|
(workspace-root (lsp-workspace-root))
|
||
|
(raw-choices
|
||
|
(with-lsp-workspaces workspaces
|
||
|
(lsp-request
|
||
|
"workspace/symbol"
|
||
|
(lsp-make-workspace-symbol-params :query query)))))
|
||
|
(mapc (lambda (it)
|
||
|
(lsp-ido--transform-candidate it lsp-ido--results workspace-root))
|
||
|
raw-choices)
|
||
|
lsp-ido--results))
|
||
|
|
||
|
;;;###autoload
|
||
|
(defun lsp-ido-workspace-symbol (arg)
|
||
|
"`ido' for lsp workspace/symbol.
|
||
|
When called with prefix ARG the default selection will be symbol at point."
|
||
|
(interactive "P")
|
||
|
(let* ((query (if arg "" (read-string "Workspace symbol: ")))
|
||
|
(hash-table-candidates (lsp-ido--workspace-symbol (lsp-workspaces) query))
|
||
|
(choice (ido-completing-read
|
||
|
"Workspace symbol: "
|
||
|
(hash-table-keys hash-table-candidates)
|
||
|
nil
|
||
|
nil
|
||
|
(when arg (thing-at-point 'symbol)))))
|
||
|
(lsp-ido--jump-selected-candidate (gethash choice hash-table-candidates))))
|
||
|
|
||
|
(lsp-consistency-check lsp-ido)
|
||
|
|
||
|
(provide 'lsp-ido)
|
||
|
;;; lsp-ido.el ends here
|