diff --git a/README.md b/README.md index dec9057..5d5fb52 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/lua/iron/fts/common.lua b/lua/iron/fts/common.lua index e55b183..19fd965 100644 --- a/lua/iron/fts/common.lua +++ b/lua/iron/fts/common.lua @@ -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 = {} @@ -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 @@ -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) @@ -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 diff --git a/lua/iron/lowlevel.lua b/lua/iron/lowlevel.lua index 1588196..0ab209c 100644 --- a/lua/iron/lowlevel.lua +++ b/lua/iron/lowlevel.lua @@ -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. @@ -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