Skip to content

Workspace

Workspace operations including folders, files, configuration, and file watching.

Workspace

Workspace(client: VSCodeClient)

VS Code workspace operations.

Source code in vscode_sockpuppet/workspace.py
def __init__(self, client: VSCodeClient):
    self.client = client
    self._events = WorkspaceEvents(client)
    self._env: Optional[Environment] = None
    # Instantiate Event objects here so they are discoverable from the
    # workspace namespace (e.g. client.workspace.on_did_save_text_document)
    # We store them on private attributes and have the public properties
    # return these instances to maintain the existing property API.
    # Use specific TypedDicts for event payloads to improve type safety.
    self._on_did_open_text_document: Event[TextDocumentDict] = Event(
        self.client, "workspace.onDidOpenTextDocument"
    )
    self._on_did_close_text_document: Event[TextDocumentDict] = Event(
        self.client, "workspace.onDidCloseTextDocument"
    )
    self._on_did_save_text_document: Event[TextDocumentDict] = Event(
        self.client, "workspace.onDidSaveTextDocument"
    )
    self._on_did_change_text_document: Event[DidChangeTextDocumentEvent] = Event(
        self.client, "workspace.onDidChangeTextDocument"
    )
    self._on_did_change_workspace_folders: Event[WorkspaceFoldersChangeEvent] = Event(
        self.client, "workspace.onDidChangeWorkspaceFolders"
    )
    self._on_did_change_configuration: Event[ConfigurationChangeEvent] = Event(
        self.client, "workspace.onDidChangeConfiguration"
    )
    self._on_did_create_files: Event[FileOperationEvent] = Event(
        self.client, "workspace.onDidCreateFiles"
    )
    self._on_did_delete_files: Event[FileOperationEvent] = Event(
        self.client, "workspace.onDidDeleteFiles"
    )
    self._on_did_rename_files: Event[FileOperationEvent] = Event(
        self.client, "workspace.onDidRenameFiles"
    )

env property

env: Environment

Access environment properties and methods.

Returns:

Type Description
Environment

Environment object with properties and methods

Example

print(f"Running in: {client.workspace.env.app_name}") print(f"UI Language: {client.workspace.env.language}") client.workspace.env.open_external("https://example.com")

on_did_open_text_document property

on_did_open_text_document: Event[TextDocumentDict]

Event fired when a text document is opened.

on_did_close_text_document property

on_did_close_text_document: Event[TextDocumentDict]

Event fired when a text document is closed.

on_did_save_text_document property

on_did_save_text_document: Event[TextDocumentDict]

Event fired when a text document is saved.

on_did_change_text_document property

on_did_change_text_document: Event[DidChangeTextDocumentEvent]

Event fired when a text document changes.

on_did_change_workspace_folders property

on_did_change_workspace_folders: Event[WorkspaceFoldersChangeEvent]

Event fired when workspace folders are added or removed.

on_did_change_configuration property

on_did_change_configuration: Event[ConfigurationChangeEvent]

Event fired when the configuration changes.

on_did_create_files property

on_did_create_files: Event[FileOperationEvent]

Event fired when files are created.

on_did_delete_files property

on_did_delete_files: Event[FileOperationEvent]

Event fired when files are deleted.

on_did_rename_files property

on_did_rename_files: Event[FileOperationEvent]

Event fired when files are renamed or moved.

open_text_document

open_text_document(uri: Optional[str] = None, content: Optional[str] = None, language: Optional[str] = None) -> TextDocument

Open a text document.

Parameters:

Name Type Description Default
uri Optional[str]

The URI of the document to open

None
content Optional[str]

Content for an untitled document

None
language Optional[str]

Language identifier for untitled document

None

Returns:

Type Description
TextDocument

TextDocument object

Source code in vscode_sockpuppet/workspace.py
def open_text_document(
    self,
    uri: Optional[str] = None,
    content: Optional[str] = None,
    language: Optional[str] = None,
) -> TextDocument:
    """
    Open a text document.

    Args:
        uri: The URI of the document to open
        content: Content for an untitled document
        language: Language identifier for untitled document

    Returns:
        TextDocument object
    """
    data = self.client._send_request(
        "workspace.openTextDocument",
        {"uri": uri, "content": content, "language": language},
    )
    return TextDocument(self.client, data)

