Plugin Development
Build powerful plugins for Vimcraft using JavaScript with hot reload and access to the complete Neovim-compatible API.
Why Build Plugins for Vimcraft?
- JavaScript-Native - Write plugins in JavaScript with modern ES6+ features.
- 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.
Getting Started
Vimcraft plugins are JavaScript modules that export a function. The vim global object is automatically available. The simplest plugin looks like this:
// ~/.config/vimcraft/plugins/hello.js export default function(vim) { // Plugin initialization vim.notify('Hello from my plugin!'); // Register a command vim.command('SayHello', () => { vim.notify('Hello, Vimcraft!'); }); // Add a keybinding vim.keymap.set('n', '<leader>h', () => { vim.cmd('SayHello'); }); }
Plugins are loaded from ~/.config/vimcraft/plugins/. Create a .js file in this directory and it will be automatically loaded on startup.
Plugin Structure
A plugin is a module that exports a default function. This function receives the vim API object and can use it to interact with the editor:
// Complete plugin example export default function(vim) { // State management let myPluginState = { enabled: true, count: 0, }; // Listen to events vim.on('bufEnter', (buffer) => { console.log('Entered buffer:', buffer.name); }); vim.on('bufWrite', async (buffer) => { console.log('Buffer saved:', buffer.name); }); // Register commands vim.command('ToggleMyPlugin', () => { myPluginState.enabled = !myPluginState.enabled; vim.notify(`Plugin ${myPluginState.enabled ? 'enabled' : 'disabled'}`); }); // Create custom keybindings vim.keymap.set('n', '<leader>mp', () => { vim.cmd('ToggleMyPlugin'); }); // Access current buffer and window const currentBuffer = vim.api.getCurrentBuffer(); const currentWindow = vim.api.getCurrentWindow(); }
Plugin Configuration
You can create configurable plugins by managing state within your plugin:
// my-plugin.js export default function(vim) { const config = { enabled: true, autoSave: true, delay: 1000, }; // Event handlers vim.on('bufWrite', async (buffer) => { if (config.autoSave) { vim.notify('File saved!'); } }); // Keybindings vim.keymap.set('n', '<leader>t', () => { config.enabled = !config.enabled; vim.notify(`Plugin ${config.enabled ? 'enabled' : 'disabled'}`); }); }
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
export default function(vim) { let timer = null; const SAVE_DELAY = 1000; // 1 second vim.on('textChanged', () => { if (timer) clearTimeout(timer); timer = setTimeout(() => { vim.cmd('write'); vim.notify('Auto-saved', { timeout: 1000 }); }, SAVE_DELAY); }); }
Project-wide Find & Replace
export default function(vim) { vim.command('FindReplace', async (args) => { const [find, replace] = args.split(' '); const files = await vim.fs.glob('**/*.{ts,js,tsx,jsx}'); let count = 0; for (const file of files) { const content = await vim.fs.readFile(file); const newContent = content.replaceAll(find, replace); if (content !== newContent) { await vim.fs.writeFile(file, newContent); count++; } } vim.notify(`Replaced in ${count} files`); }); }
Next Steps
- Configuration - Learn how to configure Vimcraft
- Community Discussions - Share your plugins and get help