From 07e9496191653587336b4c8f8cab02e5c34c7c44 Mon Sep 17 00:00:00 2001 From: Will Hopkins Date: Mon, 31 Jul 2023 16:03:33 -0700 Subject: [PATCH] style: add stylua.toml, run stylua --- lua/flatten/core.lua | 321 +++++++++++++++++++++--------------------- lua/flatten/guest.lua | 227 ++++++++++++++--------------- lua/flatten/init.lua | 128 ++++++++--------- stylua.toml | 7 + 4 files changed, 336 insertions(+), 347 deletions(-) create mode 100644 stylua.toml diff --git a/lua/flatten/core.lua b/lua/flatten/core.lua index 242c0b3..e5cd9ed 100644 --- a/lua/flatten/core.lua +++ b/lua/flatten/core.lua @@ -1,22 +1,27 @@ local M = {} local function unblock_guest(guest_pipe) - local response_sock = vim.fn.sockconnect("pipe", guest_pipe, { rpc = true }) - vim.fn.rpcnotify(response_sock, "nvim_exec_lua", "vim.cmd.qa({ bang = true })", {}) - vim.fn.chanclose(response_sock) + local response_sock = vim.fn.sockconnect("pipe", guest_pipe, { rpc = true }) + vim.fn.rpcnotify( + response_sock, + "nvim_exec_lua", + "vim.cmd.qa({ bang = true })", + {} + ) + vim.fn.chanclose(response_sock) end local function notify_when_done(pipe, bufnr, callback, ft) - vim.api.nvim_create_autocmd({ "QuitPre", "BufUnload", "BufDelete" }, { - buffer = bufnr, - once = true, - group = M.augroup, - callback = function() - vim.api.nvim_del_augroup_by_id(M.augroup) - unblock_guest(pipe) - callback(ft) - end, - }) + vim.api.nvim_create_autocmd({ "QuitPre", "BufUnload", "BufDelete" }, { + buffer = bufnr, + once = true, + group = M.augroup, + callback = function() + vim.api.nvim_del_augroup_by_id(M.augroup) + unblock_guest(pipe) + callback(ft) + end, + }) end ---@class EditFilesOptions @@ -30,152 +35,150 @@ end ---@param opts EditFilesOptions ---@return boolean M.edit_files = function(opts) - local files = opts.files - local response_pipe = opts.response_pipe - local guest_cwd = opts.guest_cwd - local stdin = opts.stdin - local force_block = opts.force_block - local argv = opts.argv - local config = require("flatten").config - local callbacks = config.callbacks - local focus_first = config.window.focus == "first" - local open = config.window.open - - local nfiles = #files - local stdin_lines = #stdin - - --- commands passed through with +, to be executed after opening files - local postcmds = {} - - if nfiles == 0 and stdin_lines == 0 then - -- If there are no new bufs, don't open anything - -- and tell the guest not to block - return false - end - - local is_cmd = false - if config.allow_cmd_passthrough then - for _, arg in ipairs(argv) do - if is_cmd then - is_cmd = false - -- execute --cmd commands - if vim.api.nvim_exec2 then - -- nvim_exec2 only exists in nvim 0.9+ - vim.api.nvim_exec2(arg, {}) - else - vim.api.nvim_exec(arg, false) - end - elseif arg:sub(1, 1) == "+" then - local cmd = string.sub(arg, 2, -1) - table.insert(postcmds, cmd) - elseif arg == "--cmd" then - -- next arg is the actual command - is_cmd = true - end - end - end - - callbacks.pre_open() - - -- Open files - if nfiles > 0 then - local argstr = "" - for i, fname in ipairs(files) do - local is_absolute = string.find(fname, "^/") - local fpath = vim.fn.fnameescape(is_absolute and fname or (guest_cwd .. "/" .. fname)) - files[i] = fpath - if argstr == "" or argstr == nil then - argstr = fpath - else - argstr = argstr .. " " .. fpath - end - end - -- Hack to work around https://github.com/vim/vim/issues/4610 - local wildignore = vim.o.wildignore - vim.o.wildignore = "" - vim.cmd("0argadd " .. argstr) - vim.o.wildignore = wildignore - end - - -- Create buffer for stdin pipe input - local stdin_buf = nil - if stdin_lines > 0 then - -- Create buffer for stdin - stdin_buf = vim.api.nvim_create_buf(true, false) - -- Add text to buffer - vim.api.nvim_buf_set_lines(stdin_buf, 0, 0, true, stdin) - -- Set buffer name based on the first line of stdin - local name = stdin[1]:sub(1, 12):gsub("[^%w%.]", "") - -- Ensure the name isn't empty or a duplicate - if vim.fn.bufname(name) ~= "" or name == "" then - local i = 1 - local newname = name .. i - while vim.fn.bufname(newname) ~= "" do - i = i + 1 - newname = name .. i - end - name = newname - end - vim.api.nvim_buf_set_name(stdin_buf, name) - end - - local winnr - local bufnr - - -- Open window - if type(open) == "function" then - bufnr, winnr = open(files, argv, stdin_buf, guest_cwd) - if winnr == nil and bufnr ~= nil then - winnr = vim.fn.bufwinid(bufnr) - end - elseif type(open) == "string" then - local focus = vim.fn.argv(focus_first and 0 or (#files - 1)) - -- If there's an stdin buf, focus that - if stdin_buf then - focus = vim.api.nvim_buf_get_name(stdin_buf) - end - if open == "current" then - vim.cmd("edit " .. focus) - elseif open == "alternate" then - winnr = vim.fn.win_getid(vim.fn.winnr("#")) - vim.api.nvim_win_set_buf(winnr, vim.fn.bufnr(focus)) - vim.api.nvim_set_current_win(winnr) - elseif open == "split" then - vim.cmd("split " .. focus) - elseif open == "vsplit" then - vim.cmd("vsplit " .. focus) - else - vim.cmd("tabedit " .. focus) - end - winnr = vim.api.nvim_get_current_win() - bufnr = vim.api.nvim_get_current_buf() - else - vim.api.nvim_err_writeln("Flatten: 'config.open.focus' expects a function or string, got " .. type(open)) - return false - end - - local ft - if bufnr ~= nil then - ft = vim.api.nvim_buf_get_option(bufnr, "filetype") - end - - local block = config.block_for[ft] or force_block - - for _, cmd in ipairs(postcmds) do - if vim.api.nvim_exec2 then - vim.api.nvim_exec2(cmd, {}) - else - vim.api.nvim_exec(cmd, false) - end - end - - callbacks.post_open(bufnr, winnr, ft, block) - - if block then - M.augroup = vim.api.nvim_create_augroup("flatten_notify", { clear = true }) - notify_when_done(response_pipe, bufnr, callbacks.block_end, ft) - end - return block + local files = opts.files + local response_pipe = opts.response_pipe + local guest_cwd = opts.guest_cwd + local stdin = opts.stdin + local force_block = opts.force_block + local argv = opts.argv + local config = require("flatten").config + local callbacks = config.callbacks + local focus_first = config.window.focus == "first" + local open = config.window.open + + local nfiles = #files + local stdin_lines = #stdin + + --- commands passed through with +, to be executed after opening files + local postcmds = {} + + if nfiles == 0 and stdin_lines == 0 then + -- If there are no new bufs, don't open anything + -- and tell the guest not to block + return false + end + + local is_cmd = false + if config.allow_cmd_passthrough then + for _, arg in ipairs(argv) do + if is_cmd then + is_cmd = false + -- execute --cmd commands + if vim.api.nvim_exec2 then + -- nvim_exec2 only exists in nvim 0.9+ + vim.api.nvim_exec2(arg, {}) + else + vim.api.nvim_exec(arg, false) + end + elseif arg:sub(1, 1) == "+" then + local cmd = string.sub(arg, 2, -1) + table.insert(postcmds, cmd) + elseif arg == "--cmd" then + -- next arg is the actual command + is_cmd = true + end + end + end + + callbacks.pre_open() + + -- Open files + if nfiles > 0 then + local argstr = "" + for i, fname in ipairs(files) do + local is_absolute = string.find(fname, "^/") + local fpath = + vim.fn.fnameescape(is_absolute and fname or (guest_cwd .. "/" .. fname)) + files[i] = fpath + if argstr == "" or argstr == nil then + argstr = fpath + else + argstr = argstr .. " " .. fpath + end + end + -- Hack to work around https://github.com/vim/vim/issues/4610 + local wildignore = vim.o.wildignore + vim.o.wildignore = "" + vim.cmd("0argadd " .. argstr) + vim.o.wildignore = wildignore + end + + -- Create buffer for stdin pipe input + local stdin_buf = nil + if stdin_lines > 0 then + -- Create buffer for stdin + stdin_buf = vim.api.nvim_create_buf(true, false) + -- Add text to buffer + vim.api.nvim_buf_set_lines(stdin_buf, 0, 0, true, stdin) + -- Set buffer name based on the first line of stdin + local name = stdin[1]:sub(1, 12):gsub("[^%w%.]", "") + -- Ensure the name isn't empty or a duplicate + if vim.fn.bufname(name) ~= "" or name == "" then + local i = 1 + local newname = name .. i + while vim.fn.bufname(newname) ~= "" do + i = i + 1 + newname = name .. i + end + name = newname + end + vim.api.nvim_buf_set_name(stdin_buf, name) + end + + local winnr + local bufnr + + -- Open window + if type(open) == "function" then + bufnr, winnr = open(files, argv, stdin_buf, guest_cwd) + if winnr == nil and bufnr ~= nil then winnr = vim.fn.bufwinid(bufnr) end + elseif type(open) == "string" then + local focus = vim.fn.argv(focus_first and 0 or (#files - 1)) + -- If there's an stdin buf, focus that + if stdin_buf then focus = vim.api.nvim_buf_get_name(stdin_buf) end + if open == "current" then + vim.cmd("edit " .. focus) + elseif open == "alternate" then + winnr = vim.fn.win_getid(vim.fn.winnr("#")) + vim.api.nvim_win_set_buf(winnr, vim.fn.bufnr(focus)) + vim.api.nvim_set_current_win(winnr) + elseif open == "split" then + vim.cmd("split " .. focus) + elseif open == "vsplit" then + vim.cmd("vsplit " .. focus) + else + vim.cmd("tabedit " .. focus) + end + winnr = vim.api.nvim_get_current_win() + bufnr = vim.api.nvim_get_current_buf() + else + vim.api.nvim_err_writeln( + "Flatten: 'config.open.focus' expects a function or string, got " + .. type(open) + ) + return false + end + + local ft + if bufnr ~= nil then ft = vim.api.nvim_buf_get_option(bufnr, "filetype") end + + local block = config.block_for[ft] or force_block + + for _, cmd in ipairs(postcmds) do + if vim.api.nvim_exec2 then + vim.api.nvim_exec2(cmd, {}) + else + vim.api.nvim_exec(cmd, false) + end + end + + callbacks.post_open(bufnr, winnr, ft, block) + + if block then + M.augroup = vim.api.nvim_create_augroup("flatten_notify", { clear = true }) + notify_when_done(response_pipe, bufnr, callbacks.block_end, ft) + end + return block end return M diff --git a/lua/flatten/guest.lua b/lua/flatten/guest.lua index 769fdaa..a57b125 100644 --- a/lua/flatten/guest.lua +++ b/lua/flatten/guest.lua @@ -3,143 +3,132 @@ local M = {} local host local function is_windows() - return string.sub(package["config"], 1, 1) == "\\" + return string.sub(package["config"], 1, 1) == "\\" end local function sanitize(path) - return path:gsub("\\", "/") + return path:gsub("\\", "/") end function M.exec_on_host(call, opts) - return vim.fn.rpcrequest(host, "nvim_exec_lua", call, opts or {}) + return vim.fn.rpcrequest(host, "nvim_exec_lua", call, opts or {}) end function M.maybe_block(block) - if not block then - vim.cmd.qa({ bang = true }) - end - vim.fn.chanclose(host) - while true do - vim.cmd("sleep 1") - end + if not block then vim.cmd.qa({ bang = true }) end + vim.fn.chanclose(host) + while true do + vim.cmd("sleep 1") + end end local function send_files(files, stdin) - if #files < 1 and #stdin < 1 then - return - end - - local config = require("flatten").config - local force_block = vim.g.flatten_wait ~= nil or config.callbacks.should_block(vim.v.argv) - - local server = vim.fn.fnameescape(vim.v.servername) - local cwd = vim.fn.fnameescape(vim.fn.getcwd(-1, -1)) - if is_windows() then - server = sanitize(server) - cwd = sanitize(cwd) - end - - local call = string.format( - [[return require('flatten.core').edit_files(%s)]], - vim.inspect({ - files = files, - response_pipe = server, - guest_cwd = cwd, - stdin = stdin, - argv = vim.v.argv, - force_block = force_block, - }) - ) - - for _, buf in ipairs(vim.api.nvim_list_bufs()) do - vim.api.nvim_buf_delete(buf, { force = true }) - end - local block = M.exec_on_host(call) or force_block - M.maybe_block(block) + if #files < 1 and #stdin < 1 then return end + + local config = require("flatten").config + local force_block = vim.g.flatten_wait ~= nil + or config.callbacks.should_block(vim.v.argv) + + local server = vim.fn.fnameescape(vim.v.servername) + local cwd = vim.fn.fnameescape(vim.fn.getcwd(-1, -1)) + if is_windows() then + server = sanitize(server) + cwd = sanitize(cwd) + end + + local call = string.format( + [[return require('flatten.core').edit_files(%s)]], + vim.inspect({ + files = files, + response_pipe = server, + guest_cwd = cwd, + stdin = stdin, + argv = vim.v.argv, + force_block = force_block, + }) + ) + + for _, buf in ipairs(vim.api.nvim_list_bufs()) do + vim.api.nvim_buf_delete(buf, { force = true }) + end + local block = M.exec_on_host(call) or force_block + M.maybe_block(block) end function M.sockconnect(host_pipe) - return pcall(vim.fn.sockconnect, "pipe", host_pipe, { rpc = true }) + return pcall(vim.fn.sockconnect, "pipe", host_pipe, { rpc = true }) end M.init = function(host_pipe) - -- Connect to host process - if type(host_pipe) == "number" then - host = host_pipe - else - local ok - ok, host = M.sockconnect(host_pipe) - -- Return on connection error - if not ok then - return - end - end - - -- Get new files - local files = vim.fn.argv() - local nfiles = #files - - vim.api.nvim_create_autocmd("StdinReadPost", { - pattern = "*", - callback = function() - local readlines = vim.api.nvim_buf_get_lines(0, 0, -1, true) - send_files(files, readlines) - end, - }) - - vim.api.nvim_create_autocmd("BufEnter", { - pattern = "*", - once = true, - callback = function() - local function filter_map(tbl, f) - local result = {} - for _, v in ipairs(tbl) do - local r = f(v) - if r ~= nil then - table.insert(result, r) - end - end - return result - end - files = filter_map(vim.api.nvim_list_bufs(), function(buffer) - if not vim.api.nvim_buf_is_loaded(buffer) then - return - end - local buftype = vim.api.nvim_buf_get_option(buffer, "buftype") - if buftype ~= "" and buftype ~= "acwrite" then - return - end - local name = vim.api.nvim_buf_get_name(buffer) - if name ~= "" and vim.api.nvim_buf_get_option(buffer, "buflisted") then - return name - end - end) - nfiles = #files - - -- No arguments, user is probably opening a nested session intentionally - -- Or only piping input from stdin - if nfiles < 1 then - local config = require("flatten").config - local should_nest, should_block = config.nest_if_no_args, false - - if config.callbacks.no_files then - local result = M.exec_on_host("return require'flatten'.config.callbacks.no_files()") - if type(result) == "boolean" then - should_nest = result - elseif type(result) == "table" then - should_nest = result.nest_if_no_args - should_block = result.should_block - end - end - if should_nest == true then - return - end - M.maybe_block(should_block) - end - - send_files(files, {}) - end, - }) + -- Connect to host process + if type(host_pipe) == "number" then + host = host_pipe + else + local ok + ok, host = M.sockconnect(host_pipe) + -- Return on connection error + if not ok then return end + end + + -- Get new files + local files = vim.fn.argv() + local nfiles = #files + + vim.api.nvim_create_autocmd("StdinReadPost", { + pattern = "*", + callback = function() + local readlines = vim.api.nvim_buf_get_lines(0, 0, -1, true) + send_files(files, readlines) + end, + }) + + vim.api.nvim_create_autocmd("BufEnter", { + pattern = "*", + once = true, + callback = function() + local function filter_map(tbl, f) + local result = {} + for _, v in ipairs(tbl) do + local r = f(v) + if r ~= nil then table.insert(result, r) end + end + return result + end + files = filter_map(vim.api.nvim_list_bufs(), function(buffer) + if not vim.api.nvim_buf_is_loaded(buffer) then return end + local buftype = vim.api.nvim_buf_get_option(buffer, "buftype") + if buftype ~= "" and buftype ~= "acwrite" then return end + local name = vim.api.nvim_buf_get_name(buffer) + if name ~= "" and vim.api.nvim_buf_get_option(buffer, "buflisted") then + return name + end + end) + nfiles = #files + + -- No arguments, user is probably opening a nested session intentionally + -- Or only piping input from stdin + if nfiles < 1 then + local config = require("flatten").config + local should_nest, should_block = config.nest_if_no_args, false + + if config.callbacks.no_files then + local result = M.exec_on_host( + "return require'flatten'.config.callbacks.no_files()" + ) + if type(result) == "boolean" then + should_nest = result + elseif type(result) == "table" then + should_nest = result.nest_if_no_args + should_block = result.should_block + end + end + if should_nest == true then return end + M.maybe_block(should_block) + end + + send_files(files, {}) + end, + }) end return M diff --git a/lua/flatten/init.lua b/lua/flatten/init.lua index ec2c0d7..b5f65b3 100644 --- a/lua/flatten/init.lua +++ b/lua/flatten/init.lua @@ -1,94 +1,84 @@ local M = {} M.try_address = function(addr, startserver) - if not addr:find("/") then - addr = ("%s/%s"):format(vim.fn.stdpath("run"), addr) - end - if vim.loop.fs_stat(addr) then - local ok, sock = require("flatten.guest").sockconnect(addr) - if ok then - return sock - end - elseif startserver then - local ok = pcall(vim.fn.serverstart, addr) - if ok then - return addr - end - end + if not addr:find("/") then + addr = ("%s/%s"):format(vim.fn.stdpath("run"), addr) + end + if vim.loop.fs_stat(addr) then + local ok, sock = require("flatten.guest").sockconnect(addr) + if ok then return sock end + elseif startserver then + local ok = pcall(vim.fn.serverstart, addr) + if ok then return addr end + end end M.default_pipe_path = function() - -- If running in a terminal inside Neovim: - if vim.env.NVIM then - return vim.env.NVIM - end - -- If running in a Kitty terminal, - -- all tabs/windows/os-windows in the same instance of kitty will open in the first neovim instance - if vim.env.KITTY_PID and M.config.one_per.kitty then - local ret = M.try_address("kitty.nvim-" .. vim.env.KITTY_PID, true) - if ret ~= nil then - return ret - end - end - -- If running in a Wezterm, - -- all tabs/windows/windows in the same instance of wezterm will open in the first neovim instance - if vim.env.WEZTERM_UNIX_SOCKET and M.config.one_per.wezterm then - local pid = vim.env.WEZTERM_UNIX_SOCKET:match("gui%-sock%-(%d+)") - local ret = M.try_address("wezterm.nvim-" .. pid, true) - if ret ~= nil then - return ret - end - end + -- If running in a terminal inside Neovim: + if vim.env.NVIM then return vim.env.NVIM end + -- If running in a Kitty terminal, + -- all tabs/windows/os-windows in the same instance of kitty will open in the first neovim instance + if vim.env.KITTY_PID and M.config.one_per.kitty then + local ret = M.try_address("kitty.nvim-" .. vim.env.KITTY_PID, true) + if ret ~= nil then return ret end + end + -- If running in a Wezterm, + -- all tabs/windows/windows in the same instance of wezterm will open in the first neovim instance + if vim.env.WEZTERM_UNIX_SOCKET and M.config.one_per.wezterm then + local pid = vim.env.WEZTERM_UNIX_SOCKET:match("gui%-sock%-(%d+)") + local ret = M.try_address("wezterm.nvim-" .. pid, true) + if ret ~= nil then return ret end + end end -- selene: allow(unused_variable) M.config = { - callbacks = { - ---@param argv table a list of all the arguments in the nested session - should_block = function(argv) - return false - end, - pre_open = function() end, - post_open = function(bufnr, winnr, filetype, is_blocking) end, - block_end = function(filetype) end, - }, - allow_cmd_passthrough = true, - ---Allow a nested session to open when nvim is - ---executed without any args - nest_if_no_args = false, - block_for = { - gitcommit = true, - }, - window = { - open = "current", - focus = "first", - }, - one_per = { kitty = true, wezterm = true }, - pipe_path = M.default_pipe_path, + callbacks = { + ---@param argv table a list of all the arguments in the nested session + should_block = function(argv) + return false + end, + pre_open = function() end, + post_open = function(bufnr, winnr, filetype, is_blocking) end, + block_end = function(filetype) end, + }, + allow_cmd_passthrough = true, + ---Allow a nested session to open when nvim is + ---executed without any args + nest_if_no_args = false, + block_for = { + gitcommit = true, + }, + window = { + open = "current", + focus = "first", + }, + one_per = { kitty = true, wezterm = true }, + pipe_path = M.default_pipe_path, } local is_guest ---@return boolean | nil ---Returns true if in guest, false if in host, and nil if flatten has not yet been initialized. function M.is_guest() - return is_guest + return is_guest end M.setup = function(opt) - M.config = vim.tbl_deep_extend("keep", opt or {}, M.config) + M.config = vim.tbl_deep_extend("keep", opt or {}, M.config) - local pipe_path = M.config.pipe_path - if type(pipe_path) == "function" then - pipe_path = pipe_path() - end + local pipe_path = M.config.pipe_path + if type(pipe_path) == "function" then pipe_path = pipe_path() end - if pipe_path == nil or vim.tbl_contains(vim.fn.serverlist(), pipe_path, {}) then - is_guest = false - return - end + if + pipe_path == nil or vim.tbl_contains(vim.fn.serverlist(), pipe_path, {}) + then + is_guest = false + return + end - is_guest = true - require("flatten.guest").init(pipe_path) + is_guest = true + require("flatten.guest").init(pipe_path) end return M diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..2014389 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,7 @@ +column_width = 80 # 120 +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 2 +quote_style = "AutoPreferDouble" +call_parentheses = "Always" +collapse_simple_statement = "ConditionalOnly"