Vimcraft Docs / vim.buffer - Buffer Content API

vim.buffer - Buffer Content API

Zero-copy buffer content access using ArrayBuffer. Designed for high-performance plugins that need direct buffer access.

Reading Content

getContent()

Get entire buffer content as ArrayBuffer.

const content = vim.buffer.getContent();
const text = new TextDecoder().decode(content);
console.log(`Buffer has ${text.length} characters`);

getLineContent(lineNumber)

Get a specific line's content (0-indexed).

// Get first line
const firstLine = vim.buffer.getLineContent(0);
const text = new TextDecoder().decode(firstLine);
console.log(`First line: ${text}`);

// Get last line
const lineCount = vim.buffer.getLineCount();
const lastLine = vim.buffer.getLineContent(lineCount - 1);

Buffer Information

getLineCount()

Get total number of lines.

const lines = vim.buffer.getLineCount();
console.log(`Buffer has ${lines} lines`);

getLength()

Get total buffer size in bytes.

const bytes = vim.buffer.getLength();
console.log(`Buffer size: ${bytes} bytes`);

getChangedTick()

Get the buffer change counter. Increments on each modification.

// Check for changes
const before = vim.buffer.getChangedTick();

// ... some operations ...

const after = vim.buffer.getChangedTick();
if (after !== before) {
  console.log('Buffer was modified');
}

Use Cases

Content Analysis Plugin

function analyzeBuffer() {
  const content = vim.buffer.getContent();
  const text = new TextDecoder().decode(content);

  const lines = vim.buffer.getLineCount();
  const chars = text.length;
  const words = text.split(/\s+/).filter(w => w.length > 0).length;

  console.log(`Lines: ${lines}, Words: ${words}, Characters: ${chars}`);
}

vim.api.createUserCmd('Stats', analyzeBuffer, {
  desc: 'Show buffer statistics'
});

Caching with Change Detection

let cachedContent: string | null = null;
let lastTick = 0;

function getBufferContent(): string {
  const currentTick = vim.buffer.getChangedTick();

  if (currentTick !== lastTick || cachedContent === null) {
    const content = vim.buffer.getContent();
    cachedContent = new TextDecoder().decode(content);
    lastTick = currentTick;
  }

  return cachedContent;
}

Line-by-Line Processing

function processAllLines() {
  const lineCount = vim.buffer.getLineCount();

  for (let i = 0; i < lineCount; i++) {
    const lineContent = vim.buffer.getLineContent(i);
    const lineText = new TextDecoder().decode(lineContent);

    // Process each line
    if (lineText.includes('TODO')) {
      console.log(`TODO found on line ${i + 1}: ${lineText}`);
    }
  }
}

Performance Notes

  • getContent() returns a zero-copy ArrayBuffer snapshot
  • Buffer modifications after the call may not be reflected in the returned ArrayBuffer
  • Use getChangedTick() to detect when content needs to be re-read
  • For line-by-line access, vim.api.bufGetLines() returns string arrays directly

Comparison with vim.api

Use Casevim.buffervim.api
Binary-safe contentgetContent() returns ArrayBufferbufGetLines() returns strings
PerformanceZero-copy, faster for large filesString conversion overhead
Line accessgetLineContent(n)bufGetLines(buf, n, n+1, false)
ModificationRead-onlybufSetLines() for editing

See Also