terrastruct / d2-vscode

VSCode extension for D2 files.
https://d2lang.com
BSD 3-Clause "New" or "Revised" License
240 stars 11 forks source link

Language server #117

Open BarryNolte opened 1 year ago

BarryNolte commented 1 year ago

New items in the PR

Resolves #51 Must pull https://github.com/terrastruct/d2/pull/1534 for this to work.

Project Layout

To facilitate a better edit/build/debug process, the extension was moved to a 'client' directory, the language server to a 'server' directory. Note: This may break the nightly build process and will need to be adjusted.

Language Server

  1. Identifies links and imports so the editor can mark them as such. Ctrl+click on the links will attempt to launch what the link points to.
  2. 'Find All References' will show a list (as presented by vscode) of all references of the given node.
  3. 'Goto Definition' will do one of two things. If there are multiple definitions, it will show a list similar to 'Find All References'. If there is only one option for the definition, then the cursor will jump to that option.
  4. 'Rename...' will rename a node. If there are multiple nodes (a.style... / a.shape... / a.label... / etc.), then a rename will change all locations that contain that node.
  5. Auto Completion:

    a) Typing a '@' will show a list of d2 files that are contained in the d2 documents current folder and all child folders from there.

    b) Typing a '.' that is along a valid path, will bring up the proper list for that position in the path.

    c) Typing a ':' will bring up a list of possible values for that position in the current path. If there is no list, in the case of a free-form field such as 'label', then no list is shown.

    d) The 'Tab' key will commit the auto completion.

  6. When a preview is not present, then there is no error messages generated, the language server will show any errors that are created during the AST phase of d2 compilation.
alixander commented 1 year ago

(apologies for the delay on this, team is super busy with some d2 studio stuff w/ deadlines, very looking forward to digging into this and trying it soon)

gavin-ts commented 11 months ago

go to definition worked for objects at the outermost level but doesn't seem to work for nested objects

Screenshot 2023-12-15 at 8 33 12 PM
gavin-ts commented 11 months ago

:100:

Screenshot 2023-12-15 at 8 40 42 PM
gavin-ts commented 11 months ago

I wonder if this can check for any d2 files inside the workspace folder rather than just the current .d2 file's folder? currently it doesn't seem to be able to lookup anything ../etc even if it is open within the workspace

gavin-ts commented 11 months ago

@ and . work great but I couldn't get : to work as described

. 💯

Screenshot 2023-12-15 at 8 44 52 PM

:

Screenshot 2023-12-15 at 8 44 42 PM

It would be nice to have children appear here too but it could be a separate issue:

Screenshot 2023-12-15 at 8 46 41 PM
BarryNolte commented 11 months ago

The exception that was firing on the JSON parse was due to the refactoring of the D2 executable code. When a parse happens, it should be allowed to, "fail", so that the ast and errors can be picked up and transmitted to the extension. The parser being fault tolerant allows for incomplete d2 code to be parsed and that gives enough information for autocomplete to work. The code was just returning because there was an error, (which happens about every fifth character you type as you create a diagram), and that exception was that the ast was empty. I've added a little more error checking around that scenario and have a PR ready for the D2 code tree.

Update: PR: https://github.com/terrastruct/d2/pull/1782

BarryNolte commented 11 months ago

Workspaces are now honored for d2 file search. Nested objects work correctly. I took out my, 'I know better', code from the ':' path for autocomplete. Now we should be at the point of, this works, but what else would be cool to add?

MarvinJWendt commented 11 months ago

I just want to say I already love this PR so much. This is literally the only feature that I miss in D2 (and my most important selling point). Thank you, @BarryNolte, for working on this.

Now we should be at the point of, this works, but what else would be cool to add?

What do you (all) think about releasing a beta of the LSP + VSC Extension? Things that are "cool to add" are probably worth looking into, when the LSP proved to be stable enough. Most cool things will show when the community uses it and finds special use cases. This would probably also decrease the time needed, as features could be prioritized by demand.

(Just my 2 cents) Cheers

BarryNolte commented 10 months ago

I just want to say I already love this PR so much. This is literally the only feature that I miss in D2 (and my most important selling point). Thank you, @BarryNolte, for working on this.

Thanks @MarvinJWendt! This has been fun to work on. It's a far cry from my previous work on performance tools and debuggers. This should be available once the team at Terrastruct accepts the PR.

BarryNolte commented 9 months ago

@alixander and @gavin-ts Ping.

BarryNolte commented 9 months ago

@BarryNolte I'm running into this error when I try to install. Any ideas?

Error at the end: ERROR Extension entrypoint(s) missing.

I moved a ton of files around to separate the client from the server, so this could be leftovers from the previous directory structure. I'd delete the whole directory, re-clone the repository and build from there. As I moved things around, I ran into numerous issues just like this that were fixed by deep cleaning the node modules directories and deleting ./dist/... directories.

alixander commented 9 months ago

it must be that it's building as .ts and vscode is looking for .js?

BarryNolte commented 9 months ago

I checked out d2:master and it appears to be behind my d2:LSP-Fixes branch. If you can checkout upstream/master, it should have my changes and the error spew will go away. All new features are described in the PR Entry #117

BarryNolte commented 9 months ago

When I started this, I was passing the IR to the server, but then I figured out how to synthesize what I needed from the AST. However, you found a limit that I should go back to using the IR for references and nested objects. I'll work on that.

The autocomplete of ':' vs. ': ', I also thought was a good idea, and had it implemented. It didn't quite feel right, at least to me. So I tried a bunch of different languages, and every one of them auto completes on the token delimiter ('.', ':', etc). The vscode autocomplete system is also geared toward this implementation. But, since I know I want a space in there, when you pick an item to autocompletion, it will put the space in.

alixander commented 8 months ago

Can we split out the smaller ones from this large PR and have this just be focused on the language server? @BarryNolte