Skip to content

Intelligent paste for Python - automatically adjusts indentation to match the current context.

Notifications You must be signed in to change notification settings

ZreXoc/smart-paste.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

smart-paste.nvim

Intelligent paste for Python - automatically adjusts indentation to match the current context.

Features

  • Smart indentation - Automatically adjusts pasted code to match context
  • Treesitter support - AST-based indentation detection with intelligent fallback
  • Dual usage modes - Toggle mode OR bind custom keys with parameters
  • Vim registers - Uses Vim's default register, integrates seamlessly with yy/p
  • File indent detection - Auto-detect the indentation width of the current file

Quick Start

Installation

Install with your plugin manager. Example for lazy.nvim:

{
    "ZreXoc/smart-paste.nvim",
    ft = "python",
    opts = {},
}

Two Usage Modes

Mode 1: Toggle Mode (Default)

  1. Enable smart paste: <leader>pt or :SmartPasteToggle
  2. Copy code: yy
  3. Paste: p or P (works in smart mode)
  4. Toggle off when not needed: <leader>pt

Mode 2: Custom Bindings Create dedicated keymaps for specific behaviors:

-- Smart paste with 8-space indent
vim.keymap.set("n", "<leader>p8", function()
    require("smart-paste").paste({ indent_width = 8 })
end)

-- Smart paste from clipboard
vim.keymap.set("n", "<leader>p+", function()
    require("smart-paste").paste({ register = "+" })
end)

-- Smart paste (fallback mode)
vim.keymap.set("n", "<leader>pf", function()
    require("smart-paste").paste({ use_treesitter = false })
end)

Both modes can be used together - toggle for quick smart paste, or use custom bindings for specific needs.

Indentation Detection

Treesitter Mode (Default)

When available, the plugin uses Treesitter to analyze the AST (Abstract Syntax Tree) of your Python code:

  • Analyzes code structure (class, function, if, for, while, etc.)
  • Detects nested blocks with high precision
  • Handles edge cases like class methods and nested functions

Fallback Mode

When Treesitter is not available or explicitly disabled, the plugin uses a simple but reliable fallback:

  • Finds the previous non-empty, non-comment line above the cursor
  • Uses that line's indentation as the target level
  • Works without any external dependencies

Use fallback mode if:

  • You want faster performance
  • Treesitter is not installed
  • You prefer simpler detection logic

Enable fallback mode:

require("smart-paste").paste({ use_treesitter = false })

File Indentation Detection

Auto-detect the indentation width used in the current file:

-- Command line
:lua print(require("smart-paste.indent").detect_file_indent())

-- In a custom command
vim.api.nvim_create_user_command("DetectIndent", function()
    local indent = require("smart-paste.indent").detect_file_indent()
    if indent then
        vim.notify("File indent: " .. indent .. " spaces")
    else
        vim.notify("Could not detect indentation")
    end
end)

Commands

Command Action
:SmartPasteToggle Toggle between smart and default mode
:SmartPasteEnable Enable smart paste
:SmartPasteDisable Disable smart paste
:SmartPasteStatus Show current status

Configuration

require("smart-paste").setup({
    enabled = false,           -- Disabled by default
    indent_width = 4,          -- Indentation width in spaces
    indent_char = " ",         -- Indentation character
    use_treesitter = true,     -- Use Treesitter when available
    register = '"',            -- Vim register to use
    debug = false,             -- Debug output
    keymaps = {
        toggle = "<leader>pt", -- Toggle shortcut
    },
})

API Reference

require("smart-paste").paste(opts)

Execute smart paste with optional parameters.

Parameters:

{
    mode = "p",              -- 'p' (after cursor) or 'P' (before cursor)
    register = '"',          -- Register: '"' (unnamed), '+' (clipboard), 'a'-'z' (named)
    indent_width = 4,        -- Override global indent width
    tabwidth = 4,            -- Alias for indent_width
    use_treesitter = true,   -- Use Treesitter for detection
    indent_char = " ",       -- Indentation character
    debug = false,           -- Enable debug output
}

Examples:

-- Basic paste
require("smart-paste").paste()

-- Custom indent width
require("smart-paste").paste({ indent_width = 8 })

-- From system clipboard
require("smart-paste").paste({ register = "+" })

-- Use fallback mode only
require("smart-paste").paste({ use_treesitter = false })

require("smart-paste").setup(opts)

Initialize the plugin with configuration options.

Other Functions

require("smart-paste").toggle()      -- Toggle smart/default mode
require("smart-paste").enable()      -- Enable smart mode
require("smart-paste").disable()     -- Disable smart mode
require("smart-paste").is_enabled()  -- Get current status (returns boolean)

Custom Keymaps

Add to your init.lua:

-- Custom indent widths
vim.keymap.set("n", "<leader>p4", function()
    require("smart-paste").paste({ indent_width = 4 })
end, { desc = "Smart paste (4-space)" })

vim.keymap.set("n", "<leader>p8", function()
    require("smart-paste").paste({ indent_width = 8 })
end, { desc = "Smart paste (8-space)" })

-- From system clipboard
vim.keymap.set("n", "<leader>p+", function()
    require("smart-paste").paste({ register = "+" })
end, { desc = "Smart paste from clipboard" })

-- Named registers
vim.keymap.set("n", "<leader>pa", function()
    require("smart-paste").paste({ register = "a" })
end, { desc = "Smart paste from register a" })

-- Fallback mode without Treesitter
vim.keymap.set("n", "<leader>pf", function()
    require("smart-paste").paste({ use_treesitter = false })
end, { desc = "Smart paste (fallback mode)" })

Custom Commands

vim.api.nvim_create_user_command("SmartPaste8", function()
    require("smart-paste").paste({ indent_width = 8 })
end, { desc = "Smart paste with 8-space indent" })

-- Usage: :SmartPaste8

How It Works

Indentation Detection

Treesitter Mode (default):

  • Analyzes the AST at the cursor position
  • Identifies code blocks (function, class, if/for/while, etc.)
  • Calculates indentation based on nesting level
  • More accurate and context-aware

Fallback Mode:

  • Finds the nearest non-empty, non-comment line above
  • Uses that line's indentation level
  • Simple and reliable, no dependencies

Indentation Adjustment

  1. Detects the base indentation of pasted content
  2. Calculates the difference (target - base)
  3. Applies adjustment to each line

File Indentation Detection

Detect the indentation width of the current file:

local indent = require("smart-paste.indent").detect_file_indent()
if indent then
    print("File uses " .. indent .. "-space indents")
end

Documentation

License

MIT

About

Intelligent paste for Python - automatically adjusts indentation to match the current context.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages