summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorJoão Távora <joaotavora@gmail.com>2023-03-14 18:14:48 +0000
committerJoão Távora <joaotavora@gmail.com>2023-03-14 18:14:48 +0000
commita55aaf9eaf203a4aedb0a492de2c33ab54b0b11c (patch)
treed091d5f43d3d932d31e1183d8534db3a151e5f56 /doc
parenta0539190979e3c4adc59a7e527d9f5a850d966bf (diff)
parent4b6f2a7028b91128934a19f83572f24106782225 (diff)
downloademacs-a55aaf9eaf203a4aedb0a492de2c33ab54b0b11c.tar.gz
Merge from origin/emacs-29
4b6f2a7028b * lisp/progmodes/xref.el: Bump the version. 24c8b146bbc * lisp/progmodes/xref.el (xref--xref-buffer-mode): Split ... 46f9e53c3da Fix import of keys in buffer created by epa-search-keys 36ade0704e1 Fix connection-local variables settings e759905d2e0 ; Minor copyedits in EGLOT-NEWS ba22a2c346b Bump Eglot version to 1.12 54e123a5055 Update Eglot's manual about eglot-workspace-configuration 812597f864c ; * lisp/novice.el (disabled-command-function): Add note ... 4a603c98499 Amend last Eglot commit (bug#62065) b916ec88b2f Make eglot-ensure's post-command-hook run a bit later (bu... 1c05175c21a Fix display of disabled-command help text 3ce37db9882 Remove mention of old dotted-list reader quirk from manual 42335c2c1f1 Fix value history shown for 'gc-cons-percentage' fffbce29349 TRework fix for bug#62106 8bc12a27362 ; * etc/NEWS: Fix last change. 2ac068d294e ; Remove 'ns-popup-font-panel' from documentation 5bc32d008fb Add missing indentation rule for rust-ts-mode (Bug#62109) 0404924930d ; One more improvement to ELisp "internals" appendix. c857775ca61 Fix bug#62106 0fedbfa6a9d ; Minor improvement of documentation of GC thresholds b0b24ad2fc5 Add missing rust-ts-mode highlight query for scoped_type_... c0cf69f7a17 Make "case" keyword a dedenter in Python db178517ce7 ; * lisp/arc-mode.el (w32-get-console-codepage): Declare. 157a91b54be Fix decoding non-ASCII file names in zip archives on MS-W... 4803f972047 Fix copying binary files from zip archives 679f528b953 Skip ruby-ts-syntax-propertize-symbol unless treesitter i... 081cc7aa8e0 ; * doc/misc/eglot.texi (Project-specific configuration):... 1de513a29fa Fix enums and unions appearing as structs in c-ts-base-mo... ecdfd584a52 ruby-ts-mode: Fine-tune s-p-f on symbols (bug#62086) 29228e24f20 python-info-dedenter-opening-block-positions: Fix to supp... 01b65d442ad Autoload Eglot helper funtion eglot--debbugs-or-github-bu... 50a3559c5a7 Add chapter on advanced server configuration to Eglot manual 2e7460c2315 ; * lisp/progmodes/java-ts-mode.el (treesit-query-capture... 255eeee0e06 java-ts-mode: detect if text_block is supported. 6fe9075ff38 Revert workaround introduced in Bug#56271 f175141aead Fix searching for end of string in python-nav-end-of-stat... # Conflicts: # etc/NEWS
Diffstat (limited to 'doc')
-rw-r--r--doc/emacs/macos.texi7
-rw-r--r--doc/lispref/internals.texi9
-rw-r--r--doc/lispref/objects.texi7
-rw-r--r--doc/misc/eglot.texi352
4 files changed, 266 insertions, 109 deletions
diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
index 6b9ae196704..9f2c4721cab 100644
--- a/doc/emacs/macos.texi
+++ b/doc/emacs/macos.texi
@@ -201,13 +201,6 @@ Setting a lower number makes the trackpad more sensitive, and a higher
number makes the trackpad less sensitive.
@end table
-@subsection Font Panel
-
-@findex ns-popup-font-panel
-The standard Mac / GNUstep font panel is accessible with @kbd{M-x
-ns-popup-font-panel} and will set the default font in the frame most
-recently used or clicked on.
-
@c To make the setting permanent, use @samp{Save Options} in the
@c Options menu, or run @code{menu-bar-options-save}.
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 55f07e86f76..9928361f7b2 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -558,12 +558,15 @@ The initial threshold value is @code{GC_DEFAULT_THRESHOLD}, defined in
value is 400,000 for the default 32-bit configuration and 800,000 for
the 64-bit one. If you specify a larger value, garbage collection
will happen less often. This reduces the amount of time spent garbage
-collecting, but increases total memory use. You may want to do this
-when running a program that creates lots of Lisp data. However, we
+collecting (so Lisp programs will run faster between cycles of garbage
+collection that happen more rarely), but increases total memory use.
+You may want to do this when running a program that creates lots of
+Lisp data, especially if you need it to run faster. However, we
recommend against increasing the threshold for prolonged periods of
time, and advise that you never set it higher than needed for the
program to run in reasonable time. Using thresholds higher than
-necessary could potentially cause system-wide memory pressure, and
+necessary could potentially cause higher system-wide memory pressure,
+and also make each garbage-collection cycle take much more time, and
should therefore be avoided.
You can make collections more frequent by specifying a smaller value, down
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 99a3c073971..2fe7e6db560 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -1007,13 +1007,6 @@ It looks like this:
@end example
@end ifnottex
- As a somewhat peculiar side effect of @code{(a b . c)} and
-@code{(a . (b . c))} being equivalent, for consistency this means
-that if you replace @code{b} here with the empty sequence, then it
-follows that @code{(a . c)} and @code{(a . ( . c))} are equivalent,
-too. This also means that @code{( . c)} is equivalent to @code{c},
-but this is seldom used.
-
@node Association List Type
@subsubsection Association List Type
diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi
index eed9744b9f0..735da5f0163 100644
--- a/doc/misc/eglot.texi
+++ b/doc/misc/eglot.texi
@@ -98,6 +98,7 @@ This manual documents how to configure, use, and customize Eglot.
* Eglot and LSP Servers:: How to work with language servers.
* Using Eglot:: Important Eglot commands and variables.
* Customizing Eglot:: Eglot customization and advanced features.
+* Advanced server configuration:: Fine-tune a specific language server
* Troubleshooting Eglot:: Troubleshooting and reporting bugs.
* GNU Free Documentation License:: The license for this manual.
* Index::
@@ -226,11 +227,10 @@ This says to invoke @var{program} with zero or more arguments
standard input and standard output streams.
@item (@var{program} @var{args}@dots{} :initializationOptions @var{options}@dots{})
-Like above, but with @var{options} specifying the options to be
-used for constructing the @samp{initializationOptions} JSON object for
-the server. @var{options} can also be a function of one argument, in
-which case it will be called with the server instance as the argument,
-and should return the JSON object to use for initialization.
+@var{program} is invoked with @var{args} but @var{options} specifies
+how to construct the @samp{:initializationOptions} JSON object to pass
+the server on during the LSP handshake (@pxref{Advanced server
+configuration}).
@item (@var{host} @var{port} @var{args}@dots{})
Here @var{host} is a string and @var{port} is a positive integer
@@ -970,139 +970,307 @@ mechanism.
Set this variable to true if you'd like progress notifications coming
from the LSP server to be handled as Emacs's progress reporting
facilities.
+@end table
+
+@node Advanced server configuration
+@chapter Advanced server configuration
+
+Though many language servers work well out-of-the-box, most allow
+fine-grained control of their operation via specific configuration
+options that vary from server to server. A small number of servers
+require such special configuration to work acceptably, or even to work
+at all.
+
+After having setup a server executable program in
+@code{eglot-server-programs} (@pxref{Setting Up LSP Servers}) and
+ensuring Eglot can invoke it, you may want to take advantage of some
+of these options. You should first distinguish two main kinds of
+server configuration:
+
+@itemize @bullet
+@item
+Project-specific, applying to a specific project;
+
+@item
+User-specific, applying to all projects the server is used for.
+@end itemize
+
+When you have decided which kind you need, the following sections
+teach how Eglot's user variables can be used to achieve it:
+
+@menu
+* Project-specific configuration::
+* User-specific configuration::
+* JSONRPC objects in Elisp::
+@end menu
+It's important to note that not all servers allow both kinds of
+configuration, nor is it guaranteed that user options can be copied
+over to project options, and vice-versa. When in doubt, consult your
+language server's documentation.
+
+It's also worth noting that some language servers can read these
+settings from configuration files in the user's @code{HOME} directory
+or in a project's directory. For example, the @command{pylsp} Python
+server reads the file @file{~/.config/pycodestyle} for user
+configuration. The @command{clangd} C/C++ server reads both
+@file{~/.config/clangd/config.yaml} for user configuration and
+@file{.clangd} for project configuration. It may be advantageous to
+use these mechanisms instead of Eglot's, as the latter have the
+advantage of working with other LSP clients.
+
+@node Project-specific configuration
+@section Project-specific configuration
@vindex eglot-workspace-configuration
-@cindex server workspace configuration
-@item eglot-workspace-configuration
-This variable is meant to be set in the @file{.dir-locals.el} file, to
-provide per-project settings, as described below in more detail.
-@end table
+@cindex workspace configuration
+
+To set project-specific settings, which the LSP specification calls
+@dfn{workspace configuration}, the variable
+@code{eglot-workspace-configuration} may be used.
-Some language servers need to know project-specific settings, which
-the LSP calls @dfn{workspace configuration}. Eglot allows such fine
-tuning of per-project settings via the variable
-@code{eglot-workspace-configuration}. Eglot sends the settings in
-this variable to each server, and each server applies the portion of the
-settings relevant to it and ignores the rest. These settings are
-communicated to the server initially (upon establishing the
-connection) or when the settings are changed, or in response to a
-configuration request from the server.
-
-In many cases, servers can be configured globally using a
-configuration file in the user's home directory or in the project
-directory, which the language server reads. For example, the
-@command{pylsp} server for Python reads the file
-@file{~/.config/pycodestyle} and the @command{clangd} server reads the
-file @file{.clangd} anywhere in the current project's directory tree.
-If possible, we recommend using those configuration files that are
-independent of Eglot and Emacs; they have the advantage that they will
-work with other LSP clients as well.
-
-If you do need to provide Emacs-specific configuration for a language
-server, we recommend defining the appropriate value in the
-@file{.dir-locals.el} file in the project's directory. The value of
-this variable should be a property list of the following format:
+This variable is a directory-local variable (@pxref{Directory
+Variables, , Per-directory Local Variables, emacs, The GNU Emacs
+Manual}). It's important to recognize that this variable really only
+makes sense when set directory-locally. It usually does not make
+sense to set it file-locally or in a major-mode hook.
+
+The most common way to set @code{eglot-workspace-configuration } is
+using a @file{.dir-locals.el} file in the root of your project. If
+you can't do that, you may also set it from Elisp code via the
+@code{dir-locals-set-class-variables} function. (@pxref{Directory
+Local Variables,,, elisp, GNU Emacs Lisp Reference Manual}).
+
+However you choose to set it, the variable's value is a plist
+(@pxref{Property Lists,,, elisp, GNU Emacs Lisp Reference Manual}) with
+the following format:
@lisp
- (:@var{server} @var{plist}@dots{})
+ (@var{:server1} @var{plist1} @var{:server2} @var{plist2} @dots{})
@end lisp
@noindent
-Here @code{:@var{server}} identifies a particular language server and
-@var{plist} is the corresponding keyword-value property list of one or
-more parameter settings for that server, serialized by Eglot as a JSON
-object. @var{plist} may be arbitrarily complex, generally containing
-other keyword-value property sublists corresponding to JSON subobjects.
-The JSON values @code{true}, @code{false}, @code{null} and @code{@{@}}
-are represented by the Lisp values @code{t}, @code{:json-false},
-@code{nil}, and @code{eglot-@{@}}, respectively.
+Here, @var{:server1} and @var{:server2} are keywords whose names
+identify the LSP language servers to target. Consult server
+documentation to find out what name to use. @var{plist1} and
+@var{plist2} are plists of options, possibly nesting other plists.
@findex eglot-show-workspace-configuration
When experimenting with workspace settings, you can use the command
@kbd{M-x eglot-show-workspace-configuration} to inspect and debug the
-JSON value to be sent to the server. This helper command works even
-before actually connecting to the server.
+value of this variable in its final JSON form, ready to be sent to the
+server (@pxref{JSONRPC objects in Elisp}). This helper command works
+even before actually connecting to the server.
+
+These variable's value doesn't take effect immediately. That happens
+upon establishing the connection, in response to an explicit query
+from the server, or when issuing the command @kbd{M-x
+eglot-signal-didChangeConfiguration} which notifies the server during
+an ongoing Eglot session.
+
+@subsection Examples
+
+For some users, setting @code{eglot-workspace-configuration} is a
+somewhat daunting task. One of the reasons is having to manage the
+general Elisp syntax of per-mode directory-local variables, which uses
+alists (@pxref{Association Lists,,, elisp, GNU Emacs Lisp Reference
+Manual}), and the specific syntax of Eglot's variable, which uses
+plists. Some examples are useful.
+
+Let's say you want to configure two language servers to be used in a
+project written in a combination of the Python and Go languages. You
+want to use the @command{pylsp} and @command{gopls} LSP servers. In
+the documentation of the servers in question (or in some other editor's
+configuration file, or in some blog article), you find the following
+configuration options in informal dotted-notation syntax:
+
+@example
+pylsp.plugins.jedi_completion.include_params: true
+pylsp.plugins.jedi_completion.fuzzy: true
+pylsp.pylint.enabled: false
+gopls.usePlaceholders: true
+@end example
+
+To apply this to Eglot, and assuming you chose the
+@file{.dir-locals.el} file method, the contents of that file could be:
-Here's an example of defining the workspace-configuration settings for
-a project that uses two different language servers, one for Python,
-the other one for Go (presumably, the project is written in a
-combination of these two languages). The server for Python in this
-case is @command{pylsp}, the server for Go is @command{gopls}. The
-value of @code{eglot-workspace-configuration} in this case should be:
+@lisp
+((nil
+ . ((eglot-workspace-configuration
+ . (:pylsp (:plugins (:jedi_completion (:include_params t
+ :fuzzy t)
+ :pylint (:enabled :json-false)))
+ :gopls (:usePlaceholders t)))))
+ (python-mode . ((indent-tabs-mode . nil)))
+ (go-mode . ((indent-tabs-mode . t))))
+@end lisp
+
+@noindent
+This sets the value of @code{eglot-workspace-configuration} in all the
+buffers inside the project; each server will use only the section of
+the parameters intended for that server, and ignore the rest. Note
+how alists are used for associating Emacs mode names with alists
+associating variable names with variable values. Then notice how
+plists are used inside the value of
+@code{eglot-workspace-configuration}.
+
+This following form may also be used:
@lisp
((python-mode
. ((eglot-workspace-configuration
. (:pylsp (:plugins (:jedi_completion (:include_params t
:fuzzy t)
- :pylint (:enabled :json-false)))))))
+ :pylint (:enabled :json-false)))))
+ (indent-tabs-mode . nil)))
(go-mode
. ((eglot-workspace-configuration
- . (:gopls (:usePlaceholders t))))))
+ . (:gopls (:usePlaceholders t)))
+ (indent-tabs-mode . t))))
@end lisp
@noindent
-This should go into the @file{.dir-locals.el} file in the project's
-root directory. It sets up the value of
-@code{eglot-workspace-configuration} separately for each major mode.
-
-Alternatively, the same configuration could be defined as follows:
+This sets up the value of @code{eglot-workspace-configuration}
+separately depending on the major mode of each of that project's
+buffers. @code{python-mode} buffers will have the variable set to
+@code{(:pylsp (:plugins ...))}. @code{go-mode} buffers will have the
+variable set to @code{(:gopls (:usePlaceholders t))}.
+
+Some servers will issue workspace configuration for specific files
+inside your project. For example, if you know @code{gopls} is asking
+about specific files in the @code{src/imported} subdirectory and you
+want to set a different option for @code{gopls.usePlaceholders} , you
+may use something like:
@lisp
-((nil
+((python-mode
. ((eglot-workspace-configuration
. (:pylsp (:plugins (:jedi_completion (:include_params t
:fuzzy t)
- :pylint (:enabled :json-false)))
- :gopls (:usePlaceholders t))))))
+ :pylint (:enabled :json-false)))))
+ (indent-tabs-mode nil)))
+ (go-mode
+ . ((eglot-workspace-configuration
+ . (:gopls (:usePlaceholders t)))
+ (indent-tabs-mode t)))
+ ("src/imported"
+ . ((eglot-workspace-configuration
+ . (:gopls (:usePlaceholders nil))))))
@end lisp
-This is an equivalent setup which sets the value for all the
-major-modes inside the project; each server will use only the section
-of the parameters intended for that server, and ignore the rest.
-
-As yet another alternative, you can set the value of
-@code{eglot-workspace-configuration} programmatically, via the
-@code{dir-locals-set-class-variables} function, @pxref{Directory Local
-Variables,,, elisp, GNU Emacs Lisp Reference Manual}.
-
Finally, if one needs to determine the workspace configuration based
on some dynamic context, @code{eglot-workspace-configuration} can be
set to a function. The function is called with the
@code{eglot-lsp-server} instance of the connected server (if any) and
with @code{default-directory} set to the root of the project. The
-function should return a value of the form described above.
+function should return a plist suitable for use as the variable's
+value.
+
+@node User-specific configuration
+@section User-specific configuration
+@cindex initializationOptions
+@cindex command-line arguments
-Some servers need special hand-holding to operate correctly. If your
-server has some quirks or non-conformity, it's possible to extend
-Eglot via Elisp to adapt to it, by defining a suitable
-@code{eglot-initialization-options} method via @code{cl-defmethod}
-(@pxref{Generic Functions,,, elisp, GNU Emacs Lisp Reference Manual}).
+This kind of configuration applies to all projects the server is used
+for. Here, there are a number of ways to do this inside Eglot.
-Here's an example:
+A common way is to pass command-line options to the server invocation
+via @code{eglot-server-programs}. Let's say we want to configure
+where the @command{clangd} server reads its
+@code{compile_commands.json} from. This can be done like so:
@lisp
-(require 'eglot)
+(with-eval-after-load 'eglot
+ (add-to-list 'eglot-server-programs
+ `(c++-mode . ("clangd" "--compile-commands-dir=/tmp"))))
-(add-to-list 'eglot-server-programs
- '((c++-mode c-mode) . (eglot-cquery "cquery")))
+@end lisp
-(defclass eglot-cquery (eglot-lsp-server) ()
- :documentation "A custom class for cquery's C/C++ langserver.")
+@noindent
+Another way is to have Eglot pass a JSON object to the server during
+the LSP handshake. This is done using the
+@code{:initializationOptions} syntax of @code{eglot-server-programs}:
-(cl-defmethod eglot-initialization-options ((server eglot-cquery))
- "Passes through required cquery initialization options"
- (let* ((root (car (project-roots (eglot--project server))))
- (cache (expand-file-name ".cquery_cached_index/" root)))
- (list :cacheDirectory (file-name-as-directory cache)
- :progressReportFrequencyMs -1)))
+@lisp
+(with-eval-after-load 'eglot
+ (add-to-list 'eglot-server-programs
+ `(c++-mode . ("clangd" :initializationOptions
+ (:compilationDatabasePath "/tmp")))))
@end lisp
@noindent
-See the doc string of @code{eglot-initialization-options} for more
-details.
-@c FIXME: The doc string of eglot-initialization-options should be
-@c enhanced and extended.
+The argument @code{(:compilationDatabasePath "/tmp")} is Emacs's
+representation in plist format of a simple JSON object
+@code{@{"compilationDatabasePath": "/tmp"@}}. To learn how to
+represent more deeply nested options in this format, @xref{JSONRPC
+objects in Elisp}.
+
+In this case, the two examples achieve exactly the same, but notice
+how the option's name has changed between them.
+
+@vindex eglot-workspace-configuration
+Finally there is another way to do user-specific configuration of
+language servers, which may be used if the methods above are not
+supported. It consists of @emph{globally} setting
+@code{eglot-workspace-configuration}, a variable originally intended
+for project-specific configuration. This has the same effect as
+giving all your projects a certain default configuration, as described
+in @xref{Project-specific configuration}. Here is an example.
+
+@lisp
+(setq-default eglot-workspace-configuration
+ '(:pylsp (:plugins (:jedi_completion (:include_params t
+ :fuzzy t)
+ :pylint (:enabled :json-false)))
+ :gopls (:usePlaceholders t)))
+@end lisp
+
+Note that the global value of @code{eglot-workspace-configuration} is
+always overriden if a directory-local value is detected.
+
+@node JSONRPC objects in Elisp
+@section JSONRPC objects in Elisp
+
+Emacs's preferred way of representing JSON is via Lisp lists. In
+Eglot, the syntax of this list is the simplest possible (the one with
+fewer parenthesis), a plist (@pxref{Property Lists,,, elisp, GNU Emacs
+Lisp Reference Manual}).
+
+The plist may be arbitrarily complex, and generally containing other
+keyword-value property sub-plists corresponding to JSON sub-objects.
+
+For representing the JSON leaf values @code{true}, @code{false},
+@code{null} and @code{@{@}}, you can use the Lisp values @code{t},
+@code{:json-false}, @code{nil}, and @code{eglot-@{@}}, respectively.
+
+For example, this plist:
+
+@lisp
+(:pylsp (:plugins (:jedi_completion (:include_params t
+ :fuzzy t)
+ :pylint (:enabled :json-false)))
+ :gopls (:usePlaceholders t))
+@end lisp
+
+Is serialized by Eglot to the following JSON text:
+
+@example
+@{
+ "pylsp": @{
+ "plugins": @{
+ "jedi_completion": @{
+ "include_params": true,
+ "fuzzy": true
+ @},
+ "pylint": @{
+ "enabled": false
+ @}
+ @}
+ @},
+ "gopls": @{
+ "usePlaceholders":true
+ @},
+@}
+@end example
@node Troubleshooting Eglot
@chapter Troubleshooting Eglot