2021-04-26 12:21:48 +00:00
|
|
|
# TypeScript plugin for Syndicate
|
|
|
|
|
|
|
|
Rewrites Syndicate DSL syntax into plain TypeScript as a `tsserver`
|
|
|
|
plugin, allowing your IDE to work directly with Syndicate constructs
|
|
|
|
and not requiring a separate preprocessing step.
|
|
|
|
|
|
|
|
Sadly, `tsc` doesn't pay attention to plugins (not as of April 2021,
|
|
|
|
anyway). If you're using `tsc` as part of your build, you will need to
|
|
|
|
use `@syndicate-lang/tsc`'s `syndicate-tsc` command instead.
|
|
|
|
|
|
|
|
## Installing the plugin
|
|
|
|
|
|
|
|
`package.json`:
|
|
|
|
|
|
|
|
{
|
|
|
|
"devDependencies": {
|
|
|
|
"@syndicate-lang/ts-plugin": "file:../..",
|
|
|
|
...
|
|
|
|
},
|
|
|
|
...
|
|
|
|
}
|
|
|
|
|
2021-04-26 13:13:30 +00:00
|
|
|
then `yarn install`.
|
2021-04-26 12:21:48 +00:00
|
|
|
|
|
|
|
## Enabling the plugin in the TypeScript compiler
|
|
|
|
|
|
|
|
`tsconfig.json`:
|
|
|
|
|
|
|
|
{
|
|
|
|
"compilerOptions": {
|
|
|
|
"plugins": [
|
|
|
|
{ "name": "@syndicate-lang/ts-plugin" }
|
|
|
|
],
|
|
|
|
...
|
|
|
|
},
|
|
|
|
...
|
|
|
|
}
|
|
|
|
|
|
|
|
## Getting it to work with specific editors
|
|
|
|
|
|
|
|
### Emacs with Tide
|
|
|
|
|
2021-04-26 14:09:29 +00:00
|
|
|
It should Just Work, if the `node_modules` next to `tsconfig.json` has
|
|
|
|
a `typescript/` subdirectory.
|
|
|
|
|
|
|
|
If no such `typescript/` subdirectory exists in `node_modules`, then
|
|
|
|
because
|
2021-12-03 14:37:41 +00:00
|
|
|
[tsserver loads plugins from relative to tsserver.js rather than tsconfig.json][tsserver-plugin-loading-problem],
|
2021-04-26 14:09:29 +00:00
|
|
|
you will have to tell `tide-mode` about where your project's
|
|
|
|
`tsserver` lives.
|
|
|
|
|
|
|
|
One easy way to do that is to create a symlink in your `node_modules`:
|
|
|
|
|
|
|
|
```shell
|
|
|
|
ln -s /FULL/PATH/TO/YOUR/PROJECT/node_modules/typescript ./node_modules/
|
|
|
|
```
|
|
|
|
|
|
|
|
Another way to do it is to put a `.dir-locals.el` file in your project
|
|
|
|
root, containing
|
|
|
|
|
|
|
|
```elisp
|
|
|
|
((tide-mode
|
|
|
|
. ((tide-tsserver-executable
|
|
|
|
. "/FULL/PATH/TO/YOUR/PROJECT/node_modules/typescript/bin/tsserver"))))
|
|
|
|
```
|
|
|
|
|
|
|
|
I don't know of any way of automatically resolving a relative path
|
|
|
|
specification with respect to the directory containing
|
|
|
|
`.dir-locals.el` without using `eval`, but if you're happy to do so,
|
|
|
|
you can use the following:
|
|
|
|
|
|
|
|
```elisp
|
|
|
|
((typescript-mode
|
|
|
|
. ((eval . (setq tide-tsserver-executable
|
|
|
|
(concat
|
|
|
|
(let ((d (dir-locals-find-file ".")))
|
|
|
|
(if (stringp d) d (car d)))
|
|
|
|
"node_modules/typescript/lib/tsserver.js"))))))
|
|
|
|
```
|
|
|
|
|
|
|
|
If you use the `.dir-locals.el` methods, you may need to run
|
|
|
|
`tide-restart-server` once after opening the first TypeScript file in
|
|
|
|
your project (and then close and re-open that TypeScript file).
|
2021-04-26 12:21:48 +00:00
|
|
|
|
2021-12-03 14:37:41 +00:00
|
|
|
### Emacs with LSP
|
|
|
|
|
|
|
|
LSP will, by default, use its own `tsserver`, no matter what is in the
|
|
|
|
local `node_modules`. Because of the [issue with tsserver's approach
|
|
|
|
to plugin loading][tsserver-plugin-loading-problem], this means that
|
|
|
|
by default it will not load the Syndicate plugin.
|
|
|
|
|
|
|
|
Overriding the `tsserver` location is similar to the way it's done for
|
|
|
|
Tide, but instead of a variable value change, a function has to be
|
|
|
|
called. One good way to do it is to use `.dir-locals.el`, as above:
|
|
|
|
|
|
|
|
```elisp
|
|
|
|
((typescript-mode
|
|
|
|
. ((eval . (progn
|
|
|
|
(require 'lsp-javascript)
|
|
|
|
(lsp-dependency
|
|
|
|
'typescript
|
|
|
|
`(:system ,(concat
|
|
|
|
(let ((d (dir-locals-find-file ".")))
|
|
|
|
(if (stringp d) d (car d)))
|
|
|
|
"node_modules/typescript/lib/tsserver.js"))))))))
|
|
|
|
```
|
|
|
|
|
|
|
|
And, of course, you can make changes for both Tide and LSP at once, if
|
|
|
|
you like:
|
|
|
|
|
|
|
|
```elisp
|
|
|
|
((typescript-mode
|
|
|
|
. ((eval
|
|
|
|
. (progn
|
|
|
|
;; For TIDE:
|
|
|
|
(setq tide-tsserver-executable
|
|
|
|
(concat
|
|
|
|
(let ((d (dir-locals-find-file ".")))
|
|
|
|
(if (stringp d) d (car d)))
|
|
|
|
"node_modules/typescript/lib/tsserver.js"))
|
|
|
|
;; For LSP:
|
|
|
|
(require 'lsp-javascript)
|
|
|
|
(lsp-dependency 'typescript
|
|
|
|
`(:system ,(concat
|
|
|
|
(let ((d (dir-locals-find-file ".")))
|
|
|
|
(if (stringp d) d (car d)))
|
|
|
|
"node_modules/typescript/lib/tsserver.js"))))
|
|
|
|
))))
|
|
|
|
```
|
|
|
|
|
2021-04-26 12:21:48 +00:00
|
|
|
### Visual Studio Code
|
|
|
|
|
2021-04-26 14:09:29 +00:00
|
|
|
After `yarn install`, if you have a `node_modules/typescript`
|
|
|
|
directory, then the following will work. (Otherwise, there may not be
|
|
|
|
an option to select "Use Workspace Version", and you may need to
|
|
|
|
symlink a `typescript` directory into `node_modules` as described for
|
|
|
|
Emacs Tide above.)
|
2021-04-26 12:21:48 +00:00
|
|
|
|
|
|
|
Open VS Code, and select the version of TypeScript contained therein
|
|
|
|
by following instructions
|
|
|
|
[here](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions).
|
|
|
|
|
|
|
|
Specifically, when selecting a TypeScript version,
|
|
|
|
[choose "Use Workspace Version"](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-the-workspace-version-of-typescript).
|
|
|
|
|
|
|
|
For me, the net effect of this is to create a `.vscode/settings.json`
|
|
|
|
file containing:
|
|
|
|
|
|
|
|
{
|
|
|
|
"typescript.tsdk": "node_modules/typescript/lib"
|
|
|
|
}
|
2021-04-26 14:09:29 +00:00
|
|
|
|
|
|
|
## Debugging
|
|
|
|
|
2021-12-03 14:37:41 +00:00
|
|
|
### Emacs with Tide
|
|
|
|
|
2021-04-26 14:09:29 +00:00
|
|
|
You can get verbose logs from Tide's tsserver by setting the Emacs
|
|
|
|
variable `tide-tsserver-process-environment`:
|
|
|
|
|
|
|
|
```elisp
|
|
|
|
(setq tide-tsserver-process-environment '("TSS_LOG=-file /tmp/tss.log"))
|
|
|
|
```
|
|
|
|
|
|
|
|
You can also enable "verbose" output, if that's useful:
|
|
|
|
|
|
|
|
```elisp
|
|
|
|
(setq tide-tsserver-process-environment '("TSS_LOG=-level verbose -file /tmp/tss.log"))
|
|
|
|
```
|
|
|
|
|
|
|
|
Finally, you can set these options in a `.dir-locals.el` file, too:
|
|
|
|
|
|
|
|
```elisp
|
|
|
|
((typescript-mode
|
|
|
|
. ((tide-tsserver-process-environment . ("TSS_LOG=-level verbose -file /tmp/tss.log")))))
|
|
|
|
```
|
2021-12-03 14:37:41 +00:00
|
|
|
|
|
|
|
### Emacs with LSP
|
|
|
|
|
|
|
|
`lsp-mode` helpfully puts logs in a `.log/` directory in your project
|
|
|
|
root! So you can follow `.log/tsserver.log`. There are also `lsp-mode`
|
|
|
|
options for changing the `tsserver` logging level, but I haven't
|
|
|
|
explored them yet.
|
|
|
|
|
|
|
|
[tsserver-plugin-loading-problem]: https://github.com/microsoft/TypeScript/issues/42688
|