commands.lua
1 local controller = require("cellmode.runtime.controller") 2 local session_store = require("cellmode.runtime.session_store") 3 local cell_layout = require("cellmode.view.cell_layout") 4 local runtime_autocmd = require("cellmode.runtime.autocmd") 5 local runtime_config = require("cellmode.config") 6 local messages = require("cellmode.runtime.messages") 7 8 local M = {} 9 10 local api = vim.api 11 12 local function split_csv(value) 13 local parts = vim.split(value or "", ",", { plain = true }) 14 local out = {} 15 for index = 1, #parts do 16 out[index] = vim.trim(parts[index]) 17 end 18 return out 19 end 20 21 local function cmd_open(bufnr, fargs) 22 local path = fargs[2] 23 local format = fargs[3] 24 if not path or not format then 25 return false, "usage: Cellmode open <path> <csv|tsv>" 26 end 27 vim.cmd("edit " .. vim.fn.fnameescape(path)) 28 bufnr = api.nvim_get_current_buf() 29 if session_store.get(bufnr) then 30 return true 31 end 32 local ok, err = controller.open(bufnr, { format = format }) 33 if not ok then 34 return false, err 35 end 36 runtime_autocmd.attach_buffer_tracking(bufnr) 37 return true 38 end 39 40 local function cmd_op(bufnr, fargs) 41 local op = fargs[2] 42 if op == "set-cell" then 43 local row = tonumber(fargs[3]) 44 local col = tonumber(fargs[4]) 45 local value = table.concat(vim.list_slice(fargs, 5), " ") 46 if not row or not col then 47 return false, "usage: Cellmode op set-cell <row> <col> <value>" 48 end 49 return controller.set_cell(bufnr, row, col, value) 50 elseif op == "insert-row" then 51 local row = tonumber(fargs[3]) 52 local values = split_csv(table.concat(vim.list_slice(fargs, 4), " ")) 53 if not row then 54 return false, "usage: Cellmode op insert-row <row> <value1,value2,...>" 55 end 56 return controller.insert_row(bufnr, row, values) 57 elseif op == "delete-row" then 58 local row = tonumber(fargs[3]) 59 if not row then 60 return false, "usage: Cellmode op delete-row <row>" 61 end 62 return controller.delete_row(bufnr, row) 63 end 64 return false, "usage: Cellmode op <set-cell|insert-row|delete-row> ..." 65 end 66 67 local function cmd_status(bufnr) 68 local session = session_store.get(bufnr) 69 if not session then 70 messages.info("no active session") 71 return true 72 end 73 local layout = cell_layout.get(bufnr) 74 local rec_count = layout and #layout.records or 0 75 local col_count = layout and #(layout.widths or {}) or 0 76 local visible = session.overlay_visible ~= false 77 messages.info(string.format( 78 "format=%s records=%d columns=%d overlay=%s", 79 session.format, 80 rec_count, 81 col_count, 82 visible and "on" or "off" 83 )) 84 return true 85 end 86 87 local function cmd_toggle(bufnr) 88 return controller.toggle_overlay(bufnr) 89 end 90 91 local function cmd_save(bufnr, fargs) 92 local _ = fargs 93 vim.api.nvim_buf_call(bufnr, function() 94 vim.cmd("write") 95 end) 96 return true 97 end 98 99 function M.exec(opts) 100 local fargs = opts.fargs 101 local action = fargs[1] 102 local bufnr = api.nvim_get_current_buf() 103 if not action then 104 return false, "usage: Cellmode <open|op|toggle|status|save> ..." 105 end 106 if action == "open" then 107 return cmd_open(bufnr, fargs) 108 elseif action == "op" then 109 return cmd_op(bufnr, fargs) 110 elseif action == "toggle" then 111 return cmd_toggle(bufnr) 112 elseif action == "status" then 113 return cmd_status(bufnr) 114 elseif action == "save" then 115 return cmd_save(bufnr, fargs) 116 end 117 return false, "unknown action: " .. action 118 end 119 120 function M.setup() 121 pcall(api.nvim_del_user_command, runtime_config.command) 122 api.nvim_create_user_command(runtime_config.command, function(opts) 123 local ok, message = M.exec(opts) 124 if not ok then 125 messages.error(message) 126 end 127 end, { 128 nargs = "*", 129 complete = function() 130 return { "open", "op", "toggle", "status", "save" } 131 end, 132 }) 133 end 134 135 return M