save_all

save_all(include_untitled: bool = False) -> bool

Save all dirty files.

Parameters:

Name Type Description Default
include_untitled bool

Whether to include untitled files

False

Returns:

Type Description
bool

True if all files were saved

Source code in vscode_sockpuppet/workspace.py
def save_all(self, include_untitled: bool = False) -> bool:
    """
    Save all dirty files.

    Args:
        include_untitled: Whether to include untitled files

    Returns:
        True if all files were saved
    """
    return self.client._send_request(
        "workspace.saveAll", {"includeUntitled": include_untitled}
    )

get_workspace_folders

get_workspace_folders() -> list[dict]

Get all workspace folders.

Returns:

Type Description
list[dict]

List of workspace folders (uri, name, index)

Source code in vscode_sockpuppet/workspace.py
def get_workspace_folders(self) -> list[dict]:
    """
    Get all workspace folders.

    Returns:
        List of workspace folders (uri, name, index)
    """
    return self.client._send_request("workspace.workspaceFolders", {})

text_documents

text_documents() -> list[TextDocument]

Get all open text documents.

Returns:

Type Description
list[TextDocument]

List of TextDocument objects

Source code in vscode_sockpuppet/workspace.py
def text_documents(self) -> list[TextDocument]:
    """
    Get all open text documents.

    Returns:
        List of TextDocument objects
    """
    docs_data = self.client._send_request("workspace.textDocuments", {})
    return [TextDocument(self.client, data) for data in docs_data]

get_text_document

get_text_document(uri: str) -> TextDocument

Get a specific open text document by URI.

Parameters:

Name Type Description Default
uri str

The URI of the document

required

Returns:

Type Description
TextDocument

TextDocument object

Source code in vscode_sockpuppet/workspace.py
def get_text_document(self, uri: str) -> TextDocument:
    """
    Get a specific open text document by URI.

    Args:
        uri: The URI of the document

    Returns:
        TextDocument object
    """
    data = self.client._send_request("workspace.getTextDocument", {"uri": uri})
    return TextDocument(self.client, data)

find_files

find_files(include: str, exclude: Optional[str] = None, max_results: Optional[int] = None) -> list[str]

Find files across all workspace folders.

Parameters:

Name Type Description Default
include str

Glob pattern for files to search for (e.g., '/*.py', '/*.{js,ts}')

required
exclude Optional[str]

Glob pattern for files/folders to exclude (e.g., '/node_modules/'). Use None for default excludes (files.exclude setting)

None
max_results Optional[int]

Maximum number of results to return

None

Returns:

Type Description
list[str]

List of file URIs matching the pattern

Example

Find all Python files

files = client.workspace.find_files('*/.py')

Find JavaScript files, excluding node_modules

files = client.workspace.find_files( '/*.js', '/node_modules/**' )

Limit results

files = client.workspace.find_files('*/.ts', max_results=10)

Source code in vscode_sockpuppet/workspace.py
def find_files(
    self,
    include: str,
    exclude: Optional[str] = None,
    max_results: Optional[int] = None,
) -> list[str]:
    """
    Find files across all workspace folders.

    Args:
        include: Glob pattern for files to search for
            (e.g., '**/*.py', '**/*.{js,ts}')
        exclude: Glob pattern for files/folders to exclude
            (e.g., '**/node_modules/**'). Use None for default
            excludes (files.exclude setting)
        max_results: Maximum number of results to return

    Returns:
        List of file URIs matching the pattern

    Example:
        # Find all Python files
        files = client.workspace.find_files('**/*.py')

        # Find JavaScript files, excluding node_modules
        files = client.workspace.find_files(
            '**/*.js',
            '**/node_modules/**'
        )

        # Limit results
        files = client.workspace.find_files('**/*.ts', max_results=10)
    """
    result = self.client._send_request(
        "workspace.findFiles",
        {
            "include": include,
            "exclude": exclude,
            "maxResults": max_results,
        },
    )
    return result["files"]

get_workspace_folder

