Vimcraft Docs / Variables & Scopes

Variables & Scopes

Vimcraft provides variable storage via vim.api functions, matching Neovim's variable system.

Current Implementation

Variables are accessed through vim.api functions:

ScopeGetSetDelete
Buffervim.api.bufGetVar(buf, name)vim.api.bufSetVar(buf, name, val)vim.api.bufDelVar(buf, name)
Windowvim.api.winGetVar(win, name)vim.api.winSetVar(win, name, val)vim.api.winDelVar(win, name)

Buffer Variables

Store data specific to each buffer using vim.api functions:

// Set buffer variable (0 = current buffer)
vim.api.bufSetVar(0, 'myPlugin_enabled', true);
vim.api.bufSetVar(0, 'customFormatter', 'prettier');

// Get buffer variable
const enabled = vim.api.bufGetVar(0, 'myPlugin_enabled');
const formatter = vim.api.bufGetVar(0, 'customFormatter');

// Delete buffer variable
vim.api.bufDelVar(0, 'myPlugin_enabled');

Use in Autocommands

// Set buffer state when entering specific files
vim.api.createAutocmd('BufEnter', {
  pattern: '*.md',
  callback: () => {
    vim.api.bufSetVar(0, 'isMarkdown', true);
    vim.api.bufSetVar(0, 'previewEnabled', false);
  }
});

// Toggle based on buffer state
vim.keymap.set('n', '<leader>p', () => {
  const isMarkdown = vim.api.bufGetVar(0, 'isMarkdown');
  if (isMarkdown) {
    const current = vim.api.bufGetVar(0, 'previewEnabled') || false;
    vim.api.bufSetVar(0, 'previewEnabled', !current);
    console.log(`Preview: ${!current ? 'on' : 'off'}`);
  }
}, { desc: 'Toggle markdown preview' });

Window Variables

Store data specific to each window:

// Set window variable (0 = current window)
vim.api.winSetVar(0, 'scrollPosition', 100);
vim.api.winSetVar(0, 'sidebarWidth', 30);

// Get window variable
const scroll = vim.api.winGetVar(0, 'scrollPosition');

// Delete window variable
vim.api.winDelVar(0, 'scrollPosition');

Track Window State

// Remember scroll position per window
vim.api.createAutocmd('WinLeave', {
  callback: () => {
    const [row, col] = vim.api.winGetCursor(0);
    vim.api.winSetVar(0, 'lastCursor', [row, col]);
  }
});

vim.api.createAutocmd('WinEnter', {
  callback: () => {
    const lastCursor = vim.api.winGetVar(0, 'lastCursor');
    if (lastCursor) {
      console.log('Returning to cursor:', lastCursor);
    }
  }
});

Buffer Options (vim.bo)

Access buffer-specific options like filetype:

// Get current buffer's filetype
const ft = vim.bo.filetype;
console.log('Current filetype:', ft);

// React to filetype
vim.api.createAutocmd('FileType', {
  callback: (args) => {
    console.log('Filetype set to:', args.match);
  }
});

Plugin State Pattern

Store plugin configuration in JavaScript variables (recommended approach):

// ~/.config/vimcraft/plugins/my-plugin.ts

// Plugin-level state (persists for session)
const config = {
  enabled: true,
  autoSave: false,
  delay: 1000,
};

// Per-buffer state using Map
const bufferState = new Map<number, { wordCount: number; lastSaved: number }>();

// Initialize state for new buffers
vim.api.createAutocmd('BufEnter', {
  callback: () => {
    const buf = vim.api.getCurrentBuf();
    if (!bufferState.has(buf)) {
      bufferState.set(buf, { wordCount: 0, lastSaved: Date.now() });
    }
  }
});

// Toggle command
vim.api.createUserCmd('ToggleMyPlugin', () => {
  config.enabled = !config.enabled;
  console.log(`Plugin ${config.enabled ? 'enabled' : 'disabled'}`);
}, { desc: 'Toggle my plugin' });

Cross-Plugin Communication

Share state between plugins using require():

// ~/.config/vimcraft/plugins/shared-state.ts
module.exports = {
  activeProject: null,
  settings: {},

  setProject(path: string) {
    this.activeProject = path;
  },

  getProject() {
    return this.activeProject;
  }
};
// ~/.config/vimcraft/plugins/project-plugin.ts
const shared = require('./shared-state');

vim.api.createUserCmd('SetProject', (args) => {
  shared.setProject(args.args);
  console.log('Project set to:', args.args);
}, { nargs: 1 });

Planned: vim.g/b/w/t/v Proxies

Future versions will add Neovim-style proxy objects for more ergonomic access:

// Planned syntax (not yet implemented)
vim.g.mapleader = ' ';           // Global variable
vim.b.customFormatter = 'prettier';  // Buffer variable
vim.w.scrollBind = true;         // Window variable
vim.t.tabName = 'Dev';           // Tab variable
const count = vim.v.count;       // Vim variable (read-only)

Until then, use vim.api functions or JavaScript variables as shown above.

See Also