#beancount #language-server #accounting #lsp #finance

bin+lib beancount-language-server

A Language Server Protocol implementation for Beancount, providing rich editing features like completions, diagnostics, and formatting

23 stable releases

Uses new Rust 2024

new 1.9.2 Feb 12, 2026
1.8.1 Jan 25, 2026
1.3.7 Jan 26, 2025
1.3.5 Aug 5, 2024
0.1.0 Nov 11, 2021

#7 in Text editors

MIT license

715KB
16K SLoC

Beancount Language Server

License GitHub release (latest by date) Crates.io

A Language Server Protocol (LSP) implementation for Beancount, the double-entry bookkeeping language. This provides rich editing features like completions, diagnostics, formatting, and more for Beancount files in your favorite editor.

nixos

โœจ Features

๐Ÿš€ Currently Implemented

LSP Feature Description Status
Completions Smart autocompletion for accounts, payees, dates, narration, tags, links, and transaction types โœ…
Diagnostics Real-time error checking and validation via beancount Python integration โœ…
Formatting Document formatting compatible with bean-format, with support for prefix-width, num-width, and currency-column options โœ…
Rename Rename symbols across files โœ…
References Find all references to accounts, payees, etc. โœ…
Semantic Highlighting Advanced syntax highlighting with semantic information โœ…
Inlay Hints Show calculated balancing amounts and unbalanced transaction warnings โœ…

