Understanding Inkdown’s workspace concept, file management, tabs, and bookmarks
The Workspace in Inkdown represents your collection of markdown files and folders. It provides a unified API for file operations, manages open tabs, and maintains bookmarks for quick access to important files.
Inkdown’s workspace is designed to be platform-agnostic, working seamlessly across Desktop (with real file systems), Web (with virtual file systems), and Mobile platforms.
A workspace is a single directory containing your markdown files. Think of it as your “vault” of notes.
import type { TFile } from '@inkdown/core';// Get all markdown files in the workspaceconst files: TFile[] = await app.workspace.getMarkdownFiles();// Get all files (including non-markdown)const allFiles = await app.workspace.getAllFiles();// Get a specific file by pathconst file = app.workspace.getAbstractFileByPath('notes/example.md');// Get workspace root pathconst root = app.workspace.getRoot();
// Create a new tabconst tab = app.tabManager.createTab({ filePath: 'notes/example.md', title: 'Example Note', isPinned: false});// Get all tabsconst tabs = app.tabManager.getTabs();// Get active tabconst activeTab = app.tabManager.getActiveTab();// Switch to a tabapp.tabManager.setActiveTab(tab.id);// Close a tabapp.tabManager.closeTab(tab.id);// Pin/unpin a tabapp.tabManager.pinTab(tab.id, true);
// Create an untitled/empty tabconst emptyTab = app.tabManager.createTab({ filePath: '', title: 'Untitled', isPinned: false});// Check if a tab is emptyif (tab.filePath === '') { console.log('This is an empty tab');}
Empty tabs are not persisted to the configuration. They’re automatically recreated if no tabs exist on startup.
// Create a bookmark groupconst groupId = app.bookmarkManager.createGroup({ name: 'Work Notes', icon: 'briefcase', color: '#4CAF50'});// Add a bookmark to a groupapp.bookmarkManager.addBookmark(groupId, { filePath: 'work/project-plan.md', title: 'Project Plan', type: 'file'});// Get all bookmark groupsconst groups = app.bookmarkManager.getGroups();// Get bookmarks in a groupconst bookmarks = app.bookmarkManager.getBookmarks(groupId);// Remove a bookmarkapp.bookmarkManager.removeBookmark(groupId, bookmarkId);// Delete a group (and all its bookmarks)app.bookmarkManager.deleteGroup(groupId);
Handle errors gracefully (file may not exist, permissions, etc.)
Listen to file events to keep UI in sync
Use debouncing for operations triggered by file changes
try { const content = await app.workspace.read(filePath); // Process content} catch (error) { console.error('Failed to read file:', error); app.showNotice('Could not read file');}
Tab Management
Close unused tabs to free memory
Pin important tabs to prevent accidental closure
Handle empty tabs gracefully
Save tab state when appropriate
// Close all unpinned tabsconst tabs = app.tabManager.getTabs();for (const tab of tabs) { if (!tab.isPinned && !tab.isDirty) { app.tabManager.closeTab(tab.id); }}
Performance
Use metadata cache instead of parsing files repeatedly
Batch file operations when possible
Debounce search queries
Lazy-load file lists for large workspaces
// Use metadata cache for quick accessconst metadata = app.metadataCache.getFileCache(filePath);const tags = metadata?.tags || [];// Instead of parsing the file again// const content = await app.workspace.read(filePath);// const tags = extractTags(content); // Slow!