snailed
/
taolf
Archived
2
0
Fork 0

feature: added tmux statusline and highlights

This commit is contained in:
Lucas Burns 2022-04-15 23:15:14 -05:00
parent 1ac4d99669
commit d4c08af70d
No known key found for this signature in database
GPG Key ID: C011CBEF6628B679
5 changed files with 114 additions and 83 deletions

View File

@ -20,15 +20,34 @@ require("lf").setup({
}, },
winblend = 10, -- psuedotransparency level winblend = 10, -- psuedotransparency level
dir = "", -- directory where `lf` starts ('gwd' is git-working-directory) dir = "", -- directory where `lf` starts ('gwd' is git-working-directory, "" is CWD)
direction = "float", -- window type: float horizontal vertical direction = "float", -- window type: float horizontal vertical
border = "double", -- border kind: single double shadow curved border = "double", -- border kind: single double shadow curved
height = 0.80, -- height of the *floating* window height = 0.80, -- height of the *floating* window
width = 0.85, -- width of the *floating* window width = 0.85, -- width of the *floating* window
mappings = true, -- whether terminal buffer mapping is enabled mappings = true, -- whether terminal buffer mapping is enabled
tmux = false, -- tmux statusline can be disabled on opening of Lf
highlights = { -- highlights passed to toggleterm
Normal = { guibg = <VALUE> },
NormalFloat = { link = 'Normal' },
FloatBorder = {
guifg = <VALUE>,
guibg = <VALUE>
}
},
... -- Layout configurations
... layout_mapping = "<A-u>", -- resize window with this key
views = { -- window dimensions to rotate through
{ width = 0.600, height = 0.600 },
{
width = 1.0 * fn.float2nr(fn.round(0.7 * o.columns)) / o.columns,
height = 1.0 * fn.float2nr(fn.round(0.7 * o.lines)) / o.lines,
},
{ width = 0.800, height = 0.800 },
{ width = 0.950, height = 0.950 },
}
}) })
vim.api.nvim_set_keymap("n", "<mapping>", "<cmd>lua require('lf').start()", { noremap = true }) vim.api.nvim_set_keymap("n", "<mapping>", "<cmd>lua require('lf').start()", { noremap = true })
@ -46,35 +65,13 @@ vim.keymap.set(
-- nil, -- this is the path to open Lf (nil means CWD) -- nil, -- this is the path to open Lf (nil means CWD)
-- this argument is optional see `.start` below -- this argument is optional see `.start` below
{ {
default_cmd = "lf", -- default `lf` command -- Pass any options (if any) that you would like
default_action = "edit", -- default action when `Lf` opens a file
default_actions = { -- default action keybindings
["<C-t>"] = "tabedit",
["<C-x>"] = "split",
["<C-v>"] = "vsplit",
["<C-o>"] = "tab drop",
},
winblend = 10, -- psuedotransparency level
dir = "", -- directory where `lf` starts ('gwd' is git-working-directory) dir = "", -- directory where `lf` starts ('gwd' is git-working-directory)
direction = "float", -- window type: float horizontal vertical direction = "float", -- window type: float horizontal vertical
border = "double", -- border kind: single double shadow curved border = "double", -- border kind: single double shadow curved
height = 0.80, -- height of the *floating* window height = 0.80, -- height of the *floating* window
width = 0.85, -- width of the *floating* window width = 0.85, -- width of the *floating* window
mappings = true, -- whether terminal buffer mapping is enabled mappings = true, -- whether terminal buffer mapping is enabled
-- Layout configurations
layout_mapping = "<A-u>", -- resize window with this key
views = { -- window dimensions
{ width = 0.600, height = 0.600 },
{
width = 1.0 * fn.float2nr(fn.round(0.7 * o.columns)) / o.columns,
height = 1.0 * fn.float2nr(fn.round(0.7 * o.lines)) / o.lines,
},
{ width = 0.800, height = 0.800 },
{ width = 0.950, height = 0.950 },
},
}) })
end, end,
{ noremap = true } { noremap = true }
@ -102,9 +99,16 @@ require('lf').start() -- opens in CWD with either `.setup()` or default options
require('lf').start("~/.config", { border = "rounded" }) -- opens in `~/.config` with rounded borders require('lf').start("~/.config", { border = "rounded" }) -- opens in `~/.config` with rounded borders
``` ```
### Highlighting Groups
The highlight groups that I know for sure work are the ones mentioned above (`Normal`, `NormalFloat`, `FloatBorder`). These are passed to `toggleterm`, and there is a plan in the future to make these `Lf`'s own groups. For now, a one-shot way to change the color of the border of the terminal is the following:
```
:lua require("lf").start({ highlights = { FloatBorder = { guifg = "#819C3B" } } })
```
### Default Actions ### Default Actions
These are various ways to open the wanted file(s). The process works by creating a Neovim mapping to send These are various ways to open the wanted file(s). The process works by creating a Neovim mapping to send
`lf` a command to manually open the file. The available commands is anything that can open a file. `lf` a command to manually open the file. The available commands are anything that can open a file.
### Resizing Window ### Resizing Window
The configuration option `layout_mapping` is the key-mapping that will cycle through the window `views`. The configuration option `layout_mapping` is the key-mapping that will cycle through the window `views`.
@ -125,5 +129,6 @@ The only configurable environment variable is `g:lf_replace_netrw`, which can be
- [ ] `:LfToggle` command - [ ] `:LfToggle` command
- [x] Find a way for `lf` to hijack keybindings - [x] Find a way for `lf` to hijack keybindings
- [x] Cycling through various sizes of the terminal (similar to `rnvimr`) - [x] Cycling through various sizes of the terminal (similar to `rnvimr`)
- [x] Set `tmux` title of ToggleTerm
- [ ] Save previous size when terminal is closed, so it is restored on open - [ ] Save previous size when terminal is closed, so it is restored on open
- [ ] Set `tmux` title of ToggleTerm - [ ] Maybe: Disable `lualine` and other status lines

