The Filesystem API provides methods for interacting with the file system, including reading and writing files, checking file existence, and working with directories.
File Operations
readFile
Read entire file contents as UTF-8 string.
readFile(path: string): Promise<string>
File path (absolute or relative to cwd)
File contents as UTF-8 string
Throws if file doesn’t exist, isn’t readable, or isn’t valid UTF-8. For binary files, this will fail. For large files, consider memory usage.
Example:
try {
const content = await editor.readFile("/path/to/file.txt");
editor.debug(`File content: ${content}`);
} catch (error) {
editor.error(`Failed to read file: ${error}`);
}
writeFile
Write string content to a NEW file (fails if file exists).
writeFile(path: string, content: string): Promise<void>
Destination path (absolute or relative to cwd)
Creates a new file with the given content. Fails if the file already exists to prevent plugins from accidentally overwriting user data.
Example:
try {
await editor.writeFile("/path/to/new-file.txt", "Hello, world!");
editor.setStatus("File created successfully");
} catch (error) {
editor.error(`Failed to create file: ${error}`);
}
fileExists
Check if a path exists (file, directory, or symlink).
fileExists(path: string): boolean
Path to check (absolute or relative to cwd)
true if path exists, false otherwise
Does not follow symlinks; returns true for broken symlinks. Use fileStat for more detailed information.
Example:
if (editor.fileExists("/path/to/file.txt")) {
editor.info("File exists");
} else {
editor.info("File does not exist");
}
fileStat
Get metadata about a file or directory.
fileStat(path: string): FileStat
Path to stat (absolute or relative to cwd)
FileStat Type:
interface FileStat {
exists: boolean; // Whether the path exists
is_file: boolean; // Whether the path is a file
is_dir: boolean; // Whether the path is a directory
size: number; // File size in bytes
readonly: boolean; // Whether the file is read-only
}
Follows symlinks. Returns exists=false for non-existent paths rather than throwing. Size is in bytes; directories may report 0.
Example:
const stat = editor.fileStat("/path/to/file.txt");
if (stat.exists) {
if (stat.is_file) {
editor.info(`File size: ${stat.size} bytes`);
} else if (stat.is_dir) {
editor.info("Path is a directory");
}
if (stat.readonly) {
editor.warn("File is read-only");
}
}
Directory Operations
readDir
List directory contents.
readDir(path: string): DirEntry[]
Directory path (absolute or relative to cwd)
Array of directory entries
DirEntry Type:
interface DirEntry {
name: string; // Entry name only (not full path)
is_file: boolean; // True if entry is a regular file
is_dir: boolean; // True if entry is a directory
}
Returns unsorted entries with type info. Entry names are relative to the directory (use pathJoin to construct full paths). Throws on permission errors or if path is not a directory.
Example:
try {
const entries = editor.readDir("/home/user");
for (const entry of entries) {
const fullPath = editor.pathJoin(["/home/user", entry.name]);
if (entry.is_file) {
editor.debug(`File: ${fullPath}`);
} else if (entry.is_dir) {
editor.debug(`Directory: ${fullPath}`);
}
}
} catch (error) {
editor.error(`Failed to read directory: ${error}`);
}
Path Operations
pathJoin
Join path segments using the OS path separator.
pathJoin(parts: string[]): string
Handles empty segments and normalizes separators. If a segment is absolute, previous segments are discarded.
Example:
const path1 = editor.pathJoin(["/home", "user", "file.txt"]);
// Result: "/home/user/file.txt"
const path2 = editor.pathJoin(["relative", "/absolute"]);
// Result: "/absolute"
pathDirname
Get the parent directory of a path.
pathDirname(path: string): string
Parent directory path, or empty string for root paths
Does not resolve symlinks or check existence.
Example:
const dir1 = editor.pathDirname("/home/user/file.txt");
// Result: "/home/user"
const dir2 = editor.pathDirname("/");
// Result: ""
pathBasename
Get the final component of a path.
pathBasename(path: string): string
Final path component, or empty string for root paths
Does not strip file extension; use pathExtname for that.
Example:
const base1 = editor.pathBasename("/home/user/file.txt");
// Result: "file.txt"
const base2 = editor.pathBasename("/home/user/");
// Result: "user"
pathExtname
Get the file extension including the dot.
pathExtname(path: string): string
File extension with dot, or empty string if no extension
Only returns the last extension for files like “archive.tar.gz” (returns “.gz”).
Example:
const ext1 = editor.pathExtname("file.txt");
// Result: ".txt"
const ext2 = editor.pathExtname("archive.tar.gz");
// Result: ".gz"
const ext3 = editor.pathExtname("Makefile");
// Result: ""
pathIsAbsolute
Check if a path is absolute.
pathIsAbsolute(path: string): boolean
true if path is absolute, false otherwise
On Unix: starts with ”/”. On Windows: starts with drive letter or UNC path.
Example:
const abs1 = editor.pathIsAbsolute("/home/user/file.txt");
// Result: true
const abs2 = editor.pathIsAbsolute("relative/path.txt");
// Result: false
Environment Operations
getCwd
Get the editor’s current working directory.
Absolute path to the editor’s working directory set at startup
Use as base for resolving relative paths.
Example:
const cwd = editor.getCwd();
const absolutePath = editor.pathJoin([cwd, "relative/file.txt"]);
getEnv
Get an environment variable.
getEnv(name: string): string
Name of environment variable
Environment variable value, or empty string if not set
Example:
const home = editor.getEnv("HOME");
const path = editor.getEnv("PATH");
editor.debug(`Home: ${home}`);
Examples
Read config file
const configDir = editor.getConfigDir();
const configPath = editor.pathJoin([configDir, "my-plugin.json"]);
if (editor.fileExists(configPath)) {
try {
const content = await editor.readFile(configPath);
const config = JSON.parse(content);
editor.debug(`Loaded config: ${JSON.stringify(config)}`);
} catch (error) {
editor.error(`Failed to load config: ${error}`);
}
} else {
editor.info("Config file not found, using defaults");
}
List files in directory
const cwd = editor.getCwd();
const entries = editor.readDir(cwd);
const files = entries
.filter(e => e.is_file)
.map(e => e.name);
const dirs = entries
.filter(e => e.is_dir)
.map(e => e.name);
editor.info(`Files: ${files.length}, Directories: ${dirs.length}`);
Find files recursively
function findFiles(dir: string, pattern: RegExp): string[] {
const results: string[] = [];
try {
const entries = editor.readDir(dir);
for (const entry of entries) {
const fullPath = editor.pathJoin([dir, entry.name]);
if (entry.is_file && pattern.test(entry.name)) {
results.push(fullPath);
} else if (entry.is_dir) {
results.push(...findFiles(fullPath, pattern));
}
}
} catch (error) {
editor.warn(`Failed to read ${dir}: ${error}`);
}
return results;
}
// Find all TypeScript files
const tsFiles = findFiles(editor.getCwd(), /\.ts$/);
editor.info(`Found ${tsFiles.length} TypeScript files`);