Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for MATLAB language server #4611

Merged
merged 5 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.org
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* Add hint about ~activation-fn~ for unsupported buffers.
* Add Roc support
* Add support for environment variables in rust analyzer runnables. Allowing the new ~Update Tests (Expect)~ code lens to work as expected.
* Add support for [[https://github.com/mathworks/MATLAB-language-server][MATLAB language server]] (requires [[https://github.com/MathWorks/Emacs-MATLAB-Mode][matlab-mode]]).

** 9.0.0
* Add language server config for QML (Qt Modeling Language) using qmlls.
Expand Down
139 changes: 139 additions & 0 deletions clients/lsp-matlab.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
;;; lsp-matlab.el --- LSP mode integration for MATLAB -*- lexical-binding: t; -*-

;;; Commentary:
;;
;; LSP client for the MATLAB language server
;;

;;; Code:
(require 'lsp-mode)

;;; MATLAB
(defgroup lsp-matlab nil
"Lsp support for MATLAB."
:group 'lsp-mode
:tag "Lsp MATLAB")

(defcustom lsp-clients-matlab-nodejs "node"
"Node.js to launch the MATLAB language server."
:group 'lsp-matlab
:type '(string))

(defcustom lsp-clients-matlab-server "/usr/local/apps/matlabls/out/index.js"
"Path to the MATLAB language server.
To setup,
- Download the language server (clone or unzip):
- git clone https://github.com/mathworks/MATLAB-language-server.git
or
- Download zip from https://github.com/mathworks/MATLAB-language-server
and unzip.
- In the downloaded directory,
npm install
npm run compile
npm run package # optional JavaScript minimization
- Set lsp-clients-matlab-server to the download directory, or
copy the ./out and ./matlab/ directory trees to an install location, e.g.
cp -r ./out/ /usr/local/apps/matlabls/out/
cp -r ./matlab/ /usr/local/apps/matlabls/matlab/
then set `lsp-clients-matlab-server' to the install location."
:group 'lsp-matlab
:type '(string))

(defcustom lsp-clients-matlab-server-args '("--stdio")
"MATLAB language server arguments."
:group 'lsp-matlab
:risky t
:type '(repeat string))

(defcustom lsp-clients-matlab-install-path ""
"Path to MATLAB to use.
If not specified, then matlab is used from the system path."
:group 'lsp-matlab
:type '(string))

(defcustom lsp-clients-matlab-cmd-args ""
"Extra arguments the language server should specify when starting MATLAB."
:group 'lsp-matlab
:type '(string))

(defcustom lsp-clients-matlab-connection-timing "onStart"
"When to start the MATLAB language server."
:group 'lsp-matlab
:type '(choice
(const "onStart")
(const "onDemand")
(const "never")))

(defcustom lsp-clients-matlab-index-workspace nil
"Whether or not to use the full background indexer.

Turning this on instructs the MATLAB language server to index all
*.m files under the project root. If there are thousands of *.m
files, then the MATLAB language server may become unresponsive,
causing hangs."
:group 'lsp-matlab
:type '(boolean))

;; Tell lsp-mode about MATLAB language
(add-to-list 'lsp-language-id-configuration '(matlab-mode . "MATLAB"))

(defun matlabls-command ()
"Return matlabls launch command LIST."
(let ((cmd (flatten-tree `(,lsp-clients-matlab-nodejs
,lsp-clients-matlab-server
,@lsp-clients-matlab-server-args))))
cmd))

