akinsho / toggleterm.nvim

A neovim lua plugin to help easily manage multiple terminal windows
GNU General Public License v3.0
4.06k stars 170 forks source link

feat: Bracketed Paste for Terminal Line Sending #591

Open 001ben opened 4 weeks ago

001ben commented 4 weeks ago

This PR adds bracketed paste functionality to the terminal line sending feature, particularly beneficial for REPLs of whitespace-sensitive languages like Python. For additional context, please see conrad irwin's blog page: https://cirw.in/blog/bracketed-paste

Problem

When sending multiple lines of code to a REPL (like IPython), the default behavior can lead to incorrect execution due to inconsistent indentation or premature code evaluation.

For example, a function with whitespace partway through will execute before reading the rest of the function.

def my_function():
    print("This is the first part")

    print("This is the second part")

    return "Done"

# Without bracketed paste, this might execute prematurely after the first print statement

Solution

Implemented bracketed paste mode for sending lines to the terminal. This approach wraps the sent text in special escape sequences, signaling the receiving program to treat the input as a single paste operation.

Key benefits:

Implementation Details

Usage

Users can enable bracketed paste mode when sending lines to the terminal:

require('toggleterm').setup({})

-- In your keymaps or wherever you call send_lines_to_terminal
require('toggleterm').send_lines_to_terminal(
  "visual",  -- or "current" or "line"
  true,      -- trim_spaces
  {},        -- cmd_data (empty table if not needed)
  true       -- use_bracketed_paste
)

This allows users to selectively use bracketed paste mode when needed, while maintaining compatibility with existing configurations.

The current "Sending lines to the terminal" docs example would be updated from:

    local trim_spaces = true
    vim.keymap.set("v", "<space>s", function()
        require("toggleterm").send_lines_to_terminal("single_line", trim_spaces, { args = vim.v.count })
    end)

to

    local trim_spaces = true
    local use_bracketed_paste = true
    vim.keymap.set("v", "<space>s", function()
        require("toggleterm").send_lines_to_terminal("single_line", trim_spaces, { args = vim.v.count }, use_bracketed_paste)
    end)

Impact

This enhancement significantly improves the user experience when working with REPLs, particularly for languages like Python, where indentation is crucial. It allows for more reliable and predictable code execution within the Neovim terminal integration.

Testing

All feedback is welcome!