https://github.com/polarmutex/beancount-language-server
A Language Server Protocol (LSP) for beancount files
https://github.com/polarmutex/beancount-language-server
Last synced: about 1 month ago
JSON representation
A Language Server Protocol (LSP) for beancount files
- Host: GitHub
- URL: https://github.com/polarmutex/beancount-language-server
- Owner: polarmutex
- License: mit
- Created: 2020-05-19T00:07:10.000Z (almost 6 years ago)
- Default Branch: main
- Last Pushed: 2025-05-01T04:56:36.000Z (11 months ago)
- Last Synced: 2025-05-08T21:34:40.685Z (11 months ago)
- Language: Rust
- Size: 1.37 MB
- Stars: 167
- Watchers: 4
- Forks: 21
- Open Issues: 25
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
- awesome-beancount - LSP
README
# Beancount Language Server



A [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP) implementation for [Beancount](https://beancount.github.io/), the double-entry bookkeeping language. This provides rich editing features like completions, diagnostics, formatting, and more for Beancount files in your favorite editor.

## âĻ 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:**
```beancount
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
### Method 1: Cargo (Recommended)
```bash
cargo install beancount-language-server
```
### Method 2: GitHub Releases (Pre-built Binaries)
Download the latest release for your platform from the [releases page](https://github.com/polarmutex/beancount-language-server/releases).
**Supported Platforms:**
- Linux (x86_64, aarch64, loongarch64)
- macOS (x86_64, aarch64)
- Windows (x86_64)
### Method 3: Homebrew (macOS/Linux)
```bash
brew install beancount-language-server
```
### Method 4: Nix
```bash
# 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
```bash
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
```bash
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:
```bash
# 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:
```json
{
"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:
```json
{
// 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:
```json
{
"bean_check": {
"method": "system", // Force bean-check binary
"bean_check_cmd": "/usr/local/bin/bean-check"
}
}
```
```json
{
"bean_check": {
"method": "python-system", // Force Python subprocess
"python_cmd": "/usr/bin/python3"
}
}
```
```json
{
"bean_check": {
"method": "python-embedded" // Force PyO3 (already default)
}
}
```
#### Troubleshooting PyO3 Checker
If the PyO3 embedded checker is not working:
1. **Verify Python installation**:
```bash
python3 --version # Should be 3.8 or higher
```
2. **Verify beancount installation**:
```bash
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**:
```bash
# 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):
```bash
# 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):
```json
{
"diagnostic_flags": ["!"]
}
```
This means padding transactions with `P` flag, or other custom flags, won't generate warnings.
**Include multiple flags:**
```json
{
"diagnostic_flags": ["!", "P"]
}
```
This generates warnings for both `!` (needs attention) and `P` (padding) flags.
**Disable all flag diagnostics:**
```json
{
"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:**
```json
{
"formatting": {}
}
```
**Fixed prefix width (like `bean-format -w 25`):**
```json
{
"formatting": {
"prefix_width": 25
}
}
```
**Currency column alignment (like `bean-format -c 60`):**
```json
{
"formatting": {
"currency_column": 60
}
}
```
**Number-currency spacing control:**
```json
{
"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:**
```json
{
"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](https://marketplace.visualstudio.com/items?itemName=polarmutex.beancount-langserver) from the marketplace
2. Configure in `settings.json` (optional):
```json
{
// 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:
```json
{
"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`
```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](https://github.com/neovim/nvim-lspconfig):
```lua
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:
```lua
vim.filetype.add({
extension = {
beancount = "beancount",
bean = "beancount",
},
})
```
**Workspace-specific configuration**: Use `.nvim.lua` or `exrc` for per-project settings:
```lua
-- .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:
```lua
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`:
```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`):
```json
{
"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:
```json
{
"lsp": {
"beancount-language-server": {
"initialization_options": {
"journal_file": "main.beancount"
}
}
}
}
```
**Note**: Zed may require a [Beancount extension](https://zed.dev/extensions) for syntax highlighting. The language server provides completions, diagnostics, and formatting regardless of syntax highlighting support.
### Emacs
Using [lsp-mode](https://github.com/emacs-lsp/lsp-mode):
```elisp
(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:
```elisp
;; .dir-locals.el
((beancount-mode
. ((lsp-clients-beancount-langserver-init-options
. (:journal_file "./main.beancount")))))
```
Or dynamically set based on project root:
```elisp
(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](https://github.com/prabirshrestha/vim-lsp):
```vim
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](https://packagecontrol.io/packages/LSP):
Add to LSP settings:
```json
{
"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):**
```bash
nix develop
```
**Manual Setup:**
```bash
# 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
```bash
# 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
```bash
# 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:
```bash
cargo run --bin beancount-language-server
```
4. **Test with editor** by configuring it to use the local binary
### VS Code Extension Development
```bash
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](#-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
- **[Beancount Documentation](https://beancount.github.io/)**
- **[Language Server Protocol Specification](https://microsoft.github.io/language-server-protocol/)**
- **[Tree-sitter Beancount Grammar](https://github.com/polarmutex/tree-sitter-beancount)**
- **[VSCode Extension API](https://code.visualstudio.com/api)**
## ð License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## ð Acknowledgments
- **[Beancount](https://github.com/beancount/beancount)** - The amazing double-entry bookkeeping language
- **[Tree-sitter](https://tree-sitter.github.io/)** - Incremental parsing framework
- **[LSP](https://microsoft.github.io/language-server-protocol/)** - Language Server Protocol specification
- **[Twemoji](https://github.com/twitter/twemoji)** - Emoji graphics used in the icon
---
Happy Beancounting! ðâĻ