get_workspace_folder(uri: str) -> Optional[dict]

Get the workspace folder that contains a given URI.

Parameters:

Name Type Description Default
uri str

The URI to find the workspace folder for

required

Returns:

Type Description
Optional[dict]

Workspace folder dict (uri, name, index) or None if not found

Example

folder = client.workspace.get_workspace_folder( 'file:///path/to/file.py' ) if folder: print(f"File is in workspace: {folder['name']}")

Source code in vscode_sockpuppet/workspace.py
def get_workspace_folder(self, uri: str) -> Optional[dict]:
    """
    Get the workspace folder that contains a given URI.

    Args:
        uri: The URI to find the workspace folder for

    Returns:
        Workspace folder dict (uri, name, index) or None if not found

    Example:
        folder = client.workspace.get_workspace_folder(
            'file:///path/to/file.py'
        )
        if folder:
            print(f"File is in workspace: {folder['name']}")
    """
    result = self.client._send_request("workspace.getWorkspaceFolder", {"uri": uri})
    return result["folder"]

as_relative_path

as_relative_path(path_or_uri: str, include_workspace_folder: bool = False) -> str

Convert a path or URI to a workspace-relative path.

Parameters:

Name Type Description Default
path_or_uri str

Absolute path or URI to convert

required
include_workspace_folder bool

Whether to prepend workspace folder name when multiple folders exist

False

Returns:

Type Description
str

Path relative to workspace root, or original input if not

str

in workspace

Example

Convert absolute path

rel_path = client.workspace.as_relative_path( '/Users/name/project/src/main.py' )

Returns: 'src/main.py'

With workspace folder name (when multiple folders)

rel_path = client.workspace.as_relative_path( '/Users/name/project/src/main.py', include_workspace_folder=True )

Returns: 'project-name/src/main.py'

Source code in vscode_sockpuppet/workspace.py
def as_relative_path(self, path_or_uri: str, include_workspace_folder: bool = False) -> str:
    """
    Convert a path or URI to a workspace-relative path.

    Args:
        path_or_uri: Absolute path or URI to convert
        include_workspace_folder: Whether to prepend workspace
            folder name when multiple folders exist

    Returns:
        Path relative to workspace root, or original input if not
        in workspace

    Example:
        # Convert absolute path
        rel_path = client.workspace.as_relative_path(
            '/Users/name/project/src/main.py'
        )
        # Returns: 'src/main.py'

        # With workspace folder name (when multiple folders)
        rel_path = client.workspace.as_relative_path(
            '/Users/name/project/src/main.py',
            include_workspace_folder=True
        )
        # Returns: 'project-name/src/main.py'
    """
    result = self.client._send_request(
        "workspace.asRelativePath",
        {
            "pathOrUri": path_or_uri,
            "includeWorkspaceFolder": include_workspace_folder,
        },
    )
    return result["relativePath"]

apply_edit

apply_edit(edit: WorkspaceEdit) -> dict

Apply a workspace edit.

This allows making changes to multiple files atomically. The edit can include text changes, file creates, file deletes, and file renames.

Parameters:

Name Type Description Default
edit WorkspaceEdit

WorkspaceEdit dict containing: - documentChanges: List of TextDocumentEdit dicts (optional) - createFiles: List of CreateFileOperation dicts (optional) - deleteFiles: List of DeleteFileOperation dicts (optional) - renameFiles: List of RenameFileOperation dicts (optional)

required

Returns:

Type Description
dict

Dict with: - success: True if edit was applied

Example

from vscode_sockpuppet import ( WorkspaceEdit, TextDocumentEdit, TextEdit, Range, Position )

Create a workspace edit with text changes

edit: WorkspaceEdit = { "documentChanges": [ { "uri": "file:///path/to/file.py", "edits": [ { "range": { "start": {"line": 0, "character": 0}, "end": {"line": 0, "character": 0} }, "newText": "# New header comment\n" } ] } ] } result = client.workspace.apply_edit(edit) print(f"Edit applied: {result['success']}")

Create a file and add content

