feature: added tmux statusline and highlights
This commit is contained in:
parent
1ac4d99669
commit
d4c08af70d
61
README.md
61
README.md
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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("%"))
|
||||||
|
|
Reference in New Issue