From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Chinmay Dalal Newsgroups: gmane.emacs.bugs Subject: bug#61412: [PATCH v2] Add inlay hints to eglot Date: Wed, 15 Feb 2023 18:26:15 +0530 Message-ID: <20230215125615.69890-1-dalal.chinmay.0101@gmail.com> References: <20230211081335.312224-1-dalal.chinmay.0101@gmail.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="4541"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Chinmay Dalal To: 61412@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Feb 15 15:39:49 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pSIwm-00010A-5a for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 15 Feb 2023 15:39:48 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pSIw6-00061H-OD; Wed, 15 Feb 2023 09:39:06 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pSIw3-00060P-Fo for bug-gnu-emacs@gnu.org; Wed, 15 Feb 2023 09:39:03 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pSIw3-0005gX-2k for bug-gnu-emacs@gnu.org; Wed, 15 Feb 2023 09:39:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1pSIw2-000568-VR for bug-gnu-emacs@gnu.org; Wed, 15 Feb 2023 09:39:02 -0500 X-Loop: help-debbugs@gnu.org In-Reply-To: <20230211081335.312224-1-dalal.chinmay.0101@gmail.com> Resent-From: Chinmay Dalal Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 15 Feb 2023 14:39:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 61412 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 61412-submit@debbugs.gnu.org id=B61412.167647190819497 (code B ref 61412); Wed, 15 Feb 2023 14:39:02 +0000 Original-Received: (at 61412) by debbugs.gnu.org; 15 Feb 2023 14:38:28 +0000 Original-Received: from localhost ([127.0.0.1]:58393 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pSIvR-00054M-O1 for submit@debbugs.gnu.org; Wed, 15 Feb 2023 09:38:27 -0500 Original-Received: from mail-pj1-f51.google.com ([209.85.216.51]:44017) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pSHL4-0005kJ-IM for 61412@debbugs.gnu.org; Wed, 15 Feb 2023 07:56:48 -0500 Original-Received: by mail-pj1-f51.google.com with SMTP id d13-20020a17090ad3cd00b0023127b2d602so1816242pjw.2 for <61412@debbugs.gnu.org>; Wed, 15 Feb 2023 04:56:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=rtNYSk2yclzJb5DHB8JqdpsUb1jzw+/wL5kcbDCFOyA=; b=OItnhbZdWf81AuFimihb7uYlUXZpLVtePw8DM+2K+BVdFv9CDs6p8LAz4ot20LMYEz +ytqx+xzHZN3uhuWi9SnbhP8nDOxB2veTF+uKjzKOesYlIKljSnytqBhEa0ryXegGcRZ 8g2zCQH3WZ68Ue3UJ2dCrGKj5ZMaO0kUzxfOAzMKl0w6cnERrCTbNEIZcArwnNf/mCnC pwRgmukwdUBSIsm4LTbaTvxGcYMyAQGoK+sh4oFYPjSQX73Ru1m+P6U/qNKbZe34hxUi Ybwq9DW31roL3NFCWp+TdeF7LZmzdjL1hCpwp4YAd5OHamyOxvlQdUuJ4xaJ+XNfZ0Nd kg9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=rtNYSk2yclzJb5DHB8JqdpsUb1jzw+/wL5kcbDCFOyA=; b=F7uOy434T0ysPogormmpFiOTeuuUIhNIsClmyPZuQIeEjJyP6jw/qBijoDgAEuetqR vH7RYVbny5pLfJ4uZ57iMChagTCQDBvgSqucuOUvMzeuoWM6W19u63I0bOB908aef0Vd 7Babefkx53r+ZLJBr47qZ+kX04mvD5TDvgWMLUrV+BPU47aB9m4Q6mKH44LdSGNx3FmG IbT5R+TVAMFiHT2Vdn8TRqysyxUcXJ0DYA76plA3NZmwt8z+gd8f5RgSBLtsK9glu2NI wjp8ywNxeu/3LXLCYiApvxbX0IAsTYa56/Y/3G2T/CLFzfQCBQPXpJwm7c+P4+6p4+uy bE/Q== X-Gm-Message-State: AO0yUKWgMg6tUNLjGpcHfbi6gVYclLf+8zXN/Xc1XMbCXFr57Bn5CVBW uR0A2Hw2xlQgRUQ2kUiQlhLdntvLEcY= X-Google-Smtp-Source: AK7set9u9VOTPwZ92kPgi8yM7pI4yQuavM8wQw+Ofv67xIonTlfNBzZ6kD/YVsDTolkTMFgnKXQ8WQ== X-Received: by 2002:a17:902:d4c1:b0:19a:9182:40fd with SMTP id o1-20020a170902d4c100b0019a918240fdmr2615873plg.65.1676465799216; Wed, 15 Feb 2023 04:56:39 -0800 (PST) Original-Received: from ganymede.bits-hyderabad.ac.in ([182.75.45.1]) by smtp.gmail.com with ESMTPSA id g1-20020a170902c38100b00198e663a856sm1197488plg.205.2023.02.15.04.56.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Feb 2023 04:56:38 -0800 (PST) X-Mailer: git-send-email 2.39.1 X-Mailman-Approved-At: Wed, 15 Feb 2023 09:38:24 -0500 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:255724 Archived-At: This uses different faces based on the "kind" of the hint: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHintKind --- lisp/progmodes/eglot.el | 85 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 6caf589..101644f 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -404,6 +404,10 @@ This can be useful when using docker to run a language server.") (when (assoc 'flex completion-styles-alist) (add-to-list 'completion-category-defaults '(eglot (styles flex basic)))) +(defcustom eglot-inlay-hints t + "If non-nil, enable inlay hints." + :type 'boolean) + ;;; Constants ;;; @@ -1624,7 +1628,8 @@ under cursor." (const :tag "Highlight links in document" :documentLinkProvider) (const :tag "Decorate color references" :colorProvider) (const :tag "Fold regions of buffer" :foldingRangeProvider) - (const :tag "Execute custom commands" :executeCommandProvider))) + (const :tag "Execute custom commands" :executeCommandProvider) + (const :tag "Inlay hints" :inlayHintProvider))) (defun eglot--server-capable (&rest feats) "Determine if current server is capable of FEATS." @@ -1845,6 +1850,8 @@ If it is activated, also signal textDocument/didOpen." (when (and buffer-file-name (eglot-current-server)) (setq eglot--diagnostics nil) (eglot--managed-mode) + (unless (not eglot-inlay-hints) + (eglot-inlay-mode)) (eglot--signal-textDocument/didOpen)))) (add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode) @@ -3456,6 +3463,82 @@ If NOERROR, return predicate, else erroring function." (revert-buffer) (pop-to-buffer (current-buffer))))) +(defface eglot-inlay-hint-face + '((t (:height 0.8 :inherit shadow))) + "Face used for inlay hint overlays.") + +(defface eglot-type-hint-face + '((t (:inherit eglot-inlay-hint))) + "Face used for type hints.") + +(defface eglot-parameter-hint-face + '((t (:inherit eglot-inlay-hint))) + "Face used for parameter hints.") + +(define-minor-mode eglot-inlay-mode + "Mode for displaying inlay hints." + :lighter " inlay" + (if eglot-inlay-mode + (progn + (add-hook 'after-save-hook 'eglot--update-hints 0 t) + (eglot--update-hints)) + (progn + (remove-hook 'after-save-hook 'eglot--update-hints t) + (eglot--remove-hints)))) + +(defun eglot--inlay-handler (buffer hints) + "Apply vector of inlay hints HINTS on buffer BUFFER." + (seq-doseq (hint hints) + (let* ((position (plist-get hint :position)) + (line (plist-get position :line)) + (character (plist-get position :character)) + (kind (plist-get hint :kind)) + (face (cond ((eq kind 1) + 'eglot-type-hint-face) + ((eq kind 2) + 'eglot-parameter-hint-face) + (t + 'eglot-inlay-hint-face))) + (label (plist-get hint :label))) + (when (stringp label) + (with-current-buffer buffer + (eglot--widening + (goto-char (point-min)) + (forward-line line) + (eglot-move-to-column character) + (let ((overlay (make-overlay (point) (point)))) + (overlay-put overlay 'before-string (propertize + (concat (if (plist-get hint :paddingLeft) " " "") + label + (if (plist-get hint :paddingRight) " " "")) + 'face face)) + (overlay-put overlay 'is-eglot-inlay-hint t)))))))) + +(defun eglot--remove-hints () + "Remove inlay hints from the buffer." + (remove-overlays nil nil 'is-eglot-inlay-hint t)) + +(defun eglot--update-hints () + "Request inlay hints for the current buffer and apply them." + (unless (eglot--server-capable :inlayHintProvider) + (eglot--error "This LSP server isn't an :inlayHintProvider")) + ;; Remove existing hints + (eglot--remove-hints) + (let ((buffer (current-buffer))) + (jsonrpc-async-request + (eglot--current-server-or-lose) + :textDocument/inlayHint + (list + :textDocument (eglot--TextDocumentIdentifier) + :range (list + :start (list :line 0 :character 0) + :end (list + :line (count-lines (point-min) (point-max)) + :character 0))) + :success-fn (lambda (hints) + (eglot--inlay-handler buffer hints)) + :deferred t))) + ;;; Hacks ;;; -- 2.39.1