Introducing Swift for Visual Studio Code

One of the issues with editing scripts is that they tend to depend on a lot of shell-specific context, such as the current working directory, environment variables, or command-line arguments.

That makes it awkward to have a one-click "Build and Run" action, especially in a graphical editor which is detached from a shell. It just doesn't have that context.

VSCode does have an integrated terminal, though. So if we wanted to offer a better editing experience for scripts, we need to find a way to invoke swift scripts in that terminal (or equivalent context), while still providing things like breakpoints. I could imagine 2 things in particular:

  1. Run & Debug in the context of a given terminal.

    A one-click action to execute the script in the integrated terminal, but with full debugging support. So in the following picture, you can see that the working directory in the script is the same as calling pwd because we launch it manually via the integrated terminal. It's important that the script gets that context, but by launching things in this way, no debugger is attached:

    (Note: VSCode does have a built-in "Run Active File in Active Terminal" command. Can we hook in to that and attach the debugger?)

  2. Some kind of terminal command which runs the current file with some arguments.

    If you need to do something more complex (perhaps passing in some command-line flags), you might still have to launch the script via the integrated terminal rather than a one-click action/keyboard shortcut. Again, we'd want a debugger attached so users could set breakpoints:

    user@this-pc tmp % code-run-swift -arg1 -arg2=foo ../arg3
                       ^^^^^^^^^^^^^^
    some helper we inject ^
    

I don't know if this is possible, but that's what I imagine the ideal script editor workflow would look like. Stuff like swift-sh or script-packages would be cool, but we need to start with just the ability to run and debug a script in the context where it is used.

1 Like

I made a PR to fix the syntax coloring in Visual Studio Code. It has the same syntax coloring backend as Google Colab for languages besides Python (Monaco): [Feature Request] Update Swift language specification to version 5.5 · Issue #2854 · microsoft/monaco-editor · GitHub

5 Likes

How is this related to VS Code? The syntax highlighting for VS Code is here: vscode/swift.tmLanguage.json at main · microsoft/vscode · GitHub

It's auto generated from the TextMate grammar, which unfortunately makes it hard to maintain.

1 Like

v0.1.1 of the VS Code Swift extension has been released.

This includes a small fix to the CodeLLDB setup while running in a remote container. Previously in many situations it was getting this wrong. It should be correct now.

2 Likes

Maybe it isn’t. I just read online somewhere that VS Code depends on Monaco. Or, the file you showed me could be codegenned from the file I corrected in Monaco.

I took a quick look at what's possible for scripts, and it seems like Microsoft plans to improve terminal/shell support relatively soon:

This additional information enables a lot of possibilities:
[...]

  • Potentially exposing a run command extension API which runs within an existing shell session and returns the exit code, additional state could also be exposed via Terminal.state.
  • Overall better awareness of what's going on inside the terminal, currently it's mostly a black box and the main ways of detecting things is via scanning all text (eg. tasks) or by listening for certain key presses (eg. current command tracking).

So perhaps great script support isn't even possible right now in VSCode ("currently it's mostly a black box"), but it would be good to keep an eye on how things develop. When a user asks:

I think this is what they're asking for - the ability to run a script in the editor's built-in terminal, and attach a debugger to it for breakpoints etc. Does anybody know of other extensions which can do that today?

Does that actually work like a script you'd launch from the terminal (via the #! shebang line), or is it just running a Python file? For example, does it inherit all environment variables and the current working directory of the active terminal?

Works like a charm! You people are amazing, thank you so much for the effort put into making this happen :heart:

2 Likes

Awesome job so far! I gave it a try and whoa it caught me unprepared. I've been using Xcode exclusively since v3. And god I loved it back then! But past few years not that much. I shall move to server-side Swift and try other IDEs...

does this use sourcekitd for the syntax highlighting? regex-based grammars do not work well when you always write swift with the type annotations (as i do)…

From the README:

Swift support uses SourceKit LSP for the language server to power code completion and LLDB to enable debugging.

SourceKit LSP has supported syntax highlighting for since August.

sourcekitd is not the same thing as sourcekit-lsp never mind, i just tested the new plugin and it looks like it does use sourcekitd! great!

Thanks. I have used VSC for quite a while using thethe maintained Swift Development Environment.

I had to switch back to Xcode from time to time to manage documentation. I have made an attempt now to add this functionality to VSC. So if you want to give a try look at this new extensions which mimics the Add Documentation from Xcode.

This is my first extension, so it may have rough edges. Please let me know if you run into issues using this.

Swift Add Documentation

1 Like

This looks really cool.

There is an issue already for doing something similar in the swift extension as having to remember the structure of comment blocks while using vscode is a pain. I was looking at the vscode.CompletionItem system to implement this, to give a similar experience to the rest of VSCode.

For example when I type /** in javascript I get a basic javascript comment header /** */. If I press return it supplies a full function comment header with parameter names etc. The code for the javascript version looks like it uses the language server to get the parameter names which is an interesting idea.

If you are interested in contributing that'd be great.

As I wrote this was my first extension and supporting something like the language server was a bridge too far for me at this point. My goal was to have something working quickly. Since everything was new I cut some corners.

If you can give me a pointer to an example that is interacting with the swift language server I may look into it. Once I have it working we could migrate it to the main package and get rid of this package all together. In the mean time this works for me :slight_smile:

I'm not that far ahead of you :sweat_smile:. Interacting with the language server is a fairly complex affair. There is virtually zero documentation on how to do it via the vscode language apis. If I get the time I'll see if I can work out what is needed and add more details into the issue.

In the meantime we still have a solution

1 Like

My PR to microsoft/monaco-editor has been (almost) approved, if that helps any.

Thanks @0xTim for pulling me in, and sorry for the delay.

We’re working towards adding such feature officially in Swift, and the prototype documentation (my GSoC write-ups) is live in GitHub - stevapple/gsoc-2021-writeups: Write-ups of GSoC 2021 project "SwiftPM support for Swift scripts".

Currently the prototype has little IDE support, which is the main direction I’m evolving towards. It should be officially pitched as SE proposal once it has gain better frontend integration. I’ve noted the request and will see if we can provide it as an experimental feature of the plugin after it is available for testing.

Personally I think it’s unwise to add any third-party integration into this plugin. A separate one should be a better choice.

By the way, for those waiting for test support to come to this plugin, there's this cool extension you can use in the mean time. I'm mentioning it because it may be of interest to those using VSCode, and because it may also help the developers to check out how this plugin does it; apparently it uses the "Test Explorer UI" plugin (which predates VSCode's official API), but migration to the official API is apparently straightforward.

2 Likes

Hi Adam,

I looked at the /** functionality and it turns out that this is part of the language configuration and this is supplied by the auto closing pairs mechanism. So similar to when you type { you also get `}'.

I can use this to for example use tab instead, so //<tab> would trigger the documentation template and when used inside a block would open up a new documentation line. Any thoughts?