ltls

About
A language server that read Latex files and provides LanguageTool diagnostics.
Features
- Spell checking through LSP Diagnostics
- Corrections propositions in the form of code actions (not implemented)
- Support for the premium LanguageTool API
- Rate limiting and smart querying (that's only wishful thiniking, I have nto
implemented that yet)
- Can reach the LanguageTool API even behind a HTTP proxy server
- Custom matches to prevent false positive due to markup (not implemented)
Credits
The code LSP part started with me reading and copy-pasting bits of
efm-langserver, although since I got
the hang of the LSP protocol and I have not looked at efm in a while (that being
said, it's a great software and I still use it regularly).
I have not been reading the code from
ltex-ls, while writing this tool (mostly
because Java and Kotlin are completely alien to me), but I'd like to credit the
author of ltex-ls because I used ltex-ls for a long time (I wrote my PhD with it
because this project was not usable yet) and was inspired by it to use the LSP
approach.
If this does not fit your need, consider using ltex-ls instead, it is a great tool.
Differences with ltex-ls
- ltex-ls provides completion, ltls does not
- ltex-ls works for Markdown and other markup language, ltls focuses on latex
(I just added rudimentary support for plain text and plan on adding basic
markdown support but I will probably stop there)
- ltex-ls focuses on the local server, it handles downloading and running it
On the contrary, ltls focuses on the premium API: it will handle proxy server
and it will ensure the queries and their frequencies are compliant with what
LanguageTool allows. It will also try to only query for what recently changed to
avoid using you limited number of queries too quickly
Installation
From source:
# assuming $GOPATH/bin is in your $PATH
go install https://git.sr.ht/~lattay/ltls@latest
# or if ~/.local/bin is in your $PATH
git clone https://git.sr.ht/~lattay/ltls
cd ltls
go build .
cp ltls ~/.local/bin
Usage
ltls has only been tested on Neovim, but I suppose it should work with any other
standard compliant LSP client.
This is the parameters that can be configured at runtime:
{
"settings": {
"ltls": {
"apiRoot": string?, // "https://api.languagetoolplus.com/v2" change that to use a custom/local instance
"apiKey": string?, // $LT_API_KEY
"username": string?, // $LT_API_USERNAME
"language": string?, // "en"
"motherTongue": string?, // "en"
"disabledCategories": string?, // []
"disabledRules": string?, // []
"debug": string? // false
}
}
}
If you have a premium account, you can find your API key at https://languagetool.org/editor/settings/access-tokens.
For Neovim 0.11+ users I made a companion plugin that makes it trivial to enable ltls.
TODO
- Basic LSP events handling
- respond/do something on initialize
- respond to initialized
- do something on initialized
- respond to didSave
- send checks on didSave
- respond to didOpen
- send checks on didOpen
- respond didChangeConfiguration
- respond to shutdown
- respond to exit
- Move language settings to a file-specific context
- Handle LT API
- get checks from LanguageTool
- send new words to dictionnary
- Expose code actions
- Propose to apply the replacements
- Propose to add to dict on typos
- Rate limiting
- Fragment large queries in several HTTP requests
- debounce to avoid redundant queries
- hold a state of the document to patch and identify changed regions
- use the patches to send shorter non redundant requests
- Full testing suite
- unit testing elements of the LT client
- more testing of the server
- more testing of the slicer
- Languages
- Latex
- Plain text
- Markdown
LaTeX specific stuff:
- Split Latex code into markup/regular text
- Implement smart rules to replace markup with text
- all the math with
1+1=2
-
\`and''with"`
-
\emph, \text* with the parameter text
- maintain a stack of
begin environments to discard non text envs
- implement better rules on envs (for example you want to discard
figure but not the caption inside, you want to discard equation but
not the text inside)
- user defined matches?