edit: WorkspaceEdit = { "createFiles": [ {"uri": "file:///path/to/new_file.py"} ], "documentChanges": [ { "uri": "file:///path/to/new_file.py", "edits": [ { "range": { "start": {"line": 0, "character": 0}, "end": {"line": 0, "character": 0} }, "newText": "print('Hello, world!')\n" } ] } ] } result = client.workspace.apply_edit(edit)

Source code in vscode_sockpuppet/workspace.py
def apply_edit(self, edit: WorkspaceEdit) -> dict:
    """
    Apply a workspace edit.

    This allows making changes to multiple files atomically. The edit can
    include text changes, file creates, file deletes, and file renames.

    Args:
        edit: WorkspaceEdit dict containing:
            - documentChanges: List of TextDocumentEdit dicts (optional)
            - createFiles: List of CreateFileOperation dicts (optional)
            - deleteFiles: List of DeleteFileOperation dicts (optional)
            - renameFiles: List of RenameFileOperation dicts (optional)

    Returns:
        Dict with:
            - success: True if edit was applied

    Example:
        from vscode_sockpuppet import (
            WorkspaceEdit, TextDocumentEdit, TextEdit, Range, Position
        )

        # Create a workspace edit with text changes
        edit: WorkspaceEdit = {
            "documentChanges": [
                {
                    "uri": "file:///path/to/file.py",
                    "edits": [
                        {
                            "range": {
                                "start": {"line": 0, "character": 0},
                                "end": {"line": 0, "character": 0}
                            },
                            "newText": "# New header comment\\n"
                        }
                    ]
                }
            ]
        }
        result = client.workspace.apply_edit(edit)
        print(f"Edit applied: {result['success']}")

        # Create a file and add content
        edit: WorkspaceEdit = {
            "createFiles": [
                {"uri": "file:///path/to/new_file.py"}
            ],
            "documentChanges": [
                {
                    "uri": "file:///path/to/new_file.py",
                    "edits": [
                        {
                            "range": {
                                "start": {"line": 0, "character": 0},
                                "end": {"line": 0, "character": 0}
                            },
                            "newText": "print('Hello, world!')\\n"
                        }
                    ]
                }
            ]
        }
        result = client.workspace.apply_edit(edit)
    """
    # TypedDict is treated as dict at runtime
    return self.client._send_request(
        "workspace.applyEdit",
        dict(edit),  # type: ignore[arg-type]
    )

get_configuration

get_configuration(section: Optional[str] = None, scope: Optional[str] = None) -> WorkspaceConfiguration

Get a workspace configuration object.

Parameters:

Name Type Description Default
section Optional[str]

Configuration section (e.g., 'editor', 'python.linting')

None
scope Optional[str]

Resource URI or language ID for scoped configuration

None

Returns:

Type Description
WorkspaceConfiguration

WorkspaceConfiguration object

Example

Get editor configuration

config = client.workspace.get_configuration('editor') font_size = config.get('fontSize', 14)

Update a setting

config.update('fontSize', 16, ConfigurationTarget.GLOBAL)

Get all configuration

config = client.workspace.get_configuration() value = config.get('editor.fontSize')

Source code in vscode_sockpuppet/workspace.py
def get_configuration(
    self, section: Optional[str] = None, scope: Optional[str] = None
) -> WorkspaceConfiguration:
    """
    Get a workspace configuration object.

    Args:
        section: Configuration section (e.g., 'editor', 'python.linting')
        scope: Resource URI or language ID for scoped configuration

    Returns:
        WorkspaceConfiguration object

    Example:
        # Get editor configuration
        config = client.workspace.get_configuration('editor')
        font_size = config.get('fontSize', 14)

        # Update a setting
        config.update('fontSize', 16, ConfigurationTarget.GLOBAL)

        # Get all configuration
        config = client.workspace.get_configuration()
        value = config.get('editor.fontSize')
    """
    return WorkspaceConfiguration(self.client, section, scope)

create_file_system_watcher

create_file_system_watcher(glob_pattern: str, ignore_create_events: bool = False, ignore_change_events: bool = False, ignore_delete_events: bool = False) -> FileSystemWatcher

Create a file system watcher for the given glob pattern.

Parameters:

Name Type Description Default
glob_pattern str

Glob pattern to watch (e.g., '/*.py', '/*.{js,ts}')

