nvim/ftplugin/python.lua
Jeremie Fraeys d79c9ce5dc
Some checks failed
Luacheck / luacheck (push) Successful in 11s
StyLua / stylua (push) Failing after 2s
fix: resolve luacheck warnings - Terminal scope and unused function
2026-02-08 15:15:17 -05:00

152 lines
4.3 KiB
Lua

-- Set buffer-local options for Python files
vim.opt_local.expandtab = true -- Use spaces instead of tabs
vim.opt_local.commentstring = '# %s' -- Python comment format
vim.opt_local.shiftwidth = 4 -- Indent width
vim.opt_local.tabstop = 4 -- Tab width
vim.opt_local.softtabstop = 4 -- Soft tab width for alignment
vim.opt_local.fileformat = 'unix' -- Use Unix line endings
vim.opt_local.textwidth = 79 -- Maximum text width
vim.opt_local.colorcolumn = '80' -- Highlight column 80
local dap = require('dap')
local function get_python_path()
local cwd = vim.fn.getcwd()
if vim.env.VIRTUAL_ENV then
return vim.env.VIRTUAL_ENV .. '/bin/python' -- Use virtual environment if set
elseif vim.fn.executable(cwd .. '/venv/bin/python') == 1 then
return cwd .. '/venv/bin/python' -- Use project-specific venv
elseif vim.fn.executable(cwd .. '/.venv/bin/python') == 1 then
return cwd .. '/.venv/bin/python' -- Use hidden project venv
else
return 'python' -- Fallback to system Python
end
end
local function get_ipython_cmd()
local cwd = vim.fn.getcwd()
local venv = vim.env.VIRTUAL_ENV
if not venv then
if vim.fn.isdirectory(cwd .. '/.venv') == 1 then
venv = cwd .. '/.venv'
elseif vim.fn.isdirectory(cwd .. '/venv') == 1 then
venv = cwd .. '/venv'
end
end
if venv and vim.fn.executable(venv .. '/bin/ipython') == 1 then
return vim.fn.shellescape(venv .. '/bin/ipython')
end
local py = get_python_path()
if py:find('/') then
py = vim.fn.shellescape(py)
end
return py .. ' -m IPython'
end
-- luacheck: ignore
local _unused_get_ipython_cmd = get_ipython_cmd
local function get_ipython_argv()
local cwd = vim.fn.getcwd()
local venv = vim.env.VIRTUAL_ENV
if not venv then
if vim.fn.isdirectory(cwd .. '/.venv') == 1 then
venv = cwd .. '/.venv'
elseif vim.fn.isdirectory(cwd .. '/venv') == 1 then
venv = cwd .. '/venv'
end
end
if venv and vim.fn.executable(venv .. '/bin/ipython') == 1 then
return { venv .. '/bin/ipython' }
end
return { get_python_path(), '-m', 'IPython' }
end
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('lsp_attach_disable_ruff_hover', { clear = true }),
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client and client.name == 'ruff' then
client.server_capabilities.hoverProvider = false
end
end,
desc = 'Disable hover capability from Ruff',
})
require('dap-python').setup(get_python_path())
dap.configurations.python = {
{
type = 'python',
request = 'launch',
name = 'Launch Program',
program = '${file}',
console = 'integratedTerminal',
},
{
type = 'python',
request = 'launch',
name = 'Profile Memory',
program = '${file}',
args = { '--profile-memory' },
},
}
vim.keymap.set('n', '<leader>Rr', function()
local screen_width_percentage = 25
local function find_terminal_buffer()
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
if
vim.api.nvim_buf_is_loaded(bufnr)
and vim.bo[bufnr].buftype == 'terminal'
and vim.b[bufnr].python_repl == true
then
return bufnr
end
end
return nil
end
local function toggle_terminal_window(bufnr)
for _, win in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_get_buf(win) == bufnr then
vim.api.nvim_win_hide(win)
return
end
end
vim.cmd('vsplit')
vim.api.nvim_win_set_buf(0, bufnr)
vim.cmd.wincmd('L')
vim.api.nvim_win_set_width(0, math.floor(vim.o.columns / (100 / screen_width_percentage)))
end
local function create_terminal()
vim.cmd('vnew')
vim.cmd.wincmd('L')
vim.api.nvim_win_set_width(0, math.floor(vim.o.columns / (100 / screen_width_percentage)))
vim.b.python_repl = true
local job_id = vim.fn.termopen(get_ipython_argv())
if job_id and job_id > 0 then
vim.g.slime_default_config = { jobid = job_id }
end
vim.cmd('startinsert')
end
local term_bufnr = find_terminal_buffer()
if term_bufnr then
local job_id = vim.b[term_bufnr].terminal_job_id
if job_id and job_id > 0 then
vim.g.slime_default_config = { jobid = job_id }
end
toggle_terminal_window(term_bufnr)
else
create_terminal()
end
end, { desc = 'Run/REPL: Toggle Python REPL' })