Skip to content
Merged
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
12 changes: 6 additions & 6 deletions doc/python.txt
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ Parameters ~
Class ~
{PythonStateVEnv}
Fields ~
{python_interpreter} `(string | nil)`
{venv_path} `(string | nil)`
{python_interpreter} `(string)`
{venv_path} `(string)`
{install_method} `(string)`
{install_file} `(string)`
{source} `(string)`
Expand All @@ -320,14 +320,14 @@ Fields ~
{dap} `(table<string, dap.Configuration>)`

------------------------------------------------------------------------------
*PythonState.State()*
`PythonState.State`()
*PythonStateM.State()*
`PythonStateM.State`()
Return ~
`(PythonState)`

------------------------------------------------------------------------------
*PythonState.save()*
`PythonState.save`({new_state})
*PythonStateM.save()*
`PythonStateM.save`({new_state})
Parameters ~
{new_state} `(PythonState)`

Expand Down
4 changes: 2 additions & 2 deletions doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ PythonConfig.setup() python.txt /*PythonConfig.setup()*
PythonDap.prepare_debugpy() python.txt /*PythonDap.prepare_debugpy()*
PythonLSPCommands.pyright_change_type_checking() python.txt /*PythonLSPCommands.pyright_change_type_checking()*
PythonState python.txt /*PythonState*
PythonState.State() python.txt /*PythonState.State()*
PythonState.save() python.txt /*PythonState.save()*
PythonStateDap python.txt /*PythonStateDap*
PythonStateM.State() python.txt /*PythonStateM.State()*
PythonStateM.save() python.txt /*PythonStateM.save()*
PythonStateVEnv python.txt /*PythonStateVEnv*
PythonTreeSitterCommands.ts_wrap_at_cursor() python.txt /*PythonTreeSitterCommands.ts_wrap_at_cursor()*
PythonUI.activate_system_call_ui() python.txt /*PythonUI.activate_system_call_ui()*
Expand Down
10 changes: 8 additions & 2 deletions lua/python/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,12 @@ local subcommand_tbl = {
end

if command == "wrap_cursor" then
ts_cmd.ts_wrap_at_cursor(args[#args])
-- Account for if the last argument is the command or an actual arg
local wrap_arg = args[#args]
if wrap_arg == "wrap_cursor" then
wrap_arg = ""
end
ts_cmd.ts_wrap_at_cursor(wrap_arg)
return
end
end,
Expand Down Expand Up @@ -289,7 +294,7 @@ function PythonCommands.load_commands()
-- NOTE: the options will vary, based on your use case.
vim.api.nvim_create_user_command("Python", python_cmd, {
nargs = "+",
desc = "My awesome command with subcommand completions",
desc = "Python.nvim commands",
complete = function(arg_lead, cmdline, _)
-- Get the subcommand.
local subcmd_key, subcmd_arg_lead = cmdline:match("^['<,'>]*Python[!]*%s(%S+)%s(.*)$")
Expand All @@ -310,6 +315,7 @@ function PythonCommands.load_commands()
end
end,
bang = true, -- If you want to support ! modifiers
range = true, -- Support some visual command
})
end

Expand Down
85 changes: 62 additions & 23 deletions scripts/minimal_init.lua
Original file line number Diff line number Diff line change
@@ -1,28 +1,67 @@
-- Add current directory to 'runtimepath' to be able to use 'lua' files
vim.cmd([[let &rtp.=','.getcwd()]])

-- Set up 'mini.test' only when calling headless Neovim (like with `make test`)
if #vim.api.nvim_list_uis() == 0 then
-- Add 'mini.nvim' to 'runtimepath' to be able to use 'mini.test'
-- Assumed that 'mini.nvim' is stored in 'deps/mini.nvim'
--
local runtime_dependencies = {
"deps/mini.nvim",
"deps/nvim-treesitter",
"deps/neotest",
"deps/neotest-python",
"deps/nvim-dap",
"deps/nvim-dap-python",
"deps/nvim-lspconfig",
"deps/LuaSnip",
}
local runtime_path = vim.fn.join(runtime_dependencies, ",")
vim.cmd("set rtp+=" .. runtime_path)
local runtime_dependencies = {
"deps/mini.nvim",
"deps/nvim-treesitter",
"deps/neotest",
"deps/neotest-python",
"deps/nvim-dap",
"deps/nvim-dap-python",
"deps/nvim-lspconfig",
"deps/LuaSnip",
}
local runtime_path = vim.fn.join(runtime_dependencies, ",")
vim.cmd("set rtp+=" .. runtime_path)

-- Set up 'mini.test'
require("luasnip.extras.fmt")
require("luasnip.nodes.absolute_indexer")
require("nvim-treesitter.locals")
require("mini.test").setup()
require("mini.doc").setup()
-- Set up 'mini.test'
require("luasnip.extras.fmt")
require("luasnip.nodes.absolute_indexer")
require("nvim-treesitter.locals")
require("nvim-treesitter").setup()
require("mini.test").setup()
require("mini.doc").setup()
local ts_configs = require("nvim-treesitter.configs").setup({
modules = {
"highlight",
},
sync_install = false,
auto_install = true,
ignore_install = {},
ensure_installed = {},
highlight = {
enable = true,
},
})

-- Clean path for use in a prefix comparison
---@param input string
---@return string
local function clean_path(input)
local pth = vim.fn.fnamemodify(input, ":p")
if vim.fn.has("win32") == 1 then
pth = pth:gsub("/", "\\")
end
return pth
end

local function ts_is_installed(lang)
local matched_parsers = vim.api.nvim_get_runtime_file("parser/" .. lang .. ".so", true) or {}
local configs = require("nvim-treesitter.configs")
local install_dir = configs.get_parser_install_dir()
if not install_dir then
return false
end
install_dir = clean_path(install_dir)
for _, path in ipairs(matched_parsers) do
local abspath = clean_path(path)
if vim.startswith(abspath, install_dir) then
return true
end
end
return false
end

if not ts_is_installed("python") then
vim.cmd("TSInstallSync python")
end
43 changes: 43 additions & 0 deletions tests/test_text_actions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
-- Define helper aliases
local new_set = MiniTest.new_set
local expect, eq = MiniTest.expect, MiniTest.expect.equality

-- Create (but not start) child Neovim object
local child = MiniTest.new_child_neovim()

-- Define main test set of this file
local T = new_set({
-- Register hooks
hooks = {
-- This will be executed before every (even nested) case
pre_case = function()
-- Restart child process with custom 'init.lua' script
child.restart({ "-u", "scripts/minimal_init.lua" })
-- Load tested plugin
child.lua([[require('python').setup()]])
end,
-- This will be executed one after all tests from this set are finished
post_once = child.stop,
},
})

local get_lines = function()
return child.api.nvim_buf_get_lines(0, 0, -1, true)
end

T["text_actions"] = MiniTest.new_set({
hooks = {
pre_case = function()
child.cmd("e _not_existing_new_buffer.py")
end,
},
})

T["text_actions"]["insert_f_string"] = function()
child.type_keys("i", [[print("{foo}")]], "<left><esc>")

eq(get_lines(), { [[print(f"{foo}")]] })
end

-- Return test set which will be collected and execute inside `MiniTest.run()`
return T
67 changes: 67 additions & 0 deletions tests/test_treesitter.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
-- Define helper aliases
local new_set = MiniTest.new_set
local expect, eq = MiniTest.expect, MiniTest.expect.equality

-- Create (but not start) child Neovim object
local child = MiniTest.new_child_neovim()

-- Define main test set of this file
local T = new_set({
-- Register hooks
hooks = {
-- This will be executed before every (even nested) case
pre_case = function()
-- Restart child process with custom 'init.lua' script
child.restart({ "-u", "scripts/minimal_init.lua" })
-- Load tested plugin
child.lua([[require('python').setup()]])
end,
-- This will be executed one after all tests from this set are finished
post_once = child.stop,
},
})

local get_lines = function()
return child.api.nvim_buf_get_lines(0, 0, -1, true)
end

T["wrap_cursor"] = MiniTest.new_set({
hooks = {
pre_case = function()
child.cmd("e _not_existing_new_buffer.py")
child.type_keys("cc", [["TEST"]], "<Esc>", "0")
end,
},
})

T["wrap_cursor"]["normal"] = function()
child.cmd("Python treesitter wrap_cursor test(%s)")
eq(get_lines(), { [[test("TEST")]] })
end

T["wrap_cursor"]["visual"] = function()
child.type_keys("l", "v", "$")
child.type_keys([[:Python treesitter wrap_cursor test(%s)<cr>]])
eq(get_lines(), { [["test(TEST")]] })
end

T["wrap_cursor"]["visual_with_selection"] = function()
child.type_keys("l", "v", "$")
child.type_keys([[:Python treesitter wrap_cursor<cr>1<cr>]])
eq(get_lines(), { [["print(TEST")]] })
end

T["wrap_cursor"]["with_selection"] = function()
child.type_keys([[:Python treesitter wrap_cursor<cr>1<cr>]])
eq(get_lines(), { [[print("TEST")]] })
end

T["enumerate"] = function()
child.cmd("e _not_existing_new_buffer.py")
child.type_keys("cc", "for i in [1, 2, 3]:", "<Esc>", "0")
child.type_keys([[:Python treesitter toggle_enumerate<cr>]])
eq(get_lines(), { "for idx, i in enumerate([1, 2, 3]):" })
end

-- Return test set which will be collected and execute inside `MiniTest.run()`
return T
Loading