lsp-ido.el (5039B)
1 ;;; lsp-ido.el --- `ido' integration -*- lexical-binding: t -*- 2 ;; 3 ;; Copyright (C) 2021 emacs-lsp maintainers 4 ;; 5 ;; This program is free software; you can redistribute it and/or modify 6 ;; it under the terms of the GNU General Public License as published by 7 ;; the Free Software Foundation, either version 3 of the License, or 8 ;; (at your option) any later version. 9 10 ;; This program is distributed in the hope that it will be useful, 11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 ;; GNU General Public License for more details. 14 15 ;; You should have received a copy of the GNU General Public License 16 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18 ;;; Commentary: 19 20 ;; This module provides an interactive ido interface to the workspace symbol 21 ;; functionality offered by lsp-mode. 22 23 ;;; Code: 24 25 (require 'ido) 26 (require 'lsp-protocol) 27 (require 'lsp-mode) 28 29 (defgroup lsp-ido nil 30 "LSP support for ido-based symbol completion" 31 :group 'lsp-mode 32 :tag "LSP ido") 33 34 (defcustom lsp-ido-symbol-kind-to-string 35 [" " ; Unknown - 0 36 "File" ; File - 1 37 "Modu" ; Module - 2 38 "Nmsp" ; Namespace - 3 39 "Pack" ; Package - 4 40 "Clss" ; Class - 5 41 "Meth" ; Method - 6 42 "Prop" ; Property - 7 43 "Fld " ; Field - 8 44 "Cons" ; Constructor - 9 45 "Enum" ; Enum - 10 46 "Intf" ; Interface - 11 47 "Func" ; Function - 12 48 "Var " ; Variable - 13 49 "Cnst" ; Constant - 14 50 "Str " ; String - 15 51 "Num " ; Number - 16 52 "Bool " ; Boolean - 17 53 "Arr " ; Array - 18 54 "Obj " ; Object - 19 55 "Key " ; Key - 20 56 "Null" ; Null - 21 57 "EmMm" ; EnumMember - 22 58 "Srct" ; Struct - 23 59 "Evnt" ; Event - 24 60 "Op " ; Operator - 25 61 "TPar"] ; TypeParameter - 26 62 "A vector of 26 items representing the SymbolKind." 63 :group 'lsp-ido 64 :type '(vector string)) 65 66 (defcustom lsp-ido-show-symbol-filename 67 t 68 "Whether to show the project-relative path to a symbol's point of definition." 69 :group 'lsp-ido 70 :type 'boolean) 71 72 (defcustom lsp-ido-show-symbol-kind 73 t 74 "Whether to show the symbol's kind when showing lsp symbols." 75 :group 'lsp-ido 76 :type 'boolean) 77 78 (eval-when-compile 79 (lsp-interface 80 (lsp-ido:FormattedSymbolInformation 81 (:kind :name :location :textualRepresentation) 82 (:containerName :deprecated)))) 83 84 (lsp-defun lsp-ido--transform-candidate 85 ((symbol-information &as &SymbolInformation :kind :location (&Location :uri)) 86 lsp-ido--results project-root) 87 (let* ((sanitized-kind (if (< kind (length lsp-ido-symbol-kind-to-string)) kind 0)) 88 (type (elt lsp-ido-symbol-kind-to-string sanitized-kind)) 89 (typestr (if lsp-ido-show-symbol-kind 90 (format "[%s] " type) 91 "")) 92 (pathstr (if lsp-ido-show-symbol-filename 93 (propertize (format " . %s" (file-relative-name (lsp--uri-to-path uri) project-root)) 94 'face 'font-lock-comment-face) 95 "")) 96 (textual-representation 97 (lsp-render-symbol-information symbol-information ".")) 98 (entry (concat typestr textual-representation pathstr))) 99 (puthash entry symbol-information lsp-ido--results))) 100 101 (lsp-defun lsp-ido--jump-selected-candidate 102 ((&SymbolInformation 103 :location (&Location :uri :range (&Range :start (&Position :line :character))))) 104 "Jump to selected candidate." 105 (find-file (lsp--uri-to-path uri)) 106 (goto-char (point-min)) 107 (forward-line line) 108 (forward-char character)) 109 110 (defun lsp-ido--workspace-symbol (workspaces query) 111 "Search against WORKSPACES based on QUERY." 112 (let* ((lsp-ido--results (make-hash-table :test 'equal)) 113 (workspace-root (lsp-workspace-root)) 114 (raw-choices 115 (with-lsp-workspaces workspaces 116 (lsp-request 117 "workspace/symbol" 118 (lsp-make-workspace-symbol-params :query query))))) 119 (mapc (lambda (it) 120 (lsp-ido--transform-candidate it lsp-ido--results workspace-root)) 121 raw-choices) 122 lsp-ido--results)) 123 124 ;;;###autoload 125 (defun lsp-ido-workspace-symbol (arg) 126 "`ido' for lsp workspace/symbol. 127 When called with prefix ARG the default selection will be symbol at point." 128 (interactive "P") 129 (let* ((query (if arg "" (read-string "Workspace symbol: "))) 130 (hash-table-candidates (lsp-ido--workspace-symbol (lsp-workspaces) query)) 131 (choice (ido-completing-read 132 "Workspace symbol: " 133 (hash-table-keys hash-table-candidates) 134 nil 135 nil 136 (when arg (thing-at-point 'symbol))))) 137 (lsp-ido--jump-selected-candidate (gethash choice hash-table-candidates)))) 138 139 (lsp-consistency-check lsp-ido) 140 141 (provide 'lsp-ido) 142 ;;; lsp-ido.el ends here