required
ignore_create_events bool

Don't fire events when files are created

False
ignore_change_events bool

Don't fire events when files are changed

False
ignore_delete_events bool

Don't fire events when files are deleted

False

Returns:

Type Description
FileSystemWatcher

FileSystemWatcher instance

Example

Watch all Python files in workspace

watcher = workspace.create_file_system_watcher("*/.py")

def on_python_file_created(uri): print(f"New Python file: {uri}")

def on_python_file_changed(uri): print(f"Python file modified: {uri}")

Subscribe to events

dispose1 = watcher.on_did_create(on_python_file_created) dispose2 = watcher.on_did_change(on_python_file_changed)

Later, stop watching

watcher.dispose()

Or use as context manager

with workspace.create_file_system_watcher("*/.js") as watcher: watcher.on_did_create(lambda uri: print(f"Created: {uri}")) # ... do work ...

Automatically disposed when exiting context

Source code in vscode_sockpuppet/workspace.py
def create_file_system_watcher(
    self,
    glob_pattern: str,
    ignore_create_events: bool = False,
    ignore_change_events: bool = False,
    ignore_delete_events: bool = False,
) -> FileSystemWatcher:
    """
    Create a file system watcher for the given glob pattern.

    Args:
        glob_pattern: Glob pattern to watch
            (e.g., '**/*.py', '**/*.{js,ts}')
        ignore_create_events: Don't fire events when files are created
        ignore_change_events: Don't fire events when files are changed
        ignore_delete_events: Don't fire events when files are deleted

    Returns:
        FileSystemWatcher instance

    Example:
        # Watch all Python files in workspace
        watcher = workspace.create_file_system_watcher("**/*.py")

        def on_python_file_created(uri):
            print(f"New Python file: {uri}")

        def on_python_file_changed(uri):
            print(f"Python file modified: {uri}")

        # Subscribe to events
        dispose1 = watcher.on_did_create(on_python_file_created)
        dispose2 = watcher.on_did_change(on_python_file_changed)

        # Later, stop watching
        watcher.dispose()

        # Or use as context manager
        with workspace.create_file_system_watcher("**/*.js") as watcher:
            watcher.on_did_create(lambda uri: print(f"Created: {uri}"))
            # ... do work ...
        # Automatically disposed when exiting context
    """
    from .filewatcher import FileSystemWatcher

    result = self.client._send_request(
        "workspace.createFileSystemWatcher",
        {
            "globPattern": glob_pattern,
            "ignoreCreateEvents": ignore_create_events,
            "ignoreChangeEvents": ignore_change_events,
            "ignoreDeleteEvents": ignore_delete_events,
        },
    )

    return FileSystemWatcher(
        self.client,
        result["watcherId"],
        glob_pattern,
        ignore_create_events,
        ignore_change_events,
        ignore_delete_events,
    )

Environment

Environment

Environment(client: VSCodeClient)

VS Code environment properties and methods.

Source code in vscode_sockpuppet/workspace.py
def __init__(self, client: VSCodeClient):
    self.client = client
    self._cached_properties = {}

app_name property

app_name: str

The application name of the editor, like 'VS Code'.

Returns:

Type Description
str

Application name

Example

print(f"Running in: {client.workspace.env.app_name}")

app_root property

app_root: str

The application root folder from which the editor is running.

Returns:

Type Description
str

Application root path (empty string if not applicable)

Example

print(f"App root: {client.workspace.env.app_root}")

language property

language: str

The UI language of VS Code.

Returns:

Type Description
str

Language identifier (e.g., 'en', 'de', 'zh-cn')

Example

if client.workspace.env.language == 'en': print("English UI")

machine_id property

machine_id: str

A unique identifier for the machine.

Returns:

Type Description
str

Machine identifier (anonymized)

Example

print(f"Machine ID: {client.workspace.env.machine_id}")

session_id property

session_id: str

A unique identifier for the current session.

Returns:

Type Description
str

Session identifier

Example

print(f"Session: {client.workspace.env.session_id}")

uri_scheme property

uri_scheme: str

The custom URI scheme the editor registers in the OS.

Returns:

