SkillAgentSearch skills...

Timber.nvim

Neovim plugin to quickly insert log statements and capture log output

Install / Use

/learn @Goose97/Timber.nvim
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

timber.nvim

Insert log statements blazingly fast and capture log results inline 🪵

https://github.com/user-attachments/assets/6bbcb1ab-45a0-45f3-a03a-1d0780219362

Table of contents

Features

  • Quickly insert log statements
    • Automatically capture the log targets and log position using Treesitter
    • Customizable log templates
  • Support batch log statements (multiple log target statements)
  • Dot-repeat actions
  • Support various languages:
    • Javascript (include JSX)
    • Typescript (include JSX)
    • Lua
    • Ruby
    • Elixir
    • Golang
    • Rust
    • Python
    • C
    • C++
    • Java
    • C#
    • Odin
    • Bash
    • Swift
    • Kotlin
    • Scala
    • Dart
    • Fallback for others

Requirements

  • Neovim 0.10+
  • [Recommended] nvim-treesitter: to support languages, users need to install appropriate Treesitter parsers. nvim-treesitter provides an easy interface to manage them.
  • [Optional] telescope.nvim: required for log statements search feature.

Installation

timber.nvim supports multiple plugin managers

<details> <summary><strong>lazy.nvim</strong></summary>
{
    "Goose97/timber.nvim",
    version = "*", -- Use for stability; omit to use `main` branch for the latest features
    event = "VeryLazy",
    config = function()
        require("timber").setup({
            -- Configuration here, or leave empty to use defaults
        })
    end
}
</details> <details> <summary><strong>packer.nvim</strong></summary>
use({
    "Goose97/timber.nvim",
    tag = "*", -- Use for stability; omit to use `main` branch for the latest features
    config = function()
        require("timber").setup({
            -- Configuration here, or leave empty to use defaults
        })
    end
})
</details> <details> <summary><strong>mini.deps</strong></summary>
local MiniDeps = require("mini.deps");

MiniDeps.add({
    source = "Goose97/timber.nvim",
})

require("timber").setup({
    -- Configuration here, or leave empty to use defaults
})
</details>

Setup

You will need to call require("timber").setup() to intialize the plugin. You can pass in a configuration table to customize the plugin.

