Skip to main content

How to make Godot open the VS Code workspace (if the project has one)

Submitted by David Snopek on Wednesday, 2022-05-11 @ 9:22am

Recently, I've started using VS Code as my external text editor with Godot when working on both GDScript and C# projects. The text editor built into Godot is pretty good, and has really great autocomplete and debugging features, but I've really started to miss my Vim keybindings. :-)

I'd already been using VS Code quite a bit for C++ when contributing to Godot itself or when hacking on SG Physics 2D, my custom deterministic physics engine for Godot. And I also use it whenever I work on a C# project in Godot, although, that's not super often, I mostly use GDScript - it's just so quick and easy!

And it turns out that there's great VS Code extensions for both GDScript and C# Godot projects, that give you (almost) all the same autocomplete and debugging functionality as the builtin text editor.

So, anyway, this has been mostly great... except for one really annoying thing:

By default, Godot will open scripts in the last VS Code editor that was focused - not one with the VS Code workspace for this project!

Now, you don't have to make VS Code workspaces for your Godot projects, but I always do. It helps me keep organized on all the different things that I work on.

Finally, I've figured out how to fix this! And this tutorial will explain how you can do it too. :-)

The solution

The solution is quite simple:

Rather than having Godot open VS Code directly, we configure it to open a wrapper script that will check if there is a VS Code workspace for this project, and if so, instruct VS Code to open the requested file in that workspace.

I chose to write my wrapper script in Python, because it's portable to (pretty much) all operating systems, doesn't need any dependencies aside from Python itself, and, well, I like it. :-)

So, first things first, you need to download and install Python 3 on your system. If you use Linux or MacOS, you probably already have it installed.

Then download the script to a file named "vscode-launcher.py" - here's the full source code:

#!/usr/bin/env python3
 
import argparse
import os
import os.path
import shutil
import sys
from glob import glob
 
def find_workspace(project_path):
    workspaces = glob(os.path.join(project_path, "*.code-workspace")) + \
        glob(os.path.join(project_path, ".vscode", "*.code-workspace"))
 
    if len(workspaces) > 1:
        print("Multiple workspaces found (%s). Opening file in the first one: %s" % (workspaces, workspaces[0]), file=sys.stderr)
 
    if len(workspaces) > 0:
        return workspaces[0]
 
    return None
 
def localize_path(path):
    if os.name == "nt":
        return path.replace('/', '\\')
    return path
 
def launch_vscode(code_path, code_args):
    if os.name == 'nt':
        # Under Windows, paths with spaces need to be quoted.
        code_args = [('"%s"' % x if ' ' in x else x) for x in code_args]
 
    os.execv(code_path, code_args)
 
def main():
    parser = argparse.ArgumentParser(description='Launches VS Code, favoring the workspace')
    parser.add_argument('--code', '-c', default='code', help="The path to VS Code")
    parser.add_argument('--project', '-p', help="The path to the project")
    parser.add_argument('file', help="The file to open")
    input = parser.parse_args()
 
    file_path = localize_path(input.file)
 
    code_path = shutil.which(localize_path(input.code))
    if code_path is None:
        print("Unable to find path to %s" % input.code)
        sys.exit(1)
 
    workspace = None
    if input.project:
        project_path = localize_path(input.project)
        workspace = find_workspace(localize_path(project_path))
        if workspace is None:
            workspace = project_path
 
    code_args = [
        os.path.basename(code_path),
        workspace,
        '-g',
        file_path
    ]
 
    launch_vscode(code_path, code_args)
 
if __name__ == '__main__': main()

Next, configure Godot to use it in Editor -> Editor Settings... under the Text Editor -> External section:

Screenshot of the external editor settings in Godot
  • Of course, Use External Editor should be turned on!
  • Exec Path should be "python", "python3" or the full path to the Python executable, depending on how Python is installed on your system.
  • Exec Flags should be the quoted path to the wrapper script (the path on my system is shown below - change it to the path where you downloaded it), plus some additional arguments:
    "/home/dsnopek/bin/vscode-launcher.py" --project "{project}" "{file}:{line}:{col}"
  • If the "code" command isn't on your system PATH, or has a different name, you should set the full path to VS Code by adding something like this to Exec Flags:

     --code "/path/to/vs/code"

The script will look for a *.code-workspace file in top-level directory for your Godot project, OR in the .vscode directory inside of it. If it finds more than one, it'll arbitrarily use the first one. And, if there is no workspace, it'll just open the file normally, without specifying a workspace.

I've tested it on both Linux and Windows. It may work on MacOS if you set the --code argument correctly, but I haven't had a chance to try it myself.

If you have issues, or suggestions for improvements, please let me know! Or, if you use it and it just works great for you, I'd be happy to hear about that as well. :-)

Level:
Beginner
Topic:

Subscribe!

Subscribe to get an email when new articles or videos are posted on SnopekGames.com!

* indicates required

Comments

Add new comment
The content of this field is kept private and will not be shown publicly.

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.