Type Description
str

URI scheme (typically 'vscode' or 'vscode-insiders')

Example

print(f"URI scheme: {client.workspace.env.uri_scheme}")

shell property

shell: str

The detected default shell for the extension host.

Returns:

Type Description
str

Path to the default shell

Example

print(f"Default shell: {client.workspace.env.shell}")

ui_kind property

ui_kind: int

The UI kind property indicates from which UI extensions are accessed.

Returns:

Type Description
int

UI kind (1 = Desktop, 2 = Web)

Example

if client.workspace.env.ui_kind == 1: print("Running in desktop VS Code") else: print("Running in web VS Code")

write_clipboard

write_clipboard(text: str) -> None

Write text to clipboard.

Parameters:

Name Type Description Default
text str

The text to write

required
Example

client.workspace.env.write_clipboard("Hello, clipboard!")

Source code in vscode_sockpuppet/workspace.py
def write_clipboard(self, text: str) -> None:
    """
    Write text to clipboard.

    Args:
        text: The text to write

    Example:
        client.workspace.env.write_clipboard("Hello, clipboard!")
    """
    self.client._send_request("env.clipboard.writeText", {"text": text})

read_clipboard

read_clipboard() -> str

Read text from clipboard.

Returns:

Type Description
str

The clipboard text

Example

text = client.workspace.env.read_clipboard() print(f"Clipboard: {text}")

Source code in vscode_sockpuppet/workspace.py
def read_clipboard(self) -> str:
    """
    Read text from clipboard.

    Returns:
        The clipboard text

    Example:
        text = client.workspace.env.read_clipboard()
        print(f"Clipboard: {text}")
    """
    return self.client._send_request("env.clipboard.readText")

open_external

open_external(uri: str) -> bool

Open an external URI in the default application.

Parameters:

Name Type Description Default
uri str

The URI to open (http, https, mailto, etc.)

required

Returns:

Type Description
bool

True if successful

Example

Open URL in browser

client.workspace.env.open_external("https://code.visualstudio.com")

Open email client

client.workspace.env.open_external("mailto:user@example.com")

Source code in vscode_sockpuppet/workspace.py
def open_external(self, uri: str) -> bool:
    """
    Open an external URI in the default application.

    Args:
        uri: The URI to open (http, https, mailto, etc.)

    Returns:
        True if successful

    Example:
        # Open URL in browser
        client.workspace.env.open_external("https://code.visualstudio.com")

        # Open email client
        client.workspace.env.open_external("mailto:user@example.com")
    """
    return self.client._send_request("env.openExternal", {"uri": uri})

as_external_uri

as_external_uri(uri: str) -> str

Convert a URI to an external URI that can be opened outside VS Code.

This resolves the authority part of a URI using VS Code's port forwarding and tunneling features. For example, when running in a remote SSH session, this converts localhost URIs to publicly accessible URIs.

Parameters:

Name Type Description Default
uri str

The URI to convert (typically a localhost or internal URI)

required

Returns:

Type Description
str

The external URI as a string

Example

Convert localhost URI when running remotely

external = client.workspace.env.as_external_uri( "http://localhost:3000" ) print(f"Public URL: {external}")

Convert workspace file URI

file_uri = "file:///workspace/file.txt" external = client.workspace.env.as_external_uri(file_uri)

Source code in vscode_sockpuppet/workspace.py
def as_external_uri(self, uri: str) -> str:
    """
    Convert a URI to an external URI that can be opened outside VS Code.

    This resolves the authority part of a URI using VS Code's port
    forwarding and tunneling features. For example, when running in a
    remote SSH session, this converts localhost URIs to publicly
    accessible URIs.

    Args:
        uri: The URI to convert (typically a localhost or internal URI)

    Returns:
        The external URI as a string

    Example:
        # Convert localhost URI when running remotely
        external = client.workspace.env.as_external_uri(
            "http://localhost:3000"
        )
        print(f"Public URL: {external}")

        # Convert workspace file URI
        file_uri = "file:///workspace/file.txt"
        external = client.workspace.env.as_external_uri(file_uri)
    """
    return self.client._send_request("env.asExternalUri", {"uri": uri})