Skip to content

Commit

Permalink
Close #792: Rework Eglot's mode-line
Browse files Browse the repository at this point in the history
Mimic flymake by replacing the old menus of the mode-line with
"context menus".  List all usefull commands under the main menu
(eglot-menu-map), and commands related to LSP debugging under the
project menu (eglot-debug-map).

* eglot.el (eglot-read-documentation, eglot-customize): New
commands.
(eglot-mode-line-string): New defcustom.
(eglot-menu-map, eglot-debug-map,): New variables.
(eglot--mode-line-props): Rework to use eglot-menu-map and
eglot-debug-map.
(eglot--mode-line-format): Use eglot-mode-line-string.
  • Loading branch information
nemethf authored and joaotavora committed Apr 4, 2022
1 parent b9b4d83 commit d28170b
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 11 deletions.
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# (upcoming)

##### Rework mode-line menus ([#792][github#792])

The new menus help discovering Egolot's features and shows which of
them are supported by the current server. Additionally, customizing
variable `eglot-mode-line-string` can leave more space on the
mode-line.

##### Easier to use LSP initialize.initializationOptions ([#901][github#901], [#845][github#845])
In `eglot-server-programs` a plist may be appended to the usual list
of strings passed as command line arguments. The value of its
Expand Down Expand Up @@ -358,6 +365,7 @@ and now said bunch of references-->
[github#751]: https://github.com/joaotavora/eglot/issues/751
[github#769]: https://github.com/joaotavora/eglot/issues/769
[github#787]: https://github.com/joaotavora/eglot/issues/787
[github#792]: https://github.com/joaotavora/eglot/issues/792
[github#794]: https://github.com/joaotavora/eglot/issues/794
[github#797]: https://github.com/joaotavora/eglot/issues/797
[github#803]: https://github.com/joaotavora/eglot/issues/803
Expand Down
129 changes: 118 additions & 11 deletions eglot.el
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ let the buffer grow forever."
"If non-nil, activate Eglot in cross-referenced non-project files."
:type 'boolean)

(defcustom eglot-mode-line-string "eglot"
"String displayed on the mode line when Eglot is active."
:type 'string)

(defvar eglot-withhold-process-id nil
"If non-nil, Eglot will not send the Emacs process id to the language server.
This can be useful when using docker to run a language server.")
Expand Down Expand Up @@ -1741,6 +1745,99 @@ If it is activated, also signal textDocument/didOpen."
(call-interactively what)
(force-mode-line-update t))))))

(defun eglot-read-documentation ()
"Open the on-line documentation."
(interactive)
(browse-url "https://github.com/joaotavora/eglot#readme"))

(defun eglot-customize ()
"Customize Eglot."
(interactive)
(customize-group "eglot"))

(easy-menu-define eglot-menu-map nil "Eglot"
(let ((action-help
"Get possible code actions for the active region or the point"))
`("Eglot"
;; Commands for getting information and customization.
["Read the documentation" eglot-read-documentation
:help "Read the on-line documentation"]
["Customize Eglot" eglot-customize
:help "Customize Eglot globally"]
"--"
;; xref like commands.
["Find definitions" xref-find-definitions
:help "Find definitions of the identifier at point"
:active (eglot--server-capable :definitionProvider)]
["Find references" xref-find-references
:help "Find references to the identifier at point"
:active (eglot--server-capable :referencesProvider)]
["Find symbols in workspace (apropos)" xref-find-apropos
:help "Find symbols matching a query"
:active (eglot--server-capable :workspaceSymbolProvider)]
["Find declaration" eglot-find-declaration
:help "Find declaration for the identifier at point"
:active (eglot--server-capable :declarationProvider)]
["Find implementation" eglot-find-implementation
:help "Find implementation for the identifier at point"
:active (eglot--server-capable :implementationProvider)]
["Find type definition" eglot-find-typeDefinition
:help "Find type definition for the identifier at point"
:active (eglot--server-capable :typeDefinitionProvider)]
"--"
;; LSP-related commands (mostly Eglot's own commands).
["Rename symbol" eglot-rename
:help "Rename current symbol"
:active (eglot--server-capable :renameProvider)]
["Format buffer" eglot-format-buffer
:help "Format contents of the buffer"
:active (eglot--server-capable :documentFormattingProvider)]
["Format region" eglot-format
:help "Format the active region"
:active (and (region-active-p)
(eglot--server-capable :documentRangeFormattingProvider))]
["Show all diagnostics" flymake-show-buffer-diagnostics
:help "Show diagnostics for current buffer (flymake)"]
["Show documentation for point" eldoc-doc-buffer
:help "Show documentation for point in a buffer (eldoc)"]
"--"
;; Code-action commands.
["All possible code actions" eglot-code-actions
:help ,action-help
:active (eglot--server-capable :codeActionProvider)]
["Organize imports" eglot-code-action-organize-imports
:help ,action-help
:visible (eglot--server-capable :codeActionProvider)]
["Extract" eglot-code-action-extract
:help ,action-help
:visible (eglot--server-capable :codeActionProvider)]
["Inline" eglot-code-action-inline
:help ,action-help
:visible (eglot--server-capable :codeActionProvider)]
["Rewrite" eglot-code-action-rewrite
:help ,action-help
:visible (eglot--server-capable :codeActionProvider)]
["Quickfix" eglot-code-action-quickfix
:help ,action-help
:visible (eglot--server-capable :codeActionProvider)])))

(easy-menu-define eglot-debug-map nil "Debugging the server communication"
'("Debugging the server communication"
["Go to events buffer" eglot-events-buffer
:help "Display the log buffer of the server communication"]
["Go to the stderr buffer" eglot-stderr-buffer
:help "Display the error buffer for current LSP server"]
["Reconnect to server" eglot-reconnect
:help "Reconnect to the current LSP server"]
["Quit server" eglot-shutdown
:help "Politely ask the LSP server to quit"]
"--"
["Customize events buffers"
(lambda ()
(interactive)
(customize-variable 'eglot-events-buffer-size))
:help "Customize variable eglot-events-buffer-size"]))

(defun eglot--mode-line-props (thing face defs &optional prepend)
"Helper for function `eglot--mode-line-format'.
Uses THING, FACE, DEFS and PREPEND."
Expand All @@ -1764,18 +1861,28 @@ Uses THING, FACE, DEFS and PREPEND."
(`(,_id ,doing ,done-p ,_detail) (and server (eglot--spinner server)))
(last-error (and server (jsonrpc-last-error server))))
(append
`(,(eglot--mode-line-props "eglot" 'eglot-mode-line nil))
`(,(propertize
eglot-mode-line-string
'face 'eglot-mode-line
'mouse-face 'mode-line-highlight
'help-echo "Eglot: an LSP client\nmouse-1: Display minor mode menu"
'keymap (let ((map (make-sparse-keymap)))
(define-key map [mode-line down-mouse-1] eglot-menu-map)
map)))
(when nick
`(":" ,(eglot--mode-line-props
nick 'eglot-mode-line
'((C-mouse-1 eglot-stderr-buffer "go to stderr buffer")
(mouse-1 eglot-events-buffer "go to events buffer")
(mouse-2 eglot-shutdown "quit server")
(mouse-3 eglot-reconnect "reconnect to server")))
,@(when last-error
`(":"
,(propertize
nick
'face 'eglot-mode-line
'mouse-face 'mode-line-highlight
'help-echo (format "Project '%s'\nmouse-1: LSP debugging menu" nick)
'keymap (let ((map (make-sparse-keymap)))
(define-key map [mode-line down-mouse-1] eglot-debug-map)
map))
,@(when last-error
`("/" ,(eglot--mode-line-props
"error" 'compilation-mode-line-fail
'((mouse-3 eglot-clear-status "clear this status"))
'((mouse-3 eglot-clear-status "Clear this status"))
(format "An error occurred: %s\n" (plist-get last-error
:message)))))
,@(when (and doing (not done-p))
Expand All @@ -1785,9 +1892,9 @@ Uses THING, FACE, DEFS and PREPEND."
`("/" ,(eglot--mode-line-props
(format "%d" pending) 'warning
'((mouse-3 eglot-forget-pending-continuations
"forget pending continuations"))
"Forget pending continuations"))
"Number of outgoing, \
still unanswered LSP requests to the server"))))))))
still unanswered LSP requests to the server\n"))))))))

(add-to-list 'mode-line-misc-info
`(eglot--managed-mode (" [" eglot--mode-line-format "] ")))
Expand Down

0 comments on commit d28170b

Please sign in to comment.