Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ iron.setup {
command = { "python3" }, -- or { "ipython", "--no-autoindent" }
format = common.bracketed_paste_python,
block_dividers = { "# %%", "#%%" },
env = {PYTHON_BASIC_REPL = "1"} --this is needed for python3.13 and up.
is_new_repl = true -- this must be set to true for Python 3.13 and later.
}
},
-- set the file type of the newly created repl to ft
Expand Down
18 changes: 17 additions & 1 deletion lua/iron/fts/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local is_windows = require("iron.util.os").is_windows
local extend = require("iron.util.tables").extend
local open_code = "\27[200~"
local close_code = "\27[201~"
local paste_mode_code = "\x1bOR"
local cr = "\13"

local common = {}
Expand Down Expand Up @@ -58,7 +59,11 @@ common.format = function(repldef, lines)

-- passing the command is for python. this will not affect bracketed_paste.
if repldef.format then
return repldef.format(lines, { command = repldef.command })
if repldef.is_new_repl then
return repldef.format(lines, { command = repldef.command, is_new_repl = repldef.is_new_repl })
else
return repldef.format(lines, { command = repldef.command })
end
elseif #lines == 1 then
new = lines
else
Expand Down Expand Up @@ -98,6 +103,7 @@ common.bracketed_paste_python = function(lines, extras)
local result = {}

local cmd = extras["command"]
local is_new_repl = extras["is_new_repl"] or false
local pseudo_meta = { current_buffer = vim.api.nvim_get_current_buf()}
if type(cmd) == "function" then
cmd = cmd(pseudo_meta)
Expand Down Expand Up @@ -153,6 +159,16 @@ common.bracketed_paste_python = function(lines, extras)
table.insert(result, "\n")
end

-- In Python 3.13 and later, the built-in REPL automatically
-- adjusts indentation based on contextual information when
-- a new line is entered. This behavior may cause unexpected
-- indentation errors in some cases. Fortunately, the new
-- REPL provides a Paste Mode, which disables automatic
-- indentation and allows code to run smoothly.
if is_new_repl and not (is_windows and result[1] and result[1] == "\r") then
table.insert(result, 1, paste_mode_code)
end

return result
end

Expand Down
14 changes: 14 additions & 0 deletions lua/iron/lowlevel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ local fts = require("iron.fts")
local providers = require("iron.providers")
local format = require("iron.fts.common").format
local view = require("iron.view")
local paste_mode_code = "\x1bOR"

--- Low level functions for iron
-- This is needed to reduce the complexity of the user API functions.
Expand Down Expand Up @@ -186,6 +187,19 @@ ll.send_to_repl = function(meta, data)
--TODO tool to get the progress of the chan send function
vim.fn.chansend(meta.job, dt)

-- In Python 3.13 and later, the built-in REPL automatically
-- adjusts indentation based on contextual information when
-- a new line is entered. This behavior may cause unexpected
-- indentation errors in some cases. Fortunately, the new
-- REPL provides a Paste Mode, which disables automatic
-- indentation and allows code to run smoothly.
if dt[1] and string.find(dt[1], paste_mode_code) then
vim.defer_fn(function()
vim.fn.chansend(meta.job, paste_mode_code .. "\r")
end, 200)
end


if window ~= -1 then
vim.api.nvim_win_set_cursor(window, {vim.api.nvim_buf_line_count(meta.bufnr), 0})
end
Expand Down