/ lua / cellmode / runtime / commands.lua
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