;; lsp-register-custom-settings plus :initialized-fn send following.
;; For available settings, see src/lifecycle/ConfigurationManager.ts
;; Params: {
;; "settings": {
;; "MATLAB": {
;; "telemetry": false,
;; "matlabConnectionTiming": "onStart",
;; "installPath": "/path/to/matlab",
;; "indexWorkspace": false
;; }
;; }
;; }
;;
;; Messages from the MATLAB language server:
;; - "telemetry/logdata"
;; The client can provide usage (telemetry) data to the server which is collected to improve
;; the MATLAB language server. Setting telemetry to false tells the language server that the
;; client is not sending data which is what Emacs is currently doing.
;; - "mvmStateChange"
;; When the MATLAB Virtual Machine (mvm) detects a change in MATLAB's state (disconnected,
;; ready, or busy) the client will receive these messages. VS Code uses these messages for
;; the embedded MATLAB Command Window. Currently, Emacs ignores these.
;; - "matlab/connection/update/server”
;; This message indicates a change in connection between the language server and MATLAB
;; (connecting, connected, or disconnected). In our case, VS Code updates its UI affordance
;; to show the active state of MATLAB.

(lsp-register-custom-settings
`(("MATLAB.indexWorkspace" nil t)
("MATLAB.installPath" (lambda () lsp-clients-matlab-install-path))
("MATLAB.matlabConnectionTiming" ,lsp-clients-matlab-connection-timing)
("MATLAB.maxFileSizeForAnalysis" 0)
("MATLAB.telemetry" nil t)))

(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection #'matlabls-command)
:major-modes '(matlab-mode)
:ignore-messages '("readFile .*? requested by MATLAB but content not available")
:server-id 'matlab-ls
:language-id "MATLAB"
:initialized-fn (lambda (workspace)
(with-lsp-workspace workspace
(lsp--set-configuration
(lsp-configuration-section "MATLAB"))))
:notification-handlers ;; See src/notifications/NotificationService.ts
(ht ("telemetry/logdata" #'ignore)
("mvmStateChange" #'ignore)
("matlab/connection/update/server" #'ignore))))

(provide 'lsp-matlab)
;;; lsp-matlab.el ends here

;; LocalWords: defcustom nodejs matlabls npm defun fn
8 changes: 8 additions & 0 deletions docs/lsp-clients.json
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,14 @@
"installation-url": "https://github.com/artempyanykh/marksman",
"debugger": "Not available"
},
{
"name": "matlab",
"full-name": "MATLAB",
"server-name": "MATLAB language server",
"server-url": "https://github.com/mathworks/MATLAB-language-server",
"installation-url": "https://github.com/mathworks/MATLAB-language-server",
"debugger": "Not available"
},
{
"name": "meson",
"full-name": "Meson",
Expand Down
5 changes: 3 additions & 2 deletions lsp-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ As defined by the Language Server Protocol 3.16."
lsp-hack lsp-haskell lsp-haxe lsp-idris lsp-java lsp-javascript lsp-jq
lsp-json lsp-kotlin lsp-kubernetes-helm lsp-latex lsp-lisp lsp-ltex
lsp-ltex-plus lsp-lua lsp-fennel lsp-magik lsp-markdown lsp-marksman
lsp-mdx lsp-meson lsp-metals lsp-mint lsp-mojo lsp-move lsp-mssql
lsp-matlab lsp-mdx lsp-meson lsp-metals lsp-mint lsp-mojo lsp-move lsp-mssql
lsp-nextflow lsp-nginx lsp-nim lsp-nix lsp-nushell lsp-ocaml lsp-openscad
lsp-pascal lsp-perl lsp-perlnavigator lsp-php lsp-pls lsp-purescript
lsp-pwsh lsp-pyls lsp-pylsp lsp-pyright lsp-python-ms lsp-qml lsp-r
Expand Down Expand Up @@ -985,7 +985,8 @@ Changes take effect only when a new session is started."
(nushell-mode . "nushell")
(nushell-ts-mode . "nushell")
(meson-mode . "meson")
(yang-mode . "yang"))
(yang-mode . "yang")
(matlab-mode . "matlab"))
"Language id configuration.")

(defvar lsp--last-active-workspaces nil
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ nav:
- Magik: page/lsp-magik.md
- Markdown: page/lsp-markdown.md
- Marksman: page/lsp-marksman.md
- MATLAB: page/lsp-matlab.md
- Meson: page/lsp-meson.md
- Move: page/lsp-move.md
- MDX: page/lsp-mdx.md
Expand Down
Loading