Lazyvim (neovim) configuration for hledger

I decided to move slowly from emacs to neovim because I feel more confortable to modal editing because as Linux admin I use vi/vim/neovim everyday. I chose the lazyvim distribution for neovim and I would like to share with you my configuration for hledger files.

Contents of the file $HOME/.config/nvim/lua/plugins/hledger.lua:

return {
  {
    "ledger/vim-ledger",
    version = false,
    ft = "ledger",
    init = function()
      vim.g.ledger_bin = "hledger"
      vim.g.ledger_fuzzy_account_completion = 1
      vim.g.ledger_date_format = "%Y-%m-%d"
      vim.g.ledger_align_at = 70
    end,
    opt = {},
  },
  {
    "saghen/blink.cmp",
    opts = {
      sources = {
        compat = {},
        default = { "lsp", "path", "snippets", "buffer", "omni" },
      },
    },
  },
  {
    "nvim-treesitter/nvim-treesitter",
    opts = {
      ensure_installed = {
        "ledger",
      },
    },
  },
  {
    "mfussenegger/nvim-lint",
    opts = {
      events = { "BufWritePost", "BufReadPost", "InsertLeave" },
      linters_by_ft = {
        ledger = { "hledger" },
      },
      linters = {},
    },
  },
  {
    "stevearc/conform.nvim",
    opts = {
      formatters_by_ft = {
        ledger = { "trim_newlines", "trim_whitespace" },
      },
    },
  },
}

Comments of my configuration:

  • I use vim-ledger plugin because it provides alignment (:LedgerAlign and :LedgerAlignBuffer commands) and ommicompletion for accounts and descriptions.
  • I configure the blink.cmp completion plugin of lazyvim to use ommnicompletion provided by vim-ledger.
  • I configure the nvim-treesitter treesitter plugin of lazyvim to download the ledger grammar to have syntax highlighting and folding.
  • I configure the nvim-lint linter plugin of lazyvim to apply the hledger linter to ledger files.
  • I configure the conform.nvim formatter plugin of lazyvim to trim newlines and whitespaces of my ledger files.

Other comments:

  • The completion is done by the old vim-ledger plugin and I did not find any more recent completion plugin.
  • I would like a more powerful formatter for hledger files which would provide also alignment and sorting of transactions apart from trims of newlines and whitespaces. For example, conform.nvim uses bean-format for beancount files.
  • I did not find a way to sort transactions by date. I would have to do it manually.
2 Likes

One minor change to $HOME/.config/nvim/lua/plugins/hledger.lua:

return {
  {
    "ledger/vim-ledger",
    version = false,
    ft = "ledger",
    init = function()
      vim.g.ledger_bin = "hledger"
      vim.g.ledger_fuzzy_account_completion = 1
      vim.g.ledger_date_format = "%Y-%m-%d"
      vim.g.ledger_align_at = 70
      vim.cmd([[
        function LedgerSort() range
          execute a:firstline .. ',' .. a:lastline .. '! hledger -f - -I print'
          execute a:firstline .. ',' .. a:lastline .. 's/^    /  /g'
          execute a:firstline .. ',' .. a:lastline .. 'LedgerAlign'
        endfunction
        command -range LedgerSort :<line1>,<line2>call LedgerSort()
      ]])
    end,
    opt = {},
  },
  {
    "saghen/blink.cmp",
    opts = {
      sources = {
        compat = {},
        default = { "lsp", "path", "snippets", "buffer", "omni" },
      },
    },
  },
  {
    "nvim-treesitter/nvim-treesitter",
    opts = {
      ensure_installed = {
        "ledger",
      },
    },
  },
  {
    "mfussenegger/nvim-lint",
    opts = {
      events = { "BufWritePost", "BufReadPost", "InsertLeave" },
      linters_by_ft = {
        ledger = { "hledger" },
      },
      linters = {},
    },
  },
  {
    "stevearc/conform.nvim",
    opts = {
      formatters_by_ft = {
        ledger = { "trim_newlines", "trim_whitespace" },
      },
    },
  },
}

Changelog:

  • New :LedgerSort vim command to be executed in visual mode once selected the transactions you want to sort by date.

Ideas:

  • It would be great to have one hledger-format CLI command to be able to integrate with nvim formatter plugins such as conform.nvim and so automatically format the hledger file when it is written. This command should trim whitespace, newlines, align post and sort transactions by date.
  • It would be great to add completion capabilities to blink.cmp for descriptions (hledger description) and for accounts (hledger accounts)
  • With completion capabilities in blink.cmp and format capabilities in conform.nvim the plugin vim-ledger would not be required. Nvim would be sufficient to edit easily hledger files (completion, treesitter, linter and formatter) and one terminal hledger command could be use to reconcile and run commands.

For the format command, you could use hledger print and replace the entire buffer.

AFAIK hledger print nowadays it not a file formatter. It could be, but it is not now AFAIK:

  • it only prints the transactions sorted by date. So, If I apply it to the entire buffer, we lost everything of the file that are not transactions: definitions of accounts, commodities and others; comments...
  • The format of transacitons and postings is not customizable AFAIK. The number of spaces for tabs and the alignment of the ammount at the right.

That is the reason I use the :LedgerSort command in vim:

  • First, I select in Visual Mode the transactions I want to sort by date. Not the entire file/buffer.
  • Second, the command :LedgerSort does three operations:
    • hledger print to sort by date the transactions
    • regex to replace tabs of 4 spaces by 2 spaces
    • :LedgerAlign command of vim-ledger plugin to align ammounts at the right