Plugin Development
Build powerful plugins for Vimcraft using TypeScript or JavaScript with hot reload and access to the complete Neovim-compatible API.
Why Build Plugins for Vimcraft?
- TypeScript-First - Write plugins in TypeScript with full IntelliSense and type checking.
- Instant Hot Reload - Save your plugin file and see changes instantly. No restart, no rebuild required.
- Neovim Compatible - Use the familiar Neovim API. Your knowledge transfers directly.
- Cross-Plugin Communication - Import and share functionality between plugins with
require().
Getting Started
TypeScript Plugin (Recommended)
// ~/.config/vimcraft/plugins/hello.ts // Plugin initialization console.log('Hello from my plugin!'); // Register a command vim.api.createUserCmd('SayHello', () => { console.log('Hello, Vimcraft!'); }, { desc: 'Say hello' }); // Add a keybinding vim.keymap.set('n', '<leader>h', () => { vim.cmd('SayHello'); }, { desc: 'Say hello' });
JavaScript Plugin
// ~/.config/vimcraft/plugins/hello.js console.log('Hello from my plugin!'); vim.api.createUserCmd('SayHello', () => { console.log('Hello, Vimcraft!'); }, { desc: 'Say hello' }); vim.keymap.set('n', '<leader>h', () => { vim.cmd('SayHello'); });
Plugins are loaded from ~/.config/vimcraft/plugins/. Create a .ts or .js file in this directory and it will be automatically loaded on startup.
Plugin Structure
Plugins run in a global scope with the vim object automatically available:
// ~/.config/vimcraft/plugins/my-plugin.ts // State management let myPluginState = { enabled: true, count: 0, }; // Listen to events via autocommands vim.api.createAutocmd('BufEnter', { callback: (args) => { console.log('Entered buffer:', args.file); } }); vim.api.createAutocmd('BufWritePost', { callback: (args) => { console.log('Buffer saved:', args.file); } }); // Register commands vim.api.createUserCmd('ToggleMyPlugin', () => { myPluginState.enabled = !myPluginState.enabled; console.log(`Plugin ${myPluginState.enabled ? 'enabled' : 'disabled'}`); }, { desc: 'Toggle my plugin' }); // Create custom keybindings vim.keymap.set('n', '<leader>mp', () => { vim.cmd('ToggleMyPlugin'); }, { desc: 'Toggle my plugin' }); // Access current buffer and window const currentBuffer = vim.api.getCurrentBuf(); const currentWindow = vim.api.getCurrentWin();
Cross-Plugin Communication
Use require() to share functionality between plugins:
Exporting from a Plugin
// ~/.config/vimcraft/plugins/utils.ts // Export utilities via module.exports module.exports = { formatDate: (date: Date) => date.toISOString().split('T')[0], showNotification: (msg: string) => { console.log(`[Notification] ${msg}`); }, debounce: (fn: Function, ms: number) => { let timeout: ReturnType<typeof setTimeout>; return (...args: any[]) => { clearTimeout(timeout); timeout = setTimeout(() => fn(...args), ms); }; } };
Importing in Another Plugin
// ~/.config/vimcraft/plugins/my-plugin.ts const utils = require('./utils'); vim.api.createUserCmd('ShowDate', () => { const today = utils.formatDate(new Date()); utils.showNotification(`Today is ${today}`); }, { desc: 'Show current date' });
Plugin Configuration
Create configurable plugins by managing state:
// ~/.config/vimcraft/plugins/my-plugin.ts const config = { enabled: true, autoSave: true, delay: 1000, }; // Event handlers vim.api.createAutocmd('BufWritePost', { callback: (args) => { if (config.autoSave) { console.log('File saved:', args.file); } } }); // Toggle keybinding vim.keymap.set('n', '<leader>t', () => { config.enabled = !config.enabled; console.log(`Plugin ${config.enabled ? 'enabled' : 'disabled'}`); }, { desc: 'Toggle plugin' });
Hot Reload Development
During development, Vimcraft automatically reloads your plugins when you save them. No need to restart the editor:
- Create your plugin file in
~/.config/vimcraft/plugins/ - Edit and save - Vimcraft automatically reloads the plugin
- Check the console (
:messages) for any errors - Use
console.log()for debugging - output appears in:messages
Debugging with Chrome DevTools
Vimcraft's --debug mode opens Chrome DevTools for enhanced debugging:
# Start Vimcraft in debug mode vimcraft --debug myfile.txt
Chrome DevTools will automatically open with console access for logging and debugging.
Currently available:
- Console access - Full JavaScript console with
console.log(),console.error(), etc. - Live inspection - View logged objects and values in real-time
Coming soon:
- Breakpoints and step-through debugging
- Variable inspection and watch expressions
- Performance profiling and memory analysis
- Network monitoring
Full debugging features (breakpoints, step-through, profiling) are planned and coming soon. For now, use console.log() for debugging - all output appears in the DevTools console.
Example Plugins
Auto-save Plugin
// ~/.config/vimcraft/plugins/auto-save.ts let timer: ReturnType<typeof setTimeout> | null = null; const SAVE_DELAY = 1000; // 1 second vim.api.createAutocmd('TextChanged', { callback: () => { if (timer) clearTimeout(timer); timer = setTimeout(() => { vim.cmd('write'); console.log('Auto-saved'); }, SAVE_DELAY); } });
Word Counter Plugin
// ~/.config/vimcraft/plugins/word-count.ts function countWords(): number { const content = vim.buffer.getContent(); const text = new TextDecoder().decode(content); return text.split(/\s+/).filter(w => w.length > 0).length; } vim.api.createUserCmd('WordCount', () => { const count = countWords(); console.log(`Word count: ${count}`); }, { desc: 'Count words in buffer' }); vim.keymap.set('n', '<leader>wc', () => { vim.cmd('WordCount'); }, { desc: 'Count words' });
Filetype-Specific Settings
// ~/.config/vimcraft/plugins/ft-settings.ts vim.api.createAutocmd('FileType', { pattern: 'typescript', callback: () => { vim.opt.tabStop = 2; vim.opt.shiftWidth = 2; vim.opt.expandTab = true; vim.keymap.set('n', '<leader>r', () => { vim.cmd('!npx ts-node %'); }, { buffer: true, desc: 'Run TypeScript file' }); } }); vim.api.createAutocmd('FileType', { pattern: 'python', callback: () => { vim.opt.tabStop = 4; vim.opt.shiftWidth = 4; vim.keymap.set('n', '<leader>r', () => { vim.cmd('!python3 %'); }, { buffer: true, desc: 'Run Python file' }); } });
Testing Plugins
Use the E2E testing framework to test your plugins:
// tests/my-plugin.ts vim.e2e.describe('My Plugin', function() { vim.e2e.test('WordCount command works', function() { vim.e2e.keys('iHello World<Esc>'); vim.cmd('WordCount'); // Check console output or state }); }); vim.e2e.runAll();
Run tests with:
vimc test tests/
Next Steps
- Configuration - Learn how to configure Vimcraft
- Editor API Reference - Full API documentation
- E2E Testing - Test your plugins
- CLI Commands - vimc run, install, test commands
- Community Discussions - Share your plugins and get help