There’s now an official API for Grammarly and a language server. That means we can use eglot
to get Grammarly in Emacs buffers. Here’s the setup which mostly works.
Update: Grammarly announced they are discontinuing the API so this won’t work after January 10th, 2024. There are no good replacements. If I find one, I’ll add it here.
You can get an Grammarly API client ID by creating an app here.
Build the Grammarly VSCode extension:
git clone git@github.com:znck/grammarly.git
cd grammarly
# Install pnpm if you don't have it installed already
npm install -g pnpm
# Build the extension and language server
pnpm build
Wrap the node based language server in a script:
#!/bin/sh
node /{PATH TO REPO}/grammarly/extension/dist/server/index.node.js --stdio
Add it to the path or copy it to a global bin:
cp /{PATH TO REPO}/grammarlylsp /usr/local/bin/grammarlylsp
# Make it executable
chmod +x grammarlylsp
Configure eglot
to use it when in markdown mode:
(defclass eglot-grammarlylsp (eglot-lsp-server) ()
:documentation "Grammarly Language Server.")
(cl-defmethod eglot-initialization-options ((server eglot-grammarlylsp))
"Passes the initializationOptions required to run
the server."
`(:clientId "{GRAMMARLY API CLIENT ID HERE"))
(add-to-list 'eglot-server-programs
`(markdown-mode . (eglot-grammarlylsp ,(executable-find "grammarlylsp"))))
Links to this note
-
There are a few ways to get linting of prose (grammar and style, not just spellcheck) in Emacs. Unfortunately, there is no good language server implementation for the popular open-source command line tools. The best option right now is probably
proselint
, butvale
gives better suggestions. -
It’s useful to think about the underlying utilities that go into running one’s life and business with the same rigor used to build something significant. Afterall, the things we rely on every day can have an outsized impact on our own performance so why not treat it that way?