๐Ÿ“‹ Completion Types

  • Accounts: Autocomplete account names with hierarchy support (Assets:Checking)
  • Payees: Previously used payee names
  • Dates: Smart date completion (today, this month, previous month, next month)
  • Narration: Previously used transaction descriptions
  • Tags: Complete hashtags (#vacation)
  • Links: Complete links (^receipt-123)
  • Transaction Types: txn, balance, open, close, etc.

๐Ÿ’ก Inlay Hints

Non-intrusive inline annotations that help visualize implicit information:

  • Calculated Balancing Amounts: When a posting omits an amount, shows the implicit balancing amount at the end of that posting line, aligned with other amounts
  • Unbalanced Transaction Warnings: When all postings have explicit amounts but don't balance to zero, shows a warning with the unbalanced total on the transaction line

Examples:

2024-01-15 * "Grocery Store"
  Expenses:Food:Groceries              45.23 USD
  Assets:Bank:Checking                         -45.23 USD  ; โ† Shown as inlay hint

2024-01-15 * "Unbalanced Transfer"  /* = 500.00 USD โš  */  ; โ† Warning shown
  Assets:Savings                     1000.00 USD
  Assets:Checking                    -500.00 USD

๐Ÿ”ฎ Planned Features

LSP Feature Description Priority
Hover Show account balances, transaction details, account metadata High
Go to Definition Jump to account/payee/commodity definitions High
Document Symbols Outline view showing accounts, transactions, and structure High
Folding Ranges Fold transactions, account hierarchies, and multi-line entries Medium
Code Actions Quick fixes, refactoring, auto-balance transactions Medium
Signature Help Help with transaction syntax and directive parameters Low
Workspace Symbols Find accounts, payees, commodities across all files Low

๐Ÿ“ฆ Installation

cargo install beancount-language-server

Method 2: GitHub Releases (Pre-built Binaries)

Download the latest release for your platform from the releases page.

Supported Platforms:

  • Linux (x86_64, aarch64, loongarch64)
  • macOS (x86_64, aarch64)
  • Windows (x86_64)

Method 3: Homebrew (macOS/Linux)

brew install beancount-language-server

Method 4: Nix

# Using nix-env
nix-env -iA nixpkgs.beancount-language-server

# Using nix shell
nix shell nixpkgs#beancount-language-server

# Development environment
nix develop

Method 5: Build from Source

git clone https://github.com/polarmutex/beancount-language-server.git
cd beancount-language-server

# Standard build (includes PyO3 embedded Python support by default)
cargo build --release

# Build without PyO3 (minimal binary, requires external bean-check/python)
cargo build --release --no-default-features

The binary will be available at target/release/beancount-language-server.

๐Ÿ”ง Requirements

For Diagnostics (Bean-check)

The language server requires one of the following for validation and diagnostics:

Option 1: PyO3 Embedded (Default - Recommended)

  • Python 3.8+ installed on your system
  • beancount Python package
    pip install beancount
    
  • Pre-built binaries from GitHub releases include PyO3 support by default
  • Performance: 60-66x faster than subprocess-based methods (~838ฮผs vs ~50ms per check)
  • Note: If beancount is not available, automatically falls back to other methods

Python Environment Compatibility

The PyO3 embedded checker (recommended) works seamlessly with:

  • โœ… System Python 3.8+ (any minor version)
  • โœ… Virtual environments (venv, virtualenv)
  • โœ… Conda environments
  • โœ… pyenv-managed Python
  • โœ… Multiple Python versions (uses abi3 stable ABI - one binary works with all Python 3.8+)
  • โœ… Project-local .venv (automatically detected)

No special configuration needed - the binary automatically detects and uses available Python installations.

Python Discovery Order

The language server searches for Python in this order:

  1. BEANCOUNT_LSP_PYTHON environment variable (if set)
  2. User-configured python_cmd in LSP settings
  3. Project-local .venv/bin/python (or .venv/Scripts/python.exe on Windows)
  4. System python3 in PATH
  5. System python in PATH

Advanced: Explicit Python Override

For edge cases or custom Python installations, set the environment variable:

# Unix/Linux/macOS
export BEANCOUNT_LSP_PYTHON=/path/to/python
beancount-language-server

# Windows (PowerShell)
$env:BEANCOUNT_LSP_PYTHON = "C:\path\to\python.exe"
beancount-language-server

# Windows (CMD)
set BEANCOUNT_LSP_PYTHON=C:\path\to\python.exe
beancount-language-server

Or configure via LSP settings:

{
  "bean_check": {
    "python_cmd": "/path/to/python"
  }
}

Option 2: System Python (Fallback)

  • Python with beancount library
  • Used automatically if PyO3 checker is unavailable
  • Invokes Python via subprocess for validation

Option 3: Bean-check Binary (Fallback)

  • Traditional bean-check command-line tool
  • Install via: pip install beancount (includes bean-check)
  • Used if Python methods are unavailable

Performance Comparison

Based on comprehensive benchmarks with a 30-line beancount file:

Method Average Time Relative Speed Availability
PyO3 Embedded (default) ~838ฮผs 1x (baseline) Requires Python 3.8+ + beancount
System Python ~50.1ms 60x slower Requires Python + beancount
Bean-check Binary ~55.2ms 66x slower Requires bean-check binary

Recommendation: Use PyO3 embedded checker (default in pre-built binaries) for optimal performance.

โš™๏ธ Configuration

The language server accepts configuration via LSP initialization options:

{
  // Optional: Only needed for multi-file projects with include directives
  "journal_file": "/path/to/main.beancount",
  "formatting": {
    "prefix_width": 30,
    "num_width": 10,
    "currency_column": 60,
    "account_amount_spacing": 2,
    "number_currency_spacing": 1
  },
  "diagnostic_flags": ["!"]  // Optional: flags that generate warnings (default: ["!"])
}

Note: All configuration is optional. The language server will auto-detect the best checker method (PyO3 โ†’ System Python โ†’ Bean-check).

Configuration Options

Option Type Description Default
journal_file string Path to the main beancount journal file. Optional: Only required if your beancount files use include directives to span multiple files. Single-file projects work without this setting. None

Workspace-Specific Configuration

The journal_file setting is workspace-specific. Each editor workspace (project folder) can have its own journal file configured. This means:

  • Completions are scoped: Account names, payees, currencies, tags, and links are loaded only from the configured journal and its included files
  • Separate ledgers: If you work on multiple beancount projects (personal finances, business, etc.), each workspace uses its own configuration
  • No cross-contamination: Accounts from one ledger won't appear as completions in another

Example workflow with multiple ledgers:

~/finances/personal/     # Workspace 1: journal_file = "main.beancount"
  โ”œโ”€โ”€ main.beancount     # Includes accounts/*.beancount
  โ””โ”€โ”€ accounts/
      โ””โ”€โ”€ assets.beancount

~/finances/business/     # Workspace 2: journal_file = "ledger.beancount"
  โ”œโ”€โ”€ ledger.beancount   # Includes 2024/*.beancount
  โ””โ”€โ”€ 2024/
      โ””โ”€โ”€ transactions.beancount

When editing files in ~/finances/personal/, completions only show accounts like Assets:Personal:Checking. When editing in ~/finances/business/, completions show Assets:Business:Operating.

Bean-check Configuration

Option Type Description Default
bean_check.method string Validation method: "system", "python-system", or "python-embedded" None
bean_check.bean_check_cmd string Path to bean-check binary (for "system" method) None
bean_check.python_cmd string Path to Python executable (for Python methods) None

Preferred checker order (when bean_check.method is not set):

  1. python-embedded (if built with the feature and available)
  2. python-system (if a compatible Python with beancount is available)
  3. system (if bean-check is available)

Configuration Examples

Default (no configuration needed):

The language server automatically selects the best available checker method:

  1. PyO3 Embedded (if Python 3.8+ with beancount is available)
  2. System Python (if Python with beancount is available)
  3. System Call (if bean-check binary is available)

No configuration required! Just install Python and beancount.

Override to force a specific method:

Only configure bean_check.method if you need to override auto-detection:

{
  "bean_check": {
    "method": "system", // Force bean-check binary
    "bean_check_cmd": "/usr/local/bin/bean-check"
  }
}
{
  "bean_check": {
    "method": "python-system", // Force Python subprocess
    "python_cmd": "/usr/bin/python3"
  }
}
{
  "bean_check": {
    "method": "python-embedded" // Force PyO3 (already default)
  }
}

Troubleshooting PyO3 Checker

If the PyO3 embedded checker is not working:

  1. Verify Python installation:

    python3 --version  # Should be 3.8 or higher
    
  2. Verify beancount installation:

    python3 -c "import beancount.loader; print('Beancount OK')"
    
  3. Check language server logs for PyO3-related messages:

    • VSCode: View โ†’ Output โ†’ Select "Beancount Language Server"
    • Neovim: :LspLog
    • Look for messages like "PyO3EmbeddedChecker: failed to import beancount.loader"
  4. Install beancount if missing:

    # System-wide
    pip3 install beancount
    
    # User installation (no sudo required)
    pip3 install --user beancount
    
    # Virtual environment (recommended)
    python3 -m venv ~/.beancount-env
    source ~/.beancount-env/bin/activate
    pip install beancount
    
  5. Override Python detection (if you have multiple Python installations):

    # Set environment variable to use specific Python
    export BEANCOUNT_LSP_PYTHON=/path/to/python3
    
    # Or configure in LSP settings
    {
      "bean_check": {
        "python_cmd": "/path/to/python3"
      }
    }
    
  6. Fallback methods: If PyO3 checker fails, the language server automatically tries:

    • System Python method (python -c with beancount)
    • System Call method (bean-check binary)

    Check your configuration if you need to explicitly set a method.

Diagnostic Flags Configuration

By default, the language server generates warnings for all flagged transactions (entries with flags like !, P, etc.). You can configure which flags should generate diagnostics to reduce noise from intentional flags.

Option Type Description Default
diagnostic_flags string[] List of transaction flags that should generate warning diagnostics ["!"]

Default behavior (only ! flag generates warnings):

{
  "diagnostic_flags": ["!"]
}

This means padding transactions with P flag, or other custom flags, won't generate warnings.

Include multiple flags:

{
  "diagnostic_flags": ["!", "P"]
}

This generates warnings for both ! (needs attention) and P (padding) flags.

Disable all flag diagnostics:

{
  "diagnostic_flags": []
}

This completely disables warnings for flagged transactions.

Use case: Some users intentionally use flags like P for padding transactions that will persist forever in the ledger. With the default configuration, these won't generate noise in your diagnostics panel, while ! flags (which typically indicate transactions needing review) will still show warnings.

Formatting Options

Option Type Description Default Bean-format Equivalent
prefix_width number Fixed width for account names (overrides auto-detection) Auto-calculated --prefix-width (-w)
num_width number Fixed width for number alignment (overrides auto-detection) Auto-calculated --num-width (-W)
currency_column number Align currencies at this specific column None (right-align) --currency-column (-c)
account_amount_spacing number Minimum spaces between account names and amounts 2 N/A
number_currency_spacing number Number of spaces between number and currency 1 N/A

Formatting Modes

Default Mode (no currency_column specified):

  • Accounts are left-aligned
  • Numbers are right-aligned with consistent end positions
  • Behaves like bean-format with no special options

Currency Column Mode (currency_column specified):

  • Currencies are aligned at the specified column
  • Numbers are positioned to place currencies at the target column
  • Equivalent to bean-format --currency-column N

Examples

Basic formatting with auto-detection:

{
  "formatting": {}
}

Fixed prefix width (like bean-format -w 25):

{
  "formatting": {
    "prefix_width": 25
  }
}

Currency column alignment (like bean-format -c 60):

{
  "formatting": {
    "currency_column": 60
  }
}

Number-currency spacing control:

{
  "formatting": {
    "number_currency_spacing": 2
  }
}

This controls the whitespace between numbers and currency codes:

  • 0: No space (100.00USD)
  • 1: Single space (100.00 USD) - default
  • 2: Two spaces (100.00 USD)

Combined options:

{
  "formatting": {
    "prefix_width": 30,
    "currency_column": 65,
    "account_amount_spacing": 3,
    "number_currency_spacing": 1
  }
}

๐Ÿ–ฅ๏ธ Editor Setup

Visual Studio Code

  1. Install the Beancount extension from the marketplace
  2. Configure in settings.json (optional):
    {
      // Optional: Only needed for multi-file projects with include directives
      "beancountLangServer.journalFile": "/path/to/main.beancount",
      "beancountLangServer.formatting": {
        "prefix_width": 30,
        "currency_column": 60,
        "number_currency_spacing": 1
      },
      // Optional: flags that generate warnings (default: ["!"])
      "beancountLangServer.diagnosticFlags": ["!"]
    }
    

Workspace-specific configuration: Create a .vscode/settings.json in each project folder:

{
  "beancountLangServer.journalFile": "${workspaceFolder}/main.beancount"
}

This ensures each workspace uses its own journal file for completions and diagnostics.

Neovim

Using nvim.lsp (nvim > 0.11)

lsp/beancount.lua

return {
    commands = { "beancount-language-server", "--stdio" },
    root_markers = { "main.bean", ".git" },
    -- init_options are optional
    init_options = {
        -- Optional: Only needed for multi-file projects with include directives
        journal_file = "main.bean",
        -- Optional: flags that generate warnings (default: ["!"])
        diagnostic_flags = { "!" },
    },
    settings = {
        beancount = {
            formatting = {
                prefix_width = 30,
                currency_column = 60,
                number_currency_spacing = 1,
            }
        }
    }
}

Using nvim-lspconfig:

local lspconfig = require('lspconfig')

lspconfig.beancount.setup({
  -- All init_options are optional
  init_options = {
    -- Optional: Only needed for multi-file projects with include directives
    -- journal_file = "/path/to/main.beancount",
    formatting = {
      prefix_width = 30,
      currency_column = 60,
      number_currency_spacing = 1,
    },
    -- Optional: flags that generate warnings (default: {"!"})
    diagnostic_flags = { "!" },
  },
})

-- To override auto-detected checker method:
-- lspconfig.beancount.setup({
--   init_options = {
--     bean_check = {
--       method = "system",  -- Force specific method: "python-embedded", "python-system", or "system"
--     },
--   },
-- })

File type detection: Ensure beancount files are detected. Add to your config:

vim.filetype.add({
  extension = {
    beancount = "beancount",
    bean = "beancount",
  },
})

Workspace-specific configuration: Use .nvim.lua or exrc for per-project settings:

-- .nvim.lua in your beancount project root
vim.lsp.config.beancount = {
  init_options = {
    journal_file = vim.fn.getcwd() .. "/main.beancount",
  },
}

Or with nvim-lspconfig, use on_new_config to dynamically set the journal file:

lspconfig.beancount.setup({
  on_new_config = function(new_config, new_root_dir)
    new_config.init_options = new_config.init_options or {}
    new_config.init_options.journal_file = new_root_dir .. "/main.beancount"
  end,
})

Helix

Add to your languages.toml:

[language-server.beancount-language-server]
command = "beancount-language-server"
args = ["--stdio"]

# Configuration is optional
[language-server.beancount-language-server.config]
# Optional: Only needed for multi-file projects with include directives
# journal_file = "/path/to/main.beancount"

# Optional: bean_check config (uses python-embedded by default)
# [language-server.beancount-language-server.config.bean_check]
# method = "python-embedded"  # or "python-system" or "system"

# Optional: formatting configuration
[language-server.beancount-language-server.config.formatting]
prefix_width = 30
currency_column = 60
number_currency_spacing = 1

[[language]]
name = "beancount"
language-servers = [{ name = "beancount-language-server" }]

Zed

Add to your settings.json (access via Zed > Settings > Open Settings):

{
  "lsp": {
    "beancount-language-server": {
      "binary": {
        "path": "beancount-language-server",
        "arguments": ["--stdio"]
      },
      "initialization_options": {
        // Optional: Only needed for multi-file projects with include directives
        "journal_file": "/path/to/main.beancount",
        "formatting": {
          "prefix_width": 30,
          "currency_column": 60,
          "number_currency_spacing": 1
        }
      }
    }
  },
  "languages": {
    "Beancount": {
      "language_servers": ["beancount-language-server"]
    }
  }
}

For workspace-specific configuration, create a .zed/settings.json in your project root:

{
  "lsp": {
    "beancount-language-server": {
      "initialization_options": {
        "journal_file": "main.beancount"
      }
    }
  }
}

Note: Zed may require a Beancount extension for syntax highlighting. The language server provides completions, diagnostics, and formatting regardless of syntax highlighting support.

Emacs

Using lsp-mode:

(use-package lsp-mode
  :hook (beancount-mode . lsp-deferred)
  :config
  (lsp-register-client
   (make-lsp-client
    :new-connection (lsp-stdio-connection "beancount-language-server")
    :major-modes '(beancount-mode)
    :server-id 'beancount-language-server
    :initialization-options
    ;; All options are optional
    (lambda () (list
                ;; Optional: Only needed for multi-file projects with include directives
                ;; :journal_file "/path/to/main.beancount"
                ;; Optional: bean_check config (uses python-embedded by default)
                ;; :bean_check '(:method "python-embedded")
                :formatting '(:prefix_width 30 :currency_column 60 :number_currency_spacing 1))))))

Workspace-specific configuration: Use .dir-locals.el in your project root:

;; .dir-locals.el
((beancount-mode
  . ((lsp-clients-beancount-langserver-init-options
      . (:journal_file "./main.beancount")))))

Or dynamically set based on project root:

(defun my/beancount-lsp-init-options ()
  "Generate init options with project-local journal file."
  (let ((journal-file (expand-file-name "main.beancount" (project-root (project-current)))))
    (when (file-exists-p journal-file)
      (list :journal_file journal-file))))

;; Use in lsp-register-client with :initialization-options #'my/beancount-lsp-init-options

Vim

Using vim-lsp:

if executable('beancount-language-server')
    au User lsp_setup call lsp#register_server({
        \ 'name': 'beancount-language-server',
        \ 'cmd': {server_info->['beancount-language-server']},
        \ 'allowlist': ['beancount'],
        \ 'initialization_options': {
        \   'formatting': {
        \     'prefix_width': 30,
        \     'currency_column': 60,
        \     'number_currency_spacing': 1
        \   }
        \ }
    \ })
    " Optional: For multi-file projects with include directives, add:
    " \   'journal_file': '/path/to/main.beancount',
    " Optional: To override default checker method, add:
    " \   'bean_check': {'method': 'python-embedded'},
endif

Sublime Text

Using LSP:

Add to LSP settings:

{
  "clients": {
    "beancount-language-server": {
      "enabled": true,
      "command": ["beancount-language-server"],
      "selector": "source.beancount",
      // All initializationOptions are optional
      "initializationOptions": {
        // Optional: Only needed for multi-file projects with include directives
        // "journal_file": "/path/to/main.beancount",
        "formatting": {
          "prefix_width": 30,
          "currency_column": 60,
          "number_currency_spacing": 1
        }
      }
    }
  }
}

๐Ÿ—๏ธ Architecture

High-Level Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     Editor      โ”‚โ—„โ”€โ”€โ–บโ”‚  LSP Server     โ”‚โ—„โ”€โ”€โ–บโ”‚   Beancount     โ”‚
โ”‚                 โ”‚    โ”‚                 โ”‚    โ”‚   (Python)      โ”‚
โ”‚ - VSCode        โ”‚    โ”‚ - Completion    โ”‚    โ”‚ - Validation    โ”‚
โ”‚ - Neovim        โ”‚    โ”‚ - Formatting    โ”‚    โ”‚ - Parsing       โ”‚
โ”‚ - Helix         โ”‚    โ”‚ - Diagnostics   โ”‚    โ”‚ - Bean-check    โ”‚
โ”‚ - Emacs         โ”‚    โ”‚ - Tree-sitter   โ”‚    โ”‚                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Core Components

  • LSP Server: Main Rust application handling LSP protocol
  • Tree-sitter Parser: Fast, incremental parsing of Beancount syntax
  • Completion Engine: Smart autocompletion with context awareness
  • Diagnostic Provider: Multi-method validation system with pluggable checkers
  • Bean-check Integration: Three validation methods (system, python-embedded)
  • Formatter: Code formatting fully compatible with bean-format, supporting prefix-width, num-width, and currency-column options

Project Structure

beancount-language-server/
โ”œโ”€โ”€ crates/lsp/           # Main LSP server implementation
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ handlers.rs   # LSP request/notification handlers
โ”‚   โ”‚   โ”œโ”€โ”€ providers/    # Feature providers (completion, diagnostics, etc.)
โ”‚   โ”‚   โ”œโ”€โ”€ checkers/     # Bean-check validation implementations
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ mod.rs    # Strategy trait and factory pattern
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ system_call.rs     # Traditional bean-check binary
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ pyo3_embedded.rs   # PyO3 embedded Python
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ types.rs           # Shared data structures
โ”‚   โ”‚   โ””โ”€โ”€ server.rs     # Core LSP server logic
โ”œโ”€โ”€ vscode/               # VS Code extension
โ””โ”€โ”€ flake.nix            # Nix development environment

๐Ÿ› ๏ธ Development

Prerequisites

  • Rust (stable toolchain)
  • Python with beancount
  • Node.js (for VS Code extension)

Development Environment

Using Nix (Recommended):

nix develop

Manual Setup:

# Install Rust dependencies
cargo build

# Install Node.js dependencies (for VS Code extension)
cd vscode && pnpm install

# Install development tools
cargo install cargo-watch

Running Tests

# Run all tests
cargo test

# Run with coverage
cargo llvm-cov --all-features --locked --workspace --lcov --output-path lcov.info

# Run tests with PyO3 feature
cargo test --features python-embedded

# Run specific test
cargo test test_completion

Code Quality

# Format code
cargo fmt

# Lint code
cargo clippy --all-targets --all-features

# Check formatting
cargo fmt -- --check

Development Workflow

  1. Make changes to the Rust code
  2. Test locally with cargo test
  3. Run LSP server in development mode:
    cargo run --bin beancount-language-server
    
  4. Test with editor by configuring it to use the local binary

VS Code Extension Development

cd vscode
pnpm run build      # Build extension
pnpm run watch      # Watch for changes
pnpm run package    # Package extension

Release Process

  1. Tag a release: git tag v1.0.0 && git push --tags
  2. GitHub Actions automatically builds and publishes:
    • Binaries for all supported platforms
    • Crates.io release
    • GitHub release with assets

๐Ÿค Contributing

Contributions are welcome! Here are some ways to help:

๐Ÿ› Bug Reports

  • Search existing issues first
  • Include beancount file examples that trigger the bug
  • Provide editor and OS information

๐Ÿ’ก Feature Requests

  • Check the planned features list
  • Describe the use case and expected behavior
  • Consider the LSP specification constraints

๐Ÿ”ง Code Contributions

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with tests
  4. Ensure code quality: cargo fmt && cargo clippy && cargo test
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

๐ŸŽฏ Good First Issues

Look for issues labeled good-first-issue:

  • Add new completion types
  • Improve error messages
  • Add editor configuration examples
  • Improve documentation

๐Ÿ“š Resources

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments

  • Beancount - The amazing double-entry bookkeeping language
  • Tree-sitter - Incremental parsing framework
  • LSP - Language Server Protocol specification
  • Twemoji - Emoji graphics used in the icon

Happy Beancounting! ๐Ÿ“Šโœจ

Dependencies

~21โ€“28MB
~423K SLoC