diff options
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180913.833/lsp-ui-peek.el')
-rw-r--r-- | configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180913.833/lsp-ui-peek.el | 732 |
1 files changed, 0 insertions, 732 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180913.833/lsp-ui-peek.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180913.833/lsp-ui-peek.el deleted file mode 100644 index ddd128337ef3..000000000000 --- a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180913.833/lsp-ui-peek.el +++ /dev/null @@ -1,732 +0,0 @@ -;;; lsp-ui-peek.el --- Lsp-Ui-Peek -*- lexical-binding: t -*- - -;; Copyright (C) 2017 Sebastien Chapuis - -;; Author: Sebastien Chapuis <sebastien@chapu.is> -;; URL: https://github.com/emacs-lsp/lsp-ui -;; Keywords: lsp, ui -;; Version: 0.0.1 - -;;; License -;; -;; 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, 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; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth -;; Floor, Boston, MA 02110-1301, USA. - -;;; Commentary: -;; -;; Load this file and execute `lsp-ui-peek-find-references' -;; on a symbol to find its references -;; or `lsp-ui-peek-find-definitions'. -;; Type 'q' to close the window. -;; - -;;; Code: - -(require 'lsp-mode) -(require 'xref) -(require 'dash) - -(defgroup lsp-ui-peek nil - "Improve version of xref with peek feature." - :group 'tools - :group 'convenience - :group 'lsp-ui - :link '(custom-manual "(lsp-ui-peek) Top") - :link '(info-link "(lsp-ui-peek) Customizing")) - -(defcustom lsp-ui-peek-enable t - "Whether or not to enable ‘lsp-ui-peek’." - :type 'boolean - :group 'lsp-ui) - -(defcustom lsp-ui-peek-peek-height 20 - "Height of the peek code." - :type 'integer - :group 'lsp-ui-peek) - -(defcustom lsp-ui-peek-list-width 50 - "Width of the right panel." - :type 'integer - :group 'lsp-ui-peek) - -(defcustom lsp-ui-peek-fontify 'on-demand - "Whether to fontify chunks of code (use semantics colors). -WARNING: 'always can heavily slow the processing when `lsp-ui-peek-expand-function' -expands more than 1 file. It is recommended to keeps the default value of -`lsp-ui-peek-expand-function' when this variable is 'always." - :type '(choice (const :tag "Never" never) - (const :tag "On demand" on-demand) - (const :tag "Always" always)) - :group 'lsp-ui-peek) - -(defcustom lsp-ui-peek-always-show nil - "Show the peek view even if there is only 1 cross reference. -By default, the peek view isn't shown if there is 1 xref." - :type 'boolean - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-peek - '((((background light)) :background "light gray") - (t :background "#031A25")) - "Face used for the peek." - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-list - '((((background light)) :background "light gray") - (t :background "#181818")) - "Face used to list references." - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-filename - '((((background light)) :foreground "red") - (t :foreground "dark orange")) - "Face used for the filename's reference in the list." - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-line-number - '((t :foreground "grey25")) - "Line number face." - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-highlight - '((((background light)) :background "dim gray" - :foreground "white" - :distant-foreground "black") - (t :background "white" - :foreground "black" - :distant-foreground "white" - :box (:line-width -1 :color "white"))) - "Face used to highlight the reference/definition. -Do not use box, underline or overline prop. If you want to use -box, use a negative value for its width. Those properties deform -the whole overlay." - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-header - '((((background light)) :background "grey30" :foreground "white") - (t :background "white" :foreground "black")) - "Face used for the headers." - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-footer - '((t :inherit lsp-ui-peek-header)) - "Face used for the footers. Only the background of this face is used." - :group 'lsp-ui-peek) - -(defface lsp-ui-peek-selection - '((((background light)) :background "grey30" :foreground "white") - (t :background "white" :foreground "black")) - "Face used for the current selection. -Do not use box, underline or overline prop. If you want to use -box, use a negative value for its width. Those properties -deform the whole overlay." - :group 'lsp-ui-peek) - -(defvar lsp-ui-peek-expand-function 'lsp-ui-peek--expand-buffer - "A function used to determinate which file(s) to expand in the list of xrefs. -The function takes one parameter: a list of cons where the car is the -filename and the cdr is the number of references in that file. -It should returns a list of filenames to expand. -WARNING: If you change this variable and expand more than 1 file, it is -recommended to set `lsp-ui-peek-fontify' to 'never or 'on-demand, otherwise it -will cause performances issues.") - -(defvar-local lsp-ui-peek--overlay nil) -(defvar-local lsp-ui-peek--list nil) -(defvar-local lsp-ui-peek--last-xref nil) -(defvar-local lsp-ui-peek--selection 0) -(defvar-local lsp-ui-peek--offset 0) -(defvar-local lsp-ui-peek--size-list 0) -(defvar-local lsp-ui-peek--win-start nil) -(defvar-local lsp-ui-peek--kind nil) -(defvar-local lsp-ui-peek--deactivate-keymap-fn nil) - -(defvar lsp-ui-peek--jumps (make-hash-table) - "Hashtable which stores all jumps on a per window basis.") - -(defvar evil--jumps-window-jumps) ; defined in evil-jumps.el - -(defmacro lsp-ui-peek--with-evil-jumps (&rest body) - "Make `evil-jumps.el' commands work on `lsp-ui-peek--jumps'." - (declare (indent 1)) - `(let ((evil--jumps-window-jumps lsp-ui-peek--jumps)) - ,@body)) - -(with-eval-after-load 'evil-jumps - ;; We need to jump through some hoops to prevent the byte-compiler from - ;; compiling this code. We can’t compile the code without requiring - ;; ‘evil-macros’. - (eval '(progn - (evil-define-motion lsp-ui-peek-jump-backward (count) - (lsp-ui-peek--with-evil-jumps - (evil--jump-backward count) - (run-hooks 'xref-after-return-hook))) - (evil-define-motion lsp-ui-peek-jump-forward (count) - (lsp-ui-peek--with-evil-jumps - (evil--jump-forward count) - (run-hooks 'xref-after-return-hook)))) - t)) - -(defmacro lsp-ui-peek--prop (prop &optional string) - `(get-text-property 0 ,prop (or ,string (lsp-ui-peek--get-text-selection) ""))) - -(defmacro lsp-ui-peek--add-prop (prop &optional string) - `(let ((obj (or ,string (lsp-ui-peek--get-text-selection)))) - (add-text-properties 0 (length obj) ,prop obj) - obj)) - -(defun lsp-ui-peek--truncate (len s) - (if (> (string-width s) len) - (format "%s.." (substring s 0 (- len 2))) - s)) - -(defun lsp-ui-peek--get-text-selection (&optional n) - (nth (or n lsp-ui-peek--selection) - (--remove (get-text-property 0 'lsp-ui-peek-hidden it) lsp-ui-peek--list))) - -(defun lsp-ui-peek--get-selection () - (get-text-property 0 'lsp-ui-peek (or (lsp-ui-peek--get-text-selection) ""))) - -(defun lsp-ui-peek--visual-index () - (- lsp-ui-peek--selection lsp-ui-peek--offset)) - -(defun lsp-ui-peek--make-line (index src) - (-let* (((s1 . s2) src) - (len-s1 (length s1)) - (len-s2 (length s2)) - (on-selection (= (1+ (lsp-ui-peek--visual-index)) index)) - (face-left (if (= index 0) 'lsp-ui-peek-header 'lsp-ui-peek-peek)) - (face-right (cond (on-selection 'lsp-ui-peek-selection) - ((= index 0) 'lsp-ui-peek-header) - (t 'lsp-ui-peek-list)))) - (when on-selection - (setq s2 (copy-sequence s2)) - (add-face-text-property 0 len-s2 face-right nil s2)) - (unless (get-text-property 0 'lsp-ui-peek-faced s2) - (add-face-text-property 0 len-s2 face-right t s2) - (add-text-properties 0 len-s2 '(lsp-ui-peek-faced t) s2) - (add-face-text-property 0 len-s2 'default t s2)) - (add-face-text-property 0 len-s1 face-left t s1) - (add-face-text-property 0 len-s1 'default t s1) - (concat - s1 - (propertize "_" 'face face-left 'display `(space :align-to (- right-fringe ,(1+ lsp-ui-peek-list-width)))) - " " - s2 - (propertize "_" 'face face-right 'display `(space :align-to (- right-fringe 1))) - (propertize "\n" 'face face-right)))) - -(defun lsp-ui-peek--adjust (width strings) - (-let* (((s1 . s2) strings)) - (cons (lsp-ui-peek--truncate (- width (1+ lsp-ui-peek-list-width)) s1) - (lsp-ui-peek--truncate (- lsp-ui-peek-list-width 2) s2)))) - -(defun lsp-ui-peek--make-footer () - ;; Character-only terminals don't support characters of different height - (when (display-graphic-p) - (list - (concat - (propertize " " - 'face `(:background ,(face-background 'lsp-ui-peek-footer nil t) :height 1) - 'display `(space :align-to (- right-fringe ,(1+ lsp-ui-peek-list-width)))) - (propertize " " 'face '(:height 1) - 'display `(space :align-to (- right-fringe ,lsp-ui-peek-list-width))) - (propertize " " - 'face `(:background ,(face-background 'lsp-ui-peek-footer nil t) :height 1) - 'display `(space :align-to (- right-fringe 0))) - (propertize "\n" 'face '(:height 1)) - (propertize "\n" 'face '(:height 0.5)))))) - -(defun lsp-ui-peek--peek-new (src1 src2) - (-let* ((win-width (window-text-width)) - (string (-some--> (-zip-fill "" src1 src2) - (--map (lsp-ui-peek--adjust win-width it) it) - (-map-indexed 'lsp-ui-peek--make-line it) - (-concat it (lsp-ui-peek--make-footer)))) - (next-line (line-beginning-position 2)) - (ov (or (when (overlayp lsp-ui-peek--overlay) lsp-ui-peek--overlay) - (make-overlay next-line next-line)))) - (setq lsp-ui-peek--overlay ov) - (overlay-put ov 'after-string (mapconcat 'identity string "")) - (overlay-put ov 'display-line-numbers-disable t) - (overlay-put ov 'window (get-buffer-window)))) - -(defun lsp-ui-peek--expand-buffer (files) - (if (--any? (equal (car it) buffer-file-name) files) - (list buffer-file-name) - (list (caar files)))) - -(defun lsp-ui-peek--expand (xrefs) - (let* ((to-expand (->> (--map (cons (plist-get it :file) (plist-get it :count)) xrefs) - (funcall lsp-ui-peek-expand-function))) - first) - (while (nth lsp-ui-peek--selection lsp-ui-peek--list) - (when (and (lsp-ui-peek--prop 'xrefs) - (member (lsp-ui-peek--prop 'file) to-expand)) - (unless first - (setq first (1+ lsp-ui-peek--selection))) - (lsp-ui-peek--toggle-file t)) - (setq lsp-ui-peek--selection (1+ lsp-ui-peek--selection))) - (setq lsp-ui-peek--selection (or first 0)) - (lsp-ui-peek--recenter))) - -(defun lsp-ui-peek--show (xrefs) - "Create a window to list references/defintions. -XREFS is a list of references/definitions." - (setq lsp-ui-peek--win-start (window-start) - lsp-ui-peek--selection 0 - lsp-ui-peek--offset 0 - lsp-ui-peek--size-list 0 - lsp-ui-peek--list nil) - (when (eq (logand lsp-ui-peek-peek-height 1) 1) - (setq lsp-ui-peek-peek-height (1+ lsp-ui-peek-peek-height))) - (when (< (- (line-number-at-pos (window-end)) (line-number-at-pos)) - (+ lsp-ui-peek-peek-height 3)) - (recenter 15)) - (setq xrefs (--sort (string< (plist-get it :file) (plist-get other :file)) xrefs)) - (--each xrefs - (-let* (((&plist :file filename :xrefs xrefs :count count) it) - (len-str (number-to-string count))) - (setq lsp-ui-peek--size-list (+ lsp-ui-peek--size-list count)) - (push (concat (propertize (lsp-ui--workspace-path filename) - 'face 'lsp-ui-peek-filename - 'file filename - 'xrefs xrefs) - (propertize " " 'display `(space :align-to (- right-fringe ,(1+ (length len-str))))) - (propertize len-str 'face 'lsp-ui-peek-filename)) - lsp-ui-peek--list))) - (setq lsp-ui-peek--list (nreverse lsp-ui-peek--list)) - (lsp-ui-peek--expand xrefs) - (lsp-ui-peek--peek)) - -(defun lsp-ui-peek--recenter () - (let ((half-height (/ lsp-ui-peek-peek-height 2))) - (when (> lsp-ui-peek--selection half-height) - (setq lsp-ui-peek--offset (- lsp-ui-peek--selection (1- half-height)))))) - -(defun lsp-ui-peek--fill (min-len list) - (let ((len (length list))) - (if (< len min-len) - (append list (-repeat (- min-len len) "")) - list))) - -(defun lsp-ui-peek--render (major string) - (with-temp-buffer - (insert string) - (delay-mode-hooks - (let ((inhibit-message t)) - (funcall major)) - (ignore-errors - (font-lock-ensure))) - (buffer-string))) - -(defun lsp-ui-peek--peek () - "Show reference's chunk of code." - (-let* ((xref (lsp-ui-peek--get-selection)) - ((&plist :file file :chunk chunk) (or xref lsp-ui-peek--last-xref)) - (header (concat " " (lsp-ui--workspace-path file) "\n")) - (header2 (format " %s %s" lsp-ui-peek--size-list (symbol-name lsp-ui-peek--kind))) - (ref-view (--> chunk - (if (eq lsp-ui-peek-fontify 'on-demand) - (lsp-ui-peek--render major-mode it) - chunk) - (subst-char-in-string ?\t ?\s it) - (concat header it) - (split-string it "\n"))) - (list-refs (->> lsp-ui-peek--list - (--remove (lsp-ui-peek--prop 'lsp-ui-peek-hidden it)) - (-drop lsp-ui-peek--offset) - (-take (1- lsp-ui-peek-peek-height)) - (lsp-ui-peek--fill (1- lsp-ui-peek-peek-height)) - (-concat (list header2))))) - (setq lsp-ui-peek--last-xref (or xref lsp-ui-peek--last-xref)) - (lsp-ui-peek--peek-new ref-view list-refs))) - -(defun lsp-ui-peek--toggle-text-prop (s) - (let ((state (lsp-ui-peek--prop 'lsp-ui-peek-hidden s))) - (lsp-ui-peek--add-prop `(lsp-ui-peek-hidden ,(not state)) s))) - -(defun lsp-ui-peek--toggle-hidden (file) - (setq lsp-ui-peek--list - (--map-when (string= (plist-get (lsp-ui-peek--prop 'lsp-ui-peek it) :file) file) - (prog1 it (lsp-ui-peek--toggle-text-prop it)) - lsp-ui-peek--list))) - -(defun lsp-ui-peek--remove-hidden (file) - (setq lsp-ui-peek--list - (--map-when (string= (plist-get (lsp-ui-peek--prop 'lsp-ui-peek it) :file) file) - (prog1 it (lsp-ui-peek--add-prop '(lsp-ui-peek-hidden nil) it)) - lsp-ui-peek--list))) - -(defun lsp-ui-peek--make-ref-line (xref) - (-let* (((&plist :summary summary :line line :file file) xref) - (string (format "%-3s %s" - (propertize (number-to-string (1+ line)) - 'face 'lsp-ui-peek-line-number) - (string-trim summary)))) - (lsp-ui-peek--add-prop `(lsp-ui-peek ,xref file ,file) string))) - -(defun lsp-ui-peek--insert-xrefs (xrefs filename index) - (setq lsp-ui-peek--list (--> (lsp-ui-peek--get-xrefs-in-file (cons filename xrefs)) - (-map 'lsp-ui-peek--make-ref-line it) - (-insert-at (1+ index) it lsp-ui-peek--list) - (-flatten it))) - (lsp-ui-peek--add-prop '(xrefs nil))) - -(defun lsp-ui-peek--toggle-file (&optional no-update) - (interactive) - (-if-let* ((xrefs (lsp-ui-peek--prop 'xrefs)) - (filename (lsp-ui-peek--prop 'file)) - (index (--find-index (equal (lsp-ui-peek--prop 'file it) filename) - lsp-ui-peek--list))) - (lsp-ui-peek--insert-xrefs xrefs filename index) - (let ((file (lsp-ui-peek--prop 'file))) - (lsp-ui-peek--toggle-hidden file) - (while (not (equal file (lsp-ui-peek--prop 'file))) - (lsp-ui-peek--select-prev t)))) - (unless no-update - (lsp-ui-peek--peek))) - -(defun lsp-ui-peek--select (index) - (setq lsp-ui-peek--selection (+ lsp-ui-peek--selection index))) - -(defun lsp-ui-peek--select-next (&optional no-update) - (interactive) - (when (lsp-ui-peek--get-text-selection (1+ lsp-ui-peek--selection)) - (lsp-ui-peek--select 1) - (while (> (lsp-ui-peek--visual-index) (- lsp-ui-peek-peek-height 2)) - (setq lsp-ui-peek--offset (1+ lsp-ui-peek--offset))) - (unless no-update - (lsp-ui-peek--peek)))) - -(defun lsp-ui-peek--select-prev (&optional no-update) - (interactive) - (when (> lsp-ui-peek--selection 0) - (lsp-ui-peek--select -1) - (while (< (lsp-ui-peek--visual-index) 0) - (setq lsp-ui-peek--offset (1- lsp-ui-peek--offset)))) - (unless no-update - (lsp-ui-peek--peek))) - -(defun lsp-ui-peek--skip-refs (fn) - (let ((last-file (lsp-ui-peek--prop 'file)) - last-selection) - (when (lsp-ui-peek--get-selection) - (while (and (equal (lsp-ui-peek--prop 'file) last-file) - (not (equal last-selection lsp-ui-peek--selection))) - (setq last-selection lsp-ui-peek--selection) - (funcall fn t))))) - -(defun lsp-ui-peek--select-prev-file () - (interactive) - (if (not (lsp-ui-peek--get-selection)) - (lsp-ui-peek--select-prev) - (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-prev) - (when (lsp-ui-peek--get-selection) - (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-prev) - (unless (= lsp-ui-peek--selection 0) - (lsp-ui-peek--select-next t)))) - (if (lsp-ui-peek--prop 'xrefs) - (lsp-ui-peek--toggle-file) - (lsp-ui-peek--remove-hidden (lsp-ui-peek--prop 'file))) - (lsp-ui-peek--select-next t) - (lsp-ui-peek--recenter) - (lsp-ui-peek--peek)) - -(defun lsp-ui-peek--select-next-file () - (interactive) - (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-next) - (if (lsp-ui-peek--prop 'xrefs) - (lsp-ui-peek--toggle-file) - (lsp-ui-peek--remove-hidden (lsp-ui-peek--prop 'file))) - (lsp-ui-peek--select-next t) - (lsp-ui-peek--recenter) - (lsp-ui-peek--peek)) - -(defun lsp-ui-peek--peek-hide () - "Hide the chunk of code and restore previous state." - (when (overlayp lsp-ui-peek--overlay) - (delete-overlay lsp-ui-peek--overlay)) - (setq lsp-ui-peek--overlay nil - lsp-ui-peek--last-xref nil) - (set-window-start (get-buffer-window) lsp-ui-peek--win-start)) - -(defun lsp-ui-peek--deactivate-keymap () - "Deactivate keymap." - (-when-let (fn lsp-ui-peek--deactivate-keymap-fn) - (setq lsp-ui-peek--deactivate-keymap-fn nil) - (funcall fn))) - -(defun lsp-ui-peek--goto-xref (&optional x other-window) - "Go to a reference/definition." - (interactive) - (-if-let (xref (or x (lsp-ui-peek--get-selection))) - (-let (((&plist :file file :line line :column column) xref) - (buffer (current-buffer))) - (if (not (file-readable-p file)) - (user-error "File not readable: %s" file) - (setq lsp-ui-peek--win-start nil) - (lsp-ui-peek--abort) - (let ((marker (with-current-buffer - (or (get-file-buffer file) - (find-file-noselect file)) - (save-restriction - (widen) - (save-excursion - ;; When we jump to a file with line/column unspecified, - ;; we do not want to move the point if the buffer exists. - ;; We interpret line=column=0 differently here. - (when (> (+ line column) 0) - (goto-char 1) - (forward-line line) - (forward-char column)) - (point-marker))))) - (current-workspace lsp--cur-workspace)) - (if other-window - (pop-to-buffer (marker-buffer marker) t) - (switch-to-buffer (marker-buffer marker))) - (with-current-buffer buffer - (lsp-ui-peek-mode -1)) - (unless lsp--cur-workspace - (setq lsp--cur-workspace current-workspace)) - (unless lsp-mode - (lsp-mode 1) - (lsp-on-open)) - (goto-char marker) - (run-hooks 'xref-after-jump-hook)))) - (lsp-ui-peek--toggle-file))) - -(defun lsp-ui-peek--goto-xref-other-window () - (interactive) - (lsp-ui-peek--goto-xref nil t)) - -(defvar lsp-ui-peek-mode-map nil - "Keymap for ‘lsp-ui-peek-mode’.") -(unless lsp-ui-peek-mode-map - (let ((map (make-sparse-keymap))) - (suppress-keymap map t) - (define-key map "\e\e\e" 'lsp-ui-peek--abort) - (define-key map "\C-g" 'lsp-ui-peek--abort) - (define-key map (kbd "M-n") 'lsp-ui-peek--select-next-file) - (define-key map (kbd "<right>") 'lsp-ui-peek--select-next-file) - (define-key map (kbd "M-p") 'lsp-ui-peek--select-prev-file) - (define-key map (kbd "<left>") 'lsp-ui-peek--select-prev-file) - (define-key map (kbd "C-n") 'lsp-ui-peek--select-next) - (define-key map (kbd "n") 'lsp-ui-peek--select-next) - (define-key map (kbd "<down>") 'lsp-ui-peek--select-next) - (define-key map (kbd "C-p") 'lsp-ui-peek--select-prev) - (define-key map (kbd "p") 'lsp-ui-peek--select-prev) - (define-key map (kbd "<up>") 'lsp-ui-peek--select-prev) - (define-key map (kbd "TAB") 'lsp-ui-peek--toggle-file) - (define-key map (kbd "q") 'lsp-ui-peek--abort) - (define-key map (kbd "RET") 'lsp-ui-peek--goto-xref) - (define-key map (kbd "M-RET") 'lsp-ui-peek--goto-xref-other-window) - (setq lsp-ui-peek-mode-map map))) - -(defun lsp-ui-peek--disable () - "Do not call this function, call `lsp-ui-peek--abort' instead." - (when (bound-and-true-p lsp-ui-peek-mode) - (lsp-ui-peek-mode -1) - (lsp-ui-peek--peek-hide))) - -(defun lsp-ui-peek--abort () - (interactive) - ;; The timer fixes https://github.com/emacs-lsp/lsp-ui/issues/33 - (run-with-idle-timer 0 nil 'lsp-ui-peek--disable)) - -(define-minor-mode lsp-ui-peek-mode - "Mode for lsp-ui-peek." - :init-value nil - (if lsp-ui-peek-mode - (setq lsp-ui-peek--deactivate-keymap-fn (set-transient-map lsp-ui-peek-mode-map t 'lsp-ui-peek--abort)) - (lsp-ui-peek--deactivate-keymap) - (lsp-ui-peek--peek-hide))) - -(defun lsp-ui-peek--find-xrefs (input kind &optional request param) - "Find INPUT references. -KIND is ‘references’, ‘definitions’ or a custom kind." - (setq lsp-ui-peek--kind kind) - (let ((xrefs (lsp-ui-peek--get-references kind request param))) - (unless xrefs - (user-error "No %s found for: %s" (symbol-name kind) input)) - (xref-push-marker-stack) - (when (featurep 'evil-jumps) - (lsp-ui-peek--with-evil-jumps (evil-set-jump))) - (if (and (not lsp-ui-peek-always-show) - (not (cdr xrefs)) - (= (length (plist-get (car xrefs) :xrefs)) 1)) - (-let* ((xref (car (plist-get (car xrefs) :xrefs))) - ((&hash "uri" file "range" range) xref) - ((&hash "line" line "character" col) (gethash "start" range)) - (file (lsp--uri-to-path file))) - (lsp-ui-peek--goto-xref `(:file ,file :line ,line :column ,col))) - (lsp-ui-peek-mode) - (lsp-ui-peek--show xrefs)))) - -(defun lsp-ui-peek-find-references () - "Find references to the IDENTIFIER at point." - (interactive) - (lsp-ui-peek--find-xrefs (symbol-at-point) - 'references - "textDocument/references" - (lsp--make-reference-params))) - -(defun lsp-ui-peek-find-definitions () - "Find definitions to the IDENTIFIER at point." - (interactive) - (lsp-ui-peek--find-xrefs (symbol-at-point) - 'definitions - "textDocument/definition")) - -(defun lsp-ui-peek-find-implementation () - "Find implementation locations of the symbol at point." - (interactive) - (lsp-ui-peek--find-xrefs (symbol-at-point) - 'implementation - "textDocument/implementation")) - -(defun lsp-ui-peek-find-workspace-symbol (pattern) - "Find symbols in the worskpace. -The symbols are found matching PATTERN." - (interactive (list (read-string "workspace/symbol: " - nil 'xref--read-pattern-history))) - (lsp-ui-peek--find-xrefs pattern - 'symbols - "workspace/symbol" - (list :query pattern))) - -(defun lsp-ui-peek-find-custom (kind request &optional extra) - "Find custom references. -KIND is a symbol to name the references (definition, reference, ..). -REQUEST is the method string to send the the language server. -EXTRA is a plist of extra parameters." - (lsp-ui-peek--find-xrefs (symbol-at-point) kind request - (append extra (lsp--text-document-position-params)))) - -(defun lsp-ui-peek--extract-chunk-from-buffer (pos start end) - "Return the chunk of code pointed to by POS (a Position object) in the current buffer. -START and END are delimiters." - (let* ((point (lsp--position-to-point pos)) - (inhibit-field-text-motion t) - (line-start (1+ (- 1 (/ lsp-ui-peek-peek-height 2)))) - (line-end (/ lsp-ui-peek-peek-height 2))) - (save-excursion - (goto-char point) - (let* ((before (buffer-substring (line-beginning-position line-start) (line-beginning-position))) - (line (buffer-substring (line-beginning-position) (line-end-position))) - (after (buffer-substring (line-end-position) (line-end-position line-end))) - (len (length line))) - (add-face-text-property (max (min start len) 0) - (max (min end len) 0) - 'lsp-ui-peek-highlight t line) - `(,line . ,(concat before line after)))))) - -(defun lsp-ui-peek--xref-make-item (filename location) - "Return an item from a LOCATION in FILENAME. -LOCATION can be either a LSP Location or SymbolInformation." - ;; TODO: Read more informations from SymbolInformation. - ;; For now, only the location is used. - (-let* ((location (or (gethash "location" location) location)) - (range (gethash "range" location)) - ((&hash "start" pos-start "end" pos-end) range) - (start (gethash "character" pos-start)) - (end (gethash "character" pos-end)) - ((line . chunk) (lsp-ui-peek--extract-chunk-from-buffer pos-start start end))) - (list :summary (or line filename) - :chunk (or chunk filename) - :file filename - :line (gethash "line" pos-start) - :column start - :len (- end start)))) - -(defun lsp-ui-peek--fontify-buffer (filename) - (when (eq lsp-ui-peek-fontify 'always) - (unless buffer-file-name - (make-local-variable 'delay-mode-hooks) - (let ((buffer-file-name filename) - (enable-local-variables nil) - (inhibit-message t) - (delay-mode-hooks t)) - (set-auto-mode))) - (font-lock-ensure))) - -(defun lsp-ui-peek--get-xrefs-in-file (file) - "Return all references that contain a file. -FILE is a cons where its car is the filename and the cdr is a list of Locations -within the file. We open and/or create the file/buffer only once for all -references. The function returns a list of `ls-xref-item'." - (let* ((filename (car file)) - (visiting (find-buffer-visiting filename)) - (fn (lambda (loc) (lsp-ui-peek--xref-make-item filename loc)))) - (cond - (visiting - (with-temp-buffer - (insert-buffer-substring-no-properties visiting) - (lsp-ui-peek--fontify-buffer filename) - (mapcar fn (cdr file)))) - ((file-readable-p filename) - (with-temp-buffer - (insert-file-contents-literally filename) - (lsp-ui-peek--fontify-buffer filename) - (mapcar fn (cdr file)))) - (t (user-error "Cannot read %s" filename))))) - -(defun lsp-ui-peek--get-xrefs-list (file) - "Return a list of xrefs in FILE." - (-let* (((filename . xrefs) file)) - `(:file ,filename :xrefs ,xrefs :count ,(length xrefs)))) - -(defun lsp-ui-peek--locations-to-xref-items (locations) - "Return a list of list of item from LOCATIONS. -LOCATIONS is an array of Location objects: - -interface Location { - uri: DocumentUri; - range: Range; -}" - (-some--> (lambda (loc) (lsp--uri-to-path (gethash "uri" (or (gethash "location" loc) loc)))) - (seq-group-by it locations) - (mapcar #'lsp-ui-peek--get-xrefs-list it))) - -(defun lsp-ui-peek--to-sequence (maybe-sequence) - "If maybe-sequence is not a sequence, wraps it into a single-element sequence." - (if (sequencep maybe-sequence) maybe-sequence (list maybe-sequence))) - -(defun lsp-ui-peek--get-references (_kind request &optional param) - "Get all references/definitions for the symbol under point. -Returns item(s)." - (-some->> (lsp--send-request (lsp--make-request - request - (or param (lsp--text-document-position-params)))) - ;; Language servers may return a single LOCATION instead of a sequence of them. - (lsp-ui-peek--to-sequence) - (lsp-ui-peek--locations-to-xref-items) - (-filter 'identity))) - -(defvar lsp-ui-mode-map) - -(defun lsp-ui-peek-enable (_enable) - (interactive) - (unless (bound-and-true-p lsp-ui-mode-map) - (user-error "Please load lsp-ui before trying to enable lsp-ui-peek"))) - -;; lsp-ui.el loads lsp-ui-peek.el, so we can’t ‘require’ lsp-ui. -;; FIXME: Remove this cyclic dependency. -(declare-function lsp-ui--workspace-path "lsp-ui" (path)) - -(declare-function evil-set-jump "evil-jumps.el" (&optional pos)) - -(provide 'lsp-ui-peek) -;;; lsp-ui-peek.el ends here |