In this blog, I want to document some useful apis, such as chat extension api and workspace api.

Get the current workspace

We can use the workspace API to create folders and files in vscode.

To do that, we need to get the reference to the current workspace.

You can read more about VSCode workspace from this doc.

Basically, when you first open a vscode editor, the workspace is empty:

workspace

You can open a folder to work with:

workspace example

Here’s how I do it:

import * as vscode from "vscode";

// Select all folders in the current workspace
const workspaceFolders = vscode.workspace.workspaceFolders;

// Select the first folder since I only have one root folder in a workspace
// Some developers like to deal with multi-folders in the same workspace
// In those case, logic needs to be adjusted accordingly
const workspacePath = workspaceFolders[0].uri.fsPath;

Create new folders and files

To create new folders and files, I use the workspace fs APIs: fs.createDirectory() and fs.writeFile().

Don’t forget to use the built-in path util function to compute file paths that are os platform agnostic.

import * as path from "path";

// Use the path() function to compute the fs path that is os platform agnostic
const folderName = "my-new-folder";
const newFolderPath = path.join(workspacePath, folderName);

// Use the createDirectory() api to create the directory
await vscode.workspace.fs.createDirectory(vscode.Uri.file(newFolderPath));

// Use the path() function to compute the fs path of the new file
const fileName = "my-new-file";
const newFilePath = path.join(newFolderPath, fileName);

// Use the writeFile() api to create the new file and write empty content to it
await vscode.workspace.fs.writeFile(
  vscode.Uri.file(newFilePath),
  Buffer.from("")
);

List files in a folder

You can use the file tree type to let the users preview individual files.

This is the code snippet from the official doc:

// Create a file tree instance
var tree: vscode.ChatResponseFileTree[] = [
  {
    name: "myworkspace",
    children: [
      { name: "README.md" },
      { name: "app.js" },
      { name: "package.json" },
    ],
  },
];

// Render the file tree control at a base location
stream.filetree(tree, baseLocation);

In my experience though, I don’t want to list out all the files in the current workspace - I just want to list the files that I created.

I ended up doing this:

async function listFilesInFolder(
  stream: vscode.ChatResponseStream,
  workspacePath: string,
  folderName: string
): Promise<void> {
  const folderPath = path.join(workspacePath, folderName);
  const baseUri = vscode.Uri.file(workspacePath);
  const folderUri = vscode.Uri.file(folderPath);
  const files = await vscode.workspace.fs.readDirectory(folderUri);

  // create a filetree instance
  var tree: vscode.ChatResponseFileTree[] = [
    {
      name: folderName,
      children: files.map(([name, _]) => ({ name })),
    },
  ];

  stream.filetree(tree, baseUri);
}

Note that there are two Uri’s:

  • baseUri: this is the uri of the workspace
  • folderUri: this is the uri of the folder that you want to display

When we create the ChatResponseFileTree instance, we need to provide a name property, and that’s the name of the folder (not the full path).

Here’s the output:

file tree

More importantly, those file links are clickable, and the editor will redirect me to the actual file:

actual file