<details> <summary><strong>Default configuration</strong></summary>
{
    log_templates = {
        default = {
            -- Templates with auto_import: when inserting a log statement, the import line is inserted automatically
            -- Applies to batch log statements as well
            -- javascript = {
            --   [[logger.info('hello world')]],
            --   auto_import = [[const logger = require('pino')()]]
            -- }
            javascript = [[console.log("%log_target", %log_target)]],
            typescript = [[console.log("%log_target", %log_target)]],
            astro = [[console.log("%log_target", %log_target)]],
            vue = [[console.log("%log_target", %log_target)]],
            jsx = [[console.log("%log_target", %log_target)]],
            tsx = [[console.log("%log_target", %log_target)]],
            lua = [[print("%log_target", %log_target)]],
            luau = [[print("%log_target", %log_target)]],
            ruby = [[puts("%log_target #{%log_target}")]],
            elixir = [[IO.inspect(%log_target, label: "%log_target")]],
            go = [[log.Printf("%log_target: %v\n", %log_target)]],
            rust = [[println!("%log_target: {:#?}", %log_target);]],
            python = [[print(f"{%log_target=}")]],
            c = [[printf("%log_target: %s\n", %log_target);]],
            cpp = [[std::cout << "%log_target: " << %log_target << std::endl;]],
            java = [[System.out.println("%log_target: " + %log_target);]],
            c_sharp = [[Console.WriteLine($"%log_target: {%log_target}");]],
            odin = [[fmt.printfln("%log_target: %v", %log_target)]],
            swift = [[print("%log_target:", %log_target)]],
            kotlin = [[println("%log_target: ${%log_target}")]],
            scala = [[println(s"%log_target: ${%log_target}")]],
            dart = [[print("%log_target: ${%log_target}");]],
        },
        plain = {
            javascript = [[console.log("%insert_cursor")]],
            typescript = [[console.log("%insert_cursor")]],
            astro = [[console.log("%insert_cursor")]],
            vue = [[console.log("%insert_cursor")]],
            jsx = [[console.log("%insert_cursor")]],
            tsx = [[console.log("%insert_cursor")]],
            lua = [[print("%insert_cursor")]],
            luau = [[print("%insert_cursor")]],
            ruby = [[puts("%insert_cursor")]],
            elixir = [[IO.puts(%insert_cursor)]],
            go = [[log.Printf("%insert_cursor")]],
            rust = [[println!("%insert_cursor");]],
            python = [[print(f"%insert_cursor")]],
            c = [[printf("%insert_cursor \n");]],
            cpp = [[std::cout << "%insert_cursor" << std::endl;]],
            java = [[System.out.println("%insert_cursor");]],
            c_sharp = [[Console.WriteLine("%insert_cursor");]],
            odin = [[fmt.println("%insert_cursor")]],
            swift = [[print("%insert_cursor")]],
            kotlin = [[println("%insert_cursor")]],
            scala = [[println("%insert_cursor")]],
            dart = [[print("%insert_cursor");]],
        },
    },
    batch_log_templates = {
        default = {
            javascript = [[console.log({ %repeat<"%log_target": %log_target><, > })]],
            typescript = [[console.log({ %repeat<"%log_target": %log_target><, > })]],
            astro = [[console.log({ %repeat<"%log_target": %log_target><, > })]],
            vue = [[console.log({ %repeat<"%log_target": %log_target><, > })]],
            jsx = [[console.log({ %repeat<"%log_target": %log_target><, > })]],
            tsx = [[console.log({ %repeat<"%log_target": %log_target><, > })]],
            lua = [[print(string.format("%repeat<%log_target=%s><, >", %repeat<%log_target><, >))]],
            luau = [[print(`%repeat<%log_target={%log_target}><, >`)]],
            ruby = [[puts("%repeat<%log_target: #{%log_target}><, >")]],
            elixir = [[IO.inspect({ %repeat<%log_target><, > })]],
            go = [[log.Printf("%repeat<%log_target: %v><, >\n", %repeat<%log_target><, >)]],
            rust = [[println!("%repeat<%log_target: {:#?}><, >", %repeat<%log_target><, >);]],
            python = [[print(f"%repeat<{%log_target=}><, >")]],
            c = [[printf("%repeat<%log_target: %s><, >\n", %repeat<%log_target><, >);]],
            cpp = [[std::cout %repeat<<< "%log_target: " << %log_target>< << "\n  " > << std::endl;]],
            java = [[System.out.printf("%repeat<%log_target=%s><, >%n", %repeat<%log_target><, >);]],
            c_sharp = [[Console.WriteLine($"%repeat<%log_target: {%log_target}><, >");]],
            odin = [[fmt.printfln("%repeat<%log_target: %v><, >", %repeat<%log_target><, >)]],
            swift = [[print("%repeat<%log_target: %log_target><, >")]],
            kotlin = [[println("%repeat<%log_target=${%log_target}><, >")]],
            scala = [[println(s"%repeat<%log_target=${%log_target}><, >")]],
            dart = [[print(s"%repeat<%log_target=${%log_target}><, >");]],
        },
    },
    template_placeholders = {
        filename = function()
          return vim.fn.expand("%:t")
        end,
        -- Custom placeholder. For example, this can be used in log templates as %truncated_line
        -- truncated_line = function(ctx)
        --   local line = ctx.log_target:start()
        --   return nvim_buf_get_lines(0, line - 1, line, false)[1]:sub(1, 16)
        -- end,
    },
    -- The string to search for when deleting or commenting log statements
    -- Can be used in log templates as %log_marker placeholder
    log_marker = "🪵",
    -- Controls the flash highlight
    highlight = {
        -- After a log statement is inserted
        on_insert = true,
        -- After a log target is added to a batch
        on_add_to_batch = true,
        -- After a log entry is shown/jumped to in the summary panel
        on_summary_show_entry = true,
        -- The duration of the flash highlight
        duration = 500,
    },
    keymaps = {
        -- Set to false to disable the default keymap for specific actions
        -- insert_log_below = false,
        insert_log_below = "glj",
        insert_log_above = "glk",
        insert_plain_log_below = "glo",
        insert_plain_log_above = "gl<S-o>",
        insert_batch_log = "glb",
        add_log_targets_to_batch = "gla",
        insert_log_below_operator = "g<S-l>j",
        insert_log_above_operator = "g<S-l>k",
        insert_batch_log_operator = "g<S-l>b",
        add_log_targets_to_batch_operator = "g<S-l>a",
    },
    -- Set to false to disable all default keymaps
    default_keymaps_enabled = true,
    log_watcher = {
        enabled = false,
        sources = {},
        -- The length of the preview snippet display as extmarks
        preview_snippet_length = 32,
    },
    log_summary = {
        -- Keymaps for the summary window
        keymaps = {
            -- Set to false to disable the default keymap for specific actions
            -- show_entry = false,
            show_entry = "<CR>",
            jump_to_entry = "o",
            next_entry = "]]",
            prev_entry = "[[",
            close = "q",
        },
        -- Set to false to disable all default keymaps in the summary window
        default_keymaps_enabled = true,
        -- Customize the summary window
        win = {
            -- Control the width of the summary window
            -- They can be a single integer (numbe
View on GitHub
GitHub Stars189
CategoryDevelopment
Updated1mo ago
Forks10

Languages

Lua

Security Score

100/100

Audited on Feb 20, 2026

No findings