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: 2 additions & 0 deletions ftplugin/matlab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ map(prefix .. (mappings.clear_workspace or 'x'), 'MatlabClearWorkspace', 'MATLAB
map(prefix .. (mappings.toggle_cell_fold or 'f'), 'MatlabToggleCellFold', 'MATLAB: Toggle cell fold')
map(prefix .. (mappings.open_in_gui or 'g'), 'MatlabOpenInGUI', 'MATLAB: Open in GUI')
map(prefix .. (mappings.run_tests or 'T'), 'MatlabRunTests', 'MATLAB: Run all tests')
map(prefix .. (mappings.run_current_test or 't'), 'MatlabRunCurrentTest', 'MATLAB: Run current test')

-- ============================================================================
-- Debug Commands (<Leader>md + key)
Expand Down Expand Up @@ -78,6 +79,7 @@ vim.api.nvim_buf_create_user_command(0, 'MatlabKeymaps', function()
' ' .. p .. 'f - Toggle cell fold',
' ' .. p .. 'g - Open in GUI',
' ' .. p .. 'T - Run all tests',
' ' .. p .. 't - Run current test',
'',
'Debug (' .. dp .. ' + key):',
' ' .. dp .. 's - Start debug',
Expand Down
95 changes: 95 additions & 0 deletions lua/matlab/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,101 @@ function M.run_tests()
tmux.run('runtests(pwd)')
end

-- Run the test at cursor
function M.run_current_test()
if not tmux.exists() then
return
end

-- Ensure we are in a MATLAB buffer
if not M.is_matlab_script() then
return
end

-- Try to get the parser for the current buffer
local has_parser, parser = pcall(vim.treesitter.get_parser, 0, "matlab")
if not has_parser or not parser then
vim.notify('MATLAB Tree-sitter parser not found. Please run :TSInstall matlab', vim.log.levels.ERROR)
return
end

-- Get the root of the tree
local tree = parser:parse()[1]
local root = tree:root()

-- Get the node at the cursor
local cursor = vim.api.nvim_win_get_cursor(0)
local row, col = cursor[1] - 1, cursor[2]
local node = root:named_descendant_for_range(row, col, row, col)

if not node then
vim.notify('No syntax node found at cursor position.', vim.log.levels.WARN)
return
end

local function_name = nil
local class_name = nil

-- Traverse up to find Function or Class definition
local curr = node
while curr do
local type = curr:type()
if type == "function_definition" then
-- In many parsers, name is a field. We can use field() to check.
-- However, iterating children and checking their field name is safer
-- for different parser versions.
for child, field in curr:iter_children() do
if field == "name" then
function_name = vim.treesitter.get_node_text(child, 0)
break
end
end
-- Fallback if field "name" wasn't found (though it should be)
if not function_name then
for child in curr:iter_children() do
if child:type() == "identifier" then
function_name = vim.treesitter.get_node_text(child, 0)
break
end
end
end
elseif type == "classdef" then
for child, field in curr:iter_children() do
if field == "name" then
class_name = vim.treesitter.get_node_text(child, 0)
break
end
end
end
curr = curr:parent()
end

local test_cmd = nil
local filename = M.get_filename()

if function_name then
-- It's a method or a function
if class_name then
-- Class-based test
test_cmd = string.format("runtests('%s/%s')", class_name, function_name)
else
-- Function-based test (or just a local function in a test file)
test_cmd = string.format("runtests('%s/%s')", filename, function_name)
end
elseif class_name then
-- Just the class
test_cmd = string.format("runtests('%s')", class_name)
else
-- Fallback to running the whole file as a test
test_cmd = string.format("runtests('%s')", filename)
end

if test_cmd then
vim.notify('Running test: ' .. test_cmd, vim.log.levels.INFO)
tmux.run(test_cmd)
end
end

-- Show documentation for the word under cursor
function M.doc()
if not tmux.exists() then
Expand Down
1 change: 1 addition & 0 deletions lua/matlab/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ M.defaults = {
toggle_cell_fold = 'f', -- <Leader>mf - Toggle cell fold
open_in_gui = 'g', -- <Leader>mg - Open in MATLAB GUI
run_tests = 'T', -- <Leader>mT - Run all tests
run_current_test = 't', -- <Leader>mt - Run current test

-- Debug commands (<Leader>md + key)
debug_prefix = 'd', -- Makes <Leader>md the debug prefix
Expand Down
4 changes: 4 additions & 0 deletions lua/matlab/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ function M.setup(opts)
commands.run_tests()
end, {})

vim.api.nvim_create_user_command('MatlabRunCurrentTest', function()
commands.run_current_test()
end, {})

-- Cell execution commands
vim.api.nvim_create_user_command('MatlabRunCell', function()
cells.execute_current_cell()
Expand Down