|
| 1 | +;;; lsp-matlab.el --- LSP mode integration for MATLAB -*- lexical-binding: t; -*- |
| 2 | + |
| 3 | +;;; Commentary: |
| 4 | +;; |
| 5 | +;; LSP client for the MATLAB language server |
| 6 | +;; |
| 7 | + |
| 8 | +;;; Code: |
| 9 | +(require 'lsp-mode) |
| 10 | + |
| 11 | +;;; MATLAB |
| 12 | +(defgroup lsp-matlab nil |
| 13 | + "Lsp support for MATLAB." |
| 14 | + :group 'lsp-mode |
| 15 | + :tag "Lsp MATLAB") |
| 16 | + |
| 17 | +(defcustom lsp-clients-matlab-nodejs "node" |
| 18 | + "Node.js to launch the MATLAB language server." |
| 19 | + :group 'lsp-matlab |
| 20 | + :type '(string)) |
| 21 | + |
| 22 | +(defcustom lsp-clients-matlab-server "/usr/local/apps/matlabls/out/index.js" |
| 23 | + "Path to the MATLAB language server. |
| 24 | +To setup, |
| 25 | +- Download the language server (clone or unzip): |
| 26 | + - git clone https://github.com/mathworks/MATLAB-language-server.git |
| 27 | + or |
| 28 | + - Download zip from https://github.com/mathworks/MATLAB-language-server |
| 29 | + and unzip. |
| 30 | +- In the downloaded directory, |
| 31 | + npm install |
| 32 | + npm run compile |
| 33 | + npm run package # optional JavaScript minimization |
| 34 | +- Set lsp-clients-matlab-server to the download directory, or |
| 35 | + copy the ./out and ./matlab/ directory trees to an install location, e.g. |
| 36 | + cp -r ./out/ /usr/local/apps/matlabls/out/ |
| 37 | + cp -r ./matlab/ /usr/local/apps/matlabls/matlab/ |
| 38 | + then set `lsp-clients-matlab-server' to the install location." |
| 39 | + :group 'lsp-matlab |
| 40 | + :type '(string)) |
| 41 | + |
| 42 | +(defcustom lsp-clients-matlab-server-args '("--stdio") |
| 43 | + "MATLAB language server arguments." |
| 44 | + :group 'lsp-matlab |
| 45 | + :risky t |
| 46 | + :type '(repeat string)) |
| 47 | + |
| 48 | +(defcustom lsp-clients-matlab-install-path "" |
| 49 | + "Path to MATLAB to use. |
| 50 | +If not specified, then matlab is used from the system path." |
| 51 | + :group 'lsp-matlab |
| 52 | + :type '(string)) |
| 53 | + |
| 54 | +(defcustom lsp-clients-matlab-cmd-args "" |
| 55 | + "Extra arguments the language server should specify when starting MATLAB." |
| 56 | + :group 'lsp-matlab |
| 57 | + :type '(string)) |
| 58 | + |
| 59 | +(defcustom lsp-clients-matlab-connection-timing "onStart" |
| 60 | + "When to start the MATLAB language server." |
| 61 | + :group 'lsp-matlab |
| 62 | + :type '(choice |
| 63 | + (const "onStart") |
| 64 | + (const "onDemand") |
| 65 | + (const "never"))) |
| 66 | + |
| 67 | +(defcustom lsp-clients-matlab-index-workspace nil |
| 68 | + "Whether or not to use the full background indexer. |
| 69 | +
|
| 70 | +Turning this on instructs the MATLAB language server to index all |
| 71 | +*.m files under the project root. If there are thousands of *.m |
| 72 | +files, then the MATLAB language server may become unresponsive, |
| 73 | +causing hangs." |
| 74 | + :group 'lsp-matlab |
| 75 | + :type '(boolean)) |
| 76 | + |
| 77 | +;; Tell lsp-mode about MATLAB language |
| 78 | +(add-to-list 'lsp-language-id-configuration '(matlab-mode . "MATLAB")) |
| 79 | + |
| 80 | +(defun matlabls-command () |
| 81 | + "Return matlabls launch command LIST." |
| 82 | + (let ((cmd (flatten-tree `(,lsp-clients-matlab-nodejs |
| 83 | + ,lsp-clients-matlab-server |
| 84 | + ,@lsp-clients-matlab-server-args)))) |
| 85 | + cmd)) |
| 86 | + |
| 87 | +;; lsp-register-custom-settings plus :initialized-fn send following. |
| 88 | +;; For available settings, see src/lifecycle/ConfigurationManager.ts |
| 89 | +;; Params: { |
| 90 | +;; "settings": { |
| 91 | +;; "MATLAB": { |
| 92 | +;; "telemetry": false, |
| 93 | +;; "matlabConnectionTiming": "onStart", |
| 94 | +;; "installPath": "/path/to/matlab", |
| 95 | +;; "indexWorkspace": false |
| 96 | +;; } |
| 97 | +;; } |
| 98 | +;; } |
| 99 | +;; |
| 100 | +;; Messages from the MATLAB language server: |
| 101 | +;; - "telemetry/logdata" |
| 102 | +;; The client can provide usage (telemetry) data to the server which is collected to improve |
| 103 | +;; the MATLAB language server. Setting telemetry to false tells the language server that the |
| 104 | +;; client is not sending data which is what Emacs is currently doing. |
| 105 | +;; - "mvmStateChange" |
| 106 | +;; When the MATLAB Virtual Machine (mvm) detects a change in MATLAB's state (disconnected, |
| 107 | +;; ready, or busy) the client will receive these messages. VS Code uses these messages for |
| 108 | +;; the embedded MATLAB Command Window. Currently, Emacs ignores these. |
| 109 | +;; - "matlab/connection/update/server” |
| 110 | +;; This message indicates a change in connection between the language server and MATLAB |
| 111 | +;; (connecting, connected, or disconnected). In our case, VS Code updates its UI affordance |
| 112 | +;; to show the active state of MATLAB. |
| 113 | + |
| 114 | +(lsp-register-custom-settings |
| 115 | + `(("MATLAB.indexWorkspace" nil t) |
| 116 | + ("MATLAB.installPath" (lambda () lsp-clients-matlab-install-path)) |
| 117 | + ("MATLAB.matlabConnectionTiming" ,lsp-clients-matlab-connection-timing) |
| 118 | + ("MATLAB.maxFileSizeForAnalysis" 0) |
| 119 | + ("MATLAB.telemetry" nil t))) |
| 120 | + |
| 121 | +(lsp-register-client |
| 122 | + (make-lsp-client :new-connection (lsp-stdio-connection #'matlabls-command) |
| 123 | + :major-modes '(matlab-mode) |
| 124 | + :ignore-messages '("readFile .*? requested by MATLAB but content not available") |
| 125 | + :server-id 'matlab-ls |
| 126 | + :language-id "MATLAB" |
| 127 | + :initialized-fn (lambda (workspace) |
| 128 | + (with-lsp-workspace workspace |
| 129 | + (lsp--set-configuration |
| 130 | + (lsp-configuration-section "MATLAB")))) |
| 131 | + :notification-handlers ;; See src/notifications/NotificationService.ts |
| 132 | + (ht ("telemetry/logdata" #'ignore) |
| 133 | + ("mvmStateChange" #'ignore) |
| 134 | + ("matlab/connection/update/server" #'ignore)))) |
| 135 | + |
| 136 | +(provide 'lsp-matlab) |
| 137 | +;;; lsp-matlab.el ends here |
| 138 | + |
| 139 | +;; LocalWords: defcustom nodejs matlabls npm defun fn |
0 commit comments