View File

@ -1,18 +1,23 @@
--- @class Config --- @class Config
--- @field default_cmd string default `lf` command --- @field default_cmd string: default `lf` command
--- @field default_action string default action when `Lf` opens a file --- @field default_action string: default action when `Lf` opens a file
--- @field default_actions table default action keybindings --- @field default_actions table: default action keybindings
--- @field winblend number psuedotransparency level --- @field winblend number: psuedotransparency level
--- @field dir string directory where `lf` starts ('gwd' is git-working-directory) --- @field dir string: directory where `lf` starts ('gwd' is git-working-directory, "" is CWD)
--- @field direction string window type: float horizontal vertical --- @field direction string: window type: float horizontal vertical
--- @field border string border kind: single double shadow curved --- @field border string: border kind: single double shadow curved
--- @field height number height of the *floating* window --- @field height number: height of the *floating* window
--- @field width number width of the *floating* window --- @field width number: width of the *floating* window
--- @field mappings boolean whether terminal buffer mappings should be set --- @field mappings boolean: whether terminal buffer mappings should be set
--- @field tmux boolean: whether tmux statusline should be changed by this plugin
--- @field highlights table: highlight table to pass to `toggleterm`
--- @field layout_mapping string: keybinding to rotate through the window layouts
--- @field views table: table of layouts to be applied to `nvim_win_set_config`
local Config = {} local Config = {}
local fn = vim.fn local fn = vim.fn
local o = vim.o local o = vim.o
local F = vim.F
-- A local function that runs each time allows for a global `.setup()` to work -- A local function that runs each time allows for a global `.setup()` to work
@ -37,6 +42,8 @@ local function init()
height = 0.80, height = 0.80,
width = 0.85, width = 0.85,
mappings = true, mappings = true,
tmux = true,
highlights = {},
-- Layout configurations -- Layout configurations
layout_mapping = "<A-u>", layout_mapping = "<A-u>",
views = { views = {
@ -47,7 +54,7 @@ local function init()
}, },
{width = 0.800, height = 0.800}, {width = 0.800, height = 0.800},
{width = 0.950, height = 0.950} {width = 0.950, height = 0.950}
} },
} }
Config = vim.tbl_deep_extend("keep", lf._cfg or {}, opts) Config = vim.tbl_deep_extend("keep", lf._cfg or {}, opts)
@ -59,17 +66,17 @@ init()
local notify = require("lf.utils").notify local notify = require("lf.utils").notify
---Verify that configuration options that are numbers are numbers or can be converted to numbers ---Verify that configuration options that are numbers are numbers or can be converted to numbers
---@param field string `Config` field to check ---@param field string | number: `Config` field to check
function Config:__check_number(field) ---@param default number: Default value to return if the conversion failed
function Config:__check_number(field, default)
if type(field) == "string" then if type(field) == "string" then
local res = tonumber(field) local res = tonumber(field)
if res == nil then return F.if_nil(res, default)
notify(("invalid option for winblend: %s"):format(field)) elseif type(field) == "number" then
return self.winblend return field
else
return res
end
end end
return default
end end
---Set a configuration passed as a function argument (not through `setup`) ---Set a configuration passed as a function argument (not through `setup`)
@ -77,9 +84,10 @@ end
---@return Config ---@return Config
function Config:set(cfg) function Config:set(cfg)
if cfg and type(cfg) == "table" then if cfg and type(cfg) == "table" then
cfg.winblend = self:__check_number(cfg.winblend) -- TODO: Maybe verify more options in configuration?
cfg.height = self:__check_number(cfg.height) cfg.winblend = self:__check_number(cfg.winblend, self.winblend)
cfg.width = self:__check_number(cfg.width) cfg.height = self:__check_number(cfg.height, self.height)
cfg.width = self:__check_number(cfg.width, self.width)
self = vim.tbl_deep_extend("force", self, cfg or {}) self = vim.tbl_deep_extend("force", self, cfg or {})
end end

View File

@ -44,7 +44,8 @@ local Terminal = require("toggleterm.terminal").Terminal
--- @field id_tmp string File path to a file containing `lf`'s id --- @field id_tmp string File path to a file containing `lf`'s id
local Lf = {} local Lf = {}
local function setup_term() local function setup_term(highlights)
vim.validate({highlights = {highlights, "table", true}})
terminal.setup( terminal.setup(
{ {
size = function(term) size = function(term)
@ -60,8 +61,8 @@ local function setup_term()
shading_factor = "1", shading_factor = "1",
start_in_insert = true, start_in_insert = true,
insert_mappings = true, insert_mappings = true,
persist_size = true persist_size = true,
-- open_mapping = [[<c-\>]], highlights = highlights
} }
) )
end end
@ -85,7 +86,7 @@ function Lf:new(config)
self.winid = nil self.winid = nil
self.id_tmp = nil self.id_tmp = nil
setup_term() setup_term(self.cfg.highlights)
self:__create_term() self:__create_term()
return self return self
@ -105,8 +106,8 @@ function Lf:__create_term()
border = self.cfg.border, border = self.cfg.border,
width = math.floor(vim.o.columns * self.cfg.width), width = math.floor(vim.o.columns * self.cfg.width),
height = math.floor(vim.o.lines * self.cfg.height), height = math.floor(vim.o.lines * self.cfg.height),
winblend = self.cfg.winblend, winblend = self.cfg.winblend
highlights = {border = "Normal", background = "Normal"} -- highlights = {border = "Normal", background = "Normal"},
} }
} }
) )
@ -163,8 +164,7 @@ function Lf:__open_in(path)
if dir ~= "" then if dir ~= "" then
return fn.expand(dir) return fn.expand(dir)
else else
-- `uv` lib doesn't switch directories -- Base the CWD on the filename and not `lcd` and such
-- Expanding the filename works instead
return fn.expand("%:p") return fn.expand("%:p")
end end
end)(path) end)(path)
@ -213,6 +213,10 @@ end
function Lf:__on_open(term) function Lf:__on_open(term)
-- api.nvim_command("setlocal filetype=lf") -- api.nvim_command("setlocal filetype=lf")
if self.cfg.tmux then
utils.tmux(true)
end
for key, mapping in pairs(self.cfg.default_actions) do for key, mapping in pairs(self.cfg.default_actions) do
map( map(
"t", "t",
@ -245,6 +249,7 @@ function Lf:__on_open(term)
if self.cfg.layout_mapping then if self.cfg.layout_mapping then
self.winid = api.nvim_get_current_win() self.winid = api.nvim_get_current_win()
-- Wrap needs to be set, otherwise the window isn't aligned on resize
api.nvim_win_set_option(self.winid, "wrap", true) api.nvim_win_set_option(self.winid, "wrap", true)
map( map(
@ -263,6 +268,10 @@ end
--- ---
---@param term Terminal ---@param term Terminal
function Lf:__callback(term) function Lf:__callback(term)
if self.cfg.tmux then
utils.tmux(false)
end
if (self.cfg.default_action == "cd" or self.cfg.default_action == "lcd") and uv.fs_stat(self.lastdir_tmp) then if (self.cfg.default_action == "cd" or self.cfg.default_action == "lcd") and uv.fs_stat(self.lastdir_tmp) then
-- Since plenary is already being used, this is used instead of `io` -- Since plenary is already being used, this is used instead of `io`
local last_dir = local last_dir =

View File

@ -11,51 +11,47 @@ local levels = vim.log.levels
---@param msg string message ---@param msg string message
---@param hl string highlight group ---@param hl string highlight group
M.echomsg = function(msg, hl) M.echomsg = function(msg, hl)
hl = hl or "Title" hl = hl or "Title"
api.nvim_echo({ { msg, hl } }, true, {}) api.nvim_echo({{msg, hl}}, true, {})
end end
---Display an info message on the CLI ---Display an info message on the CLI
---@param msg string ---@param msg string
M.info = function(msg) M.info = function(msg)
M.echomsg(("[INFO]: %s"):format(msg), "Directory") M.echomsg(("[INFO]: %s"):format(msg), "Directory")
-- M.echomsg(("[INFO]: %s"):format(msg), "Identifier") -- M.echomsg(("[INFO]: %s"):format(msg), "Identifier")
end end
---Display a warning message on the CLI ---Display a warning message on the CLI
---@param msg string ---@param msg string
M.warn = function(msg) M.warn = function(msg)
M.echomsg(("[WARN]: %s"):format(msg), "WarningMsg") M.echomsg(("[WARN]: %s"):format(msg), "WarningMsg")
end end
---Display an error message on the CLI ---Display an error message on the CLI
---@param msg string ---@param msg string
M.err = function(msg) M.err = function(msg)
M.echomsg(("[ERR]: %s"):format(msg), "ErrorMsg") M.echomsg(("[ERR]: %s"):format(msg), "ErrorMsg")
end end
---Display notification message ---Display notification message
---@param msg string ---@param msg string
---@param level 'error' | 'info' | 'warn' ---@param level 'error' | 'info' | 'warn'
M.notify = function(msg, level) M.notify = function(msg, level)
level = level and levels[level:upper()] or levels.INFO level = level and levels[level:upper()] or levels.INFO
vim.notify(fmt("[lf]: %s", msg), level) vim.notify(fmt("[lf]: %s", msg), level)
end end
---Helper function to derive the current git directory path ---Helper function to derive the current git directory path
---@return string|nil ---@return string|nil
M.git_dir = function() M.git_dir = function()
local gitdir = fn.system( local gitdir = fn.system(fmt("git -C %s rev-parse --show-toplevel", fn.expand("%:p:h")))
fmt(
"git -C %s rev-parse --show-toplevel", fn.expand("%:p:h")
)
)
local isgitdir = fn.matchstr(gitdir, "^fatal:.*") == "" local isgitdir = fn.matchstr(gitdir, "^fatal:.*") == ""
if not isgitdir then if not isgitdir then
return return
end end
return vim.trim(gitdir) return vim.trim(gitdir)
end end
---Create a neovim keybinding ---Create a neovim keybinding
@ -64,9 +60,24 @@ end
---@param rhs string string or lua function that is mapped to the keys ---@param rhs string string or lua function that is mapped to the keys
---@param opts table options set for the mapping ---@param opts table options set for the mapping
M.map = function(mode, lhs, rhs, opts) M.map = function(mode, lhs, rhs, opts)
opts = opts or {} opts = opts or {}
opts.noremap = opts.noremap == nil and true or opts.noremap opts.noremap = opts.noremap == nil and true or opts.noremap
vim.keymap.set(mode, lhs, rhs, opts) vim.keymap.set(mode, lhs, rhs, opts)
end
---Set the tmux statusline when opening/closing `Lf`
---@param disable boolean: whether the statusline is being enabled or disabled
M.tmux = function(disable)
if not vim.env.TMUX then
return
end
if disable then
fn.system([[tmux set status off]])
fn.system([[tmux list-panes -F '\#F' | grep -q Z || tmux resize-pane -Z]])
else
fn.system([[tmux set status on]])
fn.system([[tmux list-panes -F '\#F' | grep -q Z && tmux resize-pane -Z]])
end
end end
return M return M

View File

@ -11,7 +11,7 @@ api.nvim_create_user_command(
{nargs = "*", complete = "file"} {nargs = "*", complete = "file"}
) )
if g.lf_replace_netrw then if g.lf_replace_netrw == 1 then
local Path = require("plenary.path") local Path = require("plenary.path")
local group = api.nvim_create_augroup("ReplaceNetrwWithLf", {clear = true}) local group = api.nvim_create_augroup("ReplaceNetrwWithLf", {clear = true})
@ -23,7 +23,7 @@ if g.lf_replace_netrw then
once = true, once = true,
callback = function() callback = function()
if fn.exists("#FileExplorer") then if fn.exists("#FileExplorer") then
vim.cmd("sil! au! FileExplorer") vim.cmd("silent! autocmd! FileExplorer")
end end
end end
} }
@ -34,8 +34,6 @@ if g.lf_replace_netrw then
{ {
pattern = "*", pattern = "*",
group = group, group = group,
-- I don't know if this is supposed to be once
-- The file manager only needs to be opened once, but it could be handled differently
once = true, once = true,
callback = function() callback = function()
local path = Path:new(fn.expand("%")) local path = Path:new(fn.expand("%"))