Skip to content

Commit

Permalink
Support inlay hint protocol, but emacs' overlay is buggy, realtime re…
Browse files Browse the repository at this point in the history
…nder inlay hint, overlay will infect buffer's content.
  • Loading branch information
manateelazycat committed Oct 3, 2023
1 parent a3d67c8 commit 0ad8afb
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 21 deletions.
19 changes: 19 additions & 0 deletions core/fileaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def __init__(self, filepath, single_server_info, single_server, multi_servers_in
self.diagnostics = {}
self.diagnostics_ticker = 0

self.inlay_hints = {}

self.external_file_link = external_file_link
self.filepath = filepath

Expand Down Expand Up @@ -340,6 +342,23 @@ def send_code_action_request(self, lsp_server, range_start, range_end, action_ki
self.diagnostics[lsp_server_name] if lsp_server_name in self.diagnostics else [],
range_start, range_end, action_kind)

def push_inlay_hints(self, response, range_start, range_end):
for hint in response:
key = "{}-{}".format(hint["position"]["line"], hint["position"]["character"])
self.inlay_hints[key] = hint

self.inlay_hints = {k: self.inlay_hints[k] for k in sorted(self.inlay_hints, key=lambda x: [int(i) for i in x.split('-')])}

range_start_line = range_start['line']
range_end_line = range_end['line']

inlay_hints = list(reversed([v for k, v in self.inlay_hints.items() if range_start_line <= int(k.split('-')[0]) <= range_end_line]))

eval_in_emacs("lsp-bridge-inlay-hint--render",
self.filepath,
get_lsp_file_host(),
inlay_hints)

def save_file(self, buffer_name):
for lsp_server in self.get_lsp_servers():
lsp_server.send_did_save_notification(self.filepath, buffer_name)
Expand Down
1 change: 1 addition & 0 deletions core/handler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ def handle_response(self, request_id, response):
from core.handler.document_symbol import DocumentSymbol
from core.handler.jdtls.jdtls_list_overridable_methods import JdtlsListOverridableMethods
from core.handler.jdtls.jdtls_add_overridable_methods import JdtlsAddOverridableMethods
from core.handler.inlay_hint import InlayHint
23 changes: 23 additions & 0 deletions core/handler/inlay_hint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from core.handler import Handler
from core.utils import *


class InlayHint(Handler):
name = "inlay_hint"
method = "textDocument/inlayHint"
cancel_on_change = True
provider = "inlay_hint_provider"

def process_request(self, range_start, range_end) -> dict:
self.range_start = range_start
self.range_end = range_end

range = {
"start": range_start,
"end": range_end
}
return dict(range=range)

def process_response(self, response: dict) -> None:
if response is not None:
self.file_action.push_inlay_hints(response, self.range_start, self.range_end)
8 changes: 8 additions & 0 deletions core/lspserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ def __init__(self, message_queue, project_path, server_info, server_name, enable
self.code_format_provider = False
self.signature_help_provider = False
self.workspace_symbol_provider = False
self.inlay_hint_provider = False

self.code_action_kinds = [
"quickfix",
Expand Down Expand Up @@ -525,6 +526,8 @@ def handle_recv_message(self, message: dict):
self.signature_help_provider = False
elif error_message == "Unhandled method workspace/symbol":
self.workspace_symbol_provider = False
elif error_message == "Unhandled method textDocument/inlayHint":
self.inlay_hint_provider = False
else:
message_emacs(error_message)

Expand Down Expand Up @@ -600,6 +603,11 @@ def handle_recv_message(self, message: dict):
except Exception:
pass

try:
self.inlay_hint_provider = message["result"]["capabilities"]["inlayHintProvider"]["resolveProvider"]
except Exception:
pass

try:
text_document_sync = message["result"]["capabilities"]["textDocumentSync"]
if type(text_document_sync) is int:
Expand Down
133 changes: 133 additions & 0 deletions lsp-bridge-inlay-hint.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
;;; lsp-bridge-inlay-hint.el --- Inlay hint protocol -*- lexical-binding: t; -*-

;; Filename: lsp-bridge-inlay-hint.el
;; Description: Inlay hint protocol
;; Author: Andy Stewart <[email protected]>
;; Maintainer: Andy Stewart <[email protected]>
;; Copyright (C) 2023, Andy Stewart, all rights reserved.
;; Created: 2023-10-03 21:35:08
;; Version: 0.1
;; Last-Updated: 2023-10-03 21:35:08
;; By: Andy Stewart
;; URL: https://www.github.org/manateelazycat/lsp-bridge-inlay-hint
;; Keywords:
;; Compatibility: GNU Emacs 30.0.50
;;
;; Features that might be required by this library:
;;
;;
;;

;;; This file is NOT part of GNU Emacs

;;; 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:
;;
;; Inlay hint protocol
;;

;;; Installation:
;;
;; Put lsp-bridge-inlay-hint.el to your load-path.
;; The load-path is usually ~/elisp/.
;; It's set in your ~/.emacs like this:
;; (add-to-list 'load-path (expand-file-name "~/elisp"))
;;
;; And the following to your ~/.emacs startup file.
;;
;; (require 'lsp-bridge-inlay-hint)
;;
;; No need more.

;;; Customize:
;;
;;
;;
;; All of the above can customize by:
;; M-x customize-group RET lsp-bridge-inlay-hint RET
;;

;;; Change log:
;;
;; 2023/10/03
;; * First released.
;;

;;; Acknowledgements:
;;
;;
;;

;;; TODO
;;
;;
;;

;;; Require


;;; Code:

(defun lsp-bridge-inlay-hint ()
(lsp-bridge-call-file-api "inlay_hint"
(lsp-bridge--point-position (window-start))
(lsp-bridge--point-position (window-end))))

(defvar-local lsp-bridge-inlay-hint-overlays '())

(defun lsp-bridge-inlay-hint-hide-overlays ()
(when lsp-bridge-inlay-hint-overlays
(dolist (inlay-hint-overlay lsp-bridge-inlay-hint-overlays)
(delete-overlay inlay-hint-overlay)))

(setq-local lsp-bridge-inlay-hint-overlays nil))

(defun lsp-bridge-inlay-hint--render (filepath filehost inlay-hints)
(lsp-bridge--with-file-buffer filepath filehost
(lsp-bridge-inlay-hint-hide-overlays)

(dolist (hint inlay-hints)
(let* ((hint-start-pos (acm-backend-lsp-position-to-point (plist-get hint :position)))
(hint-at-end-of-line-p (save-excursion
(goto-char hint-start-pos)
(eolp)))
(hint-text (format "%s"
(cond ((listp (plist-get hint :label))
(apply 'concat
(mapcar (lambda (label)
(concat (plist-get label :value) " "))
(plist-get hint :label)
)))
(t (plist-get hint :label)))))
(hint-insert-text (if hint-at-end-of-line-p
(format "%s\n" hint-text)
hint-text))
(overlay (make-overlay
hint-start-pos
(1+ hint-start-pos)
nil t t)))
(overlay-put overlay 'display hint-insert-text)
(overlay-put overlay 'face `(:foreground "#aaaaaa"))
(overlay-put overlay 'read-only t)
(push overlay lsp-bridge-inlay-hint-overlays)
))))

(provide 'lsp-bridge-inlay-hint)

;;; lsp-bridge-inlay-hint.el ends here
22 changes: 11 additions & 11 deletions lsp-bridge.el
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
(require 'lsp-bridge-diagnostic)
(require 'lsp-bridge-lsp-installer)
(require 'lsp-bridge-org-babel)
(require 'lsp-bridge-inlay-hint)

(defgroup lsp-bridge nil
"LSP-Bridge group."
Expand Down Expand Up @@ -596,16 +597,16 @@ you can customize `lsp-bridge-get-workspace-folder' to return workspace folder p
(rust-ts-mode . rust-ts-mode-indent-offset) ; Rust
(rustic-mode . rustic-indent-offset) ; Rust
(scala-mode . scala-indent:step) ; Scala
(powershell-mode . powershell-indent) ; PowerShell
(ess-mode . ess-indent-offset) ; ESS (R)
(yaml-mode . yaml-indent-offset) ; YAML
(hack-mode . hack-indent-offset) ; Hack
(kotlin-mode . c-basic-offset) ; Kotlin
(verilog-mode . verilog-indent-level) ; Verilog
(vhdl-mode . vhdl-basic-offset) ; VHDL
(go-mode . c-basic-offset) ;Golang
(go-ts-mode . c-basic-offset) ;Golang
(svelte-mode . js-indent-level) ;Svelte
(powershell-mode . powershell-indent) ; PowerShell
(ess-mode . ess-indent-offset) ; ESS (R)
(yaml-mode . yaml-indent-offset) ; YAML
(hack-mode . hack-indent-offset) ; Hack
(kotlin-mode . c-basic-offset) ; Kotlin
(verilog-mode . verilog-indent-level) ; Verilog
(vhdl-mode . vhdl-basic-offset) ; VHDL
(go-mode . c-basic-offset) ;Golang
(go-ts-mode . c-basic-offset) ;Golang
(svelte-mode . js-indent-level) ;Svelte
(fsharp-mode . fsharp-indent-offset) ; F#
(default . standard-indent)) ; default fallback
"A mapping from `major-mode' to its indent variable.")
Expand Down Expand Up @@ -1329,7 +1330,6 @@ So we build this macro to restore postion after code format."
(buffer-name)
(acm-get-input-prefix)))


;; Complete other non-LSP backends.
(lsp-bridge-complete-other-backends)

Expand Down
3 changes: 2 additions & 1 deletion multiserver/css_emmet.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "vscode-css-language-server",
"rename": "vscode-css-language-server",
"document_symbol": "vscode-css-language-server",
"workspace_symbol": "vscode-css-language-server"
"workspace_symbol": "vscode-css-language-server",
"inlay_hint": "vscode-css-language-server"
}
3 changes: 2 additions & 1 deletion multiserver/html_emmet.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "vscode-html-language-server",
"rename": "vscode-html-language-server",
"document_symbol": "vscode-html-language-server",
"workspace_symbol": "vscode-html-language-server"
"workspace_symbol": "vscode-html-language-server",
"inlay_hint": "vscode-html-language-server"
}
3 changes: 2 additions & 1 deletion multiserver/jedi_ruff.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "jedi",
"rename": "jedi",
"document_symbol": "jedi",
"workspace_symbol": "jedi"
"workspace_symbol": "jedi",
"inlay_hint": "jedi"
}
3 changes: 2 additions & 1 deletion multiserver/pylsp_ruff.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "pylsp",
"rename": "pylsp",
"document_symbol": "pylsp",
"workspace_symbol": "pylsp"
"workspace_symbol": "pylsp",
"inlay_hint": "pylsp"
}
3 changes: 2 additions & 1 deletion multiserver/pyright-background-analysis_ruff.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "pyright-background-analysis",
"rename": "pyright-background-analysis",
"document_symbol": "pyright-background-analysis",
"workspace_symbol": "pyright-background-analysis"
"workspace_symbol": "pyright-background-analysis",
"inlay_hint": "pyright-background-analysis"
}
3 changes: 2 additions & 1 deletion multiserver/pyright_ruff.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "pyright",
"rename": "pyright",
"document_symbol": "pyright",
"workspace_symbol": "pyright"
"workspace_symbol": "pyright",
"inlay_hint": "pyright"
}
3 changes: 2 additions & 1 deletion multiserver/python-ms_ruff.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "python-ms",
"rename": "python-ms",
"document_symbol": "python-ms",
"workspace_symbol": "python-ms"
"workspace_symbol": "python-ms",
"inlay_hint": "python-ms"
}
3 changes: 2 additions & 1 deletion multiserver/qmlls_javascript.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "qmlls",
"rename": "qmlls",
"document_symbol": "qmalls",
"workspace_symbol": "qmalls"
"workspace_symbol": "qmalls",
"inlay_hint": "qmalls"
}
3 changes: 2 additions & 1 deletion multiserver/typescript_eslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "typescript",
"rename": "typescript",
"document_symbol": "typescript",
"workspace_symbol": "typescript"
"workspace_symbol": "typescript",
"inlay_hint": "typescript"
}
3 changes: 2 additions & 1 deletion multiserver/volar_emmet.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"prepare_rename": "volar",
"rename": "volar",
"document_symbol": "volar",
"workspace_symbol": "volar"
"workspace_symbol": "volar",
"inlay_hint": "volar"
}

0 comments on commit 0ad8afb

Please sign in to comment.