├── .github └── FUNDING.yml ├── LICENSE ├── README.md ├── docs └── shadow-border.png └── lua └── buffertag ├── config.lua └── init.lua /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ldelossa] 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Louis DeLosSantos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Buffertag 2 | 3 | ![buffertag screenshot](./docs/shadow-border.png) 4 | 5 | Buffertag is a very simple plugin which always shows the buffer name in non-focused 6 | windows. 7 | 8 | This is designed to be used with the `set laststatus=3` configuration which removes 9 | the unnecessary status lines on each window. 10 | 11 | This idea came from enjoying the space saving of `set laststatus=3` but missing 12 | the ability to quickly reference which buffers are in which windows. I split 13 | hard, and I split often. 14 | 15 | # Usage 16 | 17 | ## Include in Vim Plug (or your package manager of choice) 18 | ```vim 19 | Plug 'ldelossa/buffertag' 20 | ``` 21 | 22 | ## Call setup with an optional config 23 | ```lua 24 | lua require('buffertag').setup({ 25 | -- accepts any border options that `nvim_open_win` accepts. 26 | -- see ":help vim.api.nvim_open_win" 27 | border = "none", 28 | -- By default if the buffer name is too wide for the pane it's in, it will 29 | -- display and overlap the pane. By setting this to true, the buffer name will 30 | -- be truncated to fit within the pane, ensuring the floating window does not 31 | -- overlap any other panes. 32 | limit_width = false, 33 | -- if `vim.bo.modified` is `true` for the current buffer, 34 | -- display modified symbol before the buffer name. 35 | modified_symbol = "[+]", -- other modified symbol: "●" 36 | }) 37 | ``` 38 | 39 | ## Toggle it on and off 40 | ``` 41 | : BuffertagToggle 42 | ``` 43 | 44 | # Demo 45 | 46 | Checkout the demo video [here](https://youtu.be/NhhsLYnYjRU) 47 | -------------------------------------------------------------------------------- /docs/shadow-border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ldelossa/buffertag/59df48544585695da3439d78f3d816461797c592/docs/shadow-border.png -------------------------------------------------------------------------------- /lua/buffertag/config.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.config = { 4 | border = 'none', 5 | limit_width = false, 6 | modified_symbol = "[+]", 7 | } 8 | 9 | return M 10 | -------------------------------------------------------------------------------- /lua/buffertag/init.lua: -------------------------------------------------------------------------------- 1 | local c = require("buffertag.config") 2 | local M = {} 3 | 4 | -- holds any currently open floating windows displaying buffer tags 5 | local float_wins = {} 6 | 7 | function create_tag_float(parent_win) 8 | local buf = vim.api.nvim_win_get_buf(parent_win) 9 | local buf_name = vim.api.nvim_buf_get_name(buf) 10 | buf_name = vim.fn.fnamemodify(buf_name, ":~:.") 11 | 12 | if vim.api.nvim_buf_get_option(buf, "modified") then 13 | buf_name = c.config.modified_symbol .. " " .. buf_name 14 | end 15 | 16 | -- couldn't determine a buffer name, for whatever reason, just return and dont 17 | -- tag the buffer. 18 | if #buf_name <= 0 then 19 | return 20 | end 21 | 22 | -- only consider normal buffers with files loaded into them. 23 | if vim.api.nvim_buf_get_option(buf, "buftype") ~= "" then 24 | return 25 | end 26 | 27 | local buf = vim.api.nvim_create_buf(false, true) 28 | if buf == 0 then 29 | vim.api.nvim_err_writeln("details_popup: could not create details buffer") 30 | return nil 31 | end 32 | 33 | local popup_text = buf_name 34 | -- By default, the popup width is the same as the length of the buffer text we want to show. 35 | local popup_width = #buf_name 36 | 37 | local window_width = vim.api.nvim_win_get_width(parent_win) 38 | -- Subtract 5 here to give the window a bit of padding - otherwise it can 39 | -- look a bit squashed as technically the text fits, but it's right up to 40 | -- the very edge of the pane and doesn't look great 41 | local window_width_with_padding = window_width - 5; 42 | 43 | if c.config.limit_width and popup_width > window_width_with_padding then 44 | popup_width = window_width_with_padding 45 | -- Take the last X characters of the buf_name, where X is the available width. 46 | -- e.g. if the name is foo/bar/baz.js, and the width is 6, this will return baz.js 47 | popup_text = string.sub(popup_text, #buf_name - popup_width + 1, #buf_name) 48 | end 49 | 50 | if popup_width >= vim.api.nvim_win_get_width(0) or popup_width < 0 then 51 | -- do not paint buffer tag 52 | return 53 | end 54 | 55 | 56 | vim.api.nvim_buf_set_option(buf, 'bufhidden', 'delete') 57 | vim.api.nvim_buf_set_option(buf, 'modifiable', true) 58 | vim.api.nvim_buf_set_lines(buf, 0, 0, false, {popup_text}) 59 | vim.api.nvim_buf_set_option(buf, 'modifiable', false) 60 | 61 | local popup_conf = { 62 | relative = "win", 63 | anchor = "NE", 64 | win = parent_win, 65 | width = popup_width, 66 | height = 1, 67 | focusable = false, 68 | zindex = 1, 69 | style = "minimal", 70 | border = c.config.border, 71 | row = 0, 72 | col = vim.api.nvim_win_get_width(parent_win), 73 | } 74 | local float_win = vim.api.nvim_open_win(buf, false, popup_conf) 75 | table.insert(float_wins, float_win) 76 | end 77 | 78 | function M.display_buffertags() 79 | local cur_win = vim.api.nvim_get_current_win() 80 | local wins_to_tag = {} 81 | M.remove_buffertags() 82 | for _, w in ipairs(vim.api.nvim_tabpage_list_wins(0)) do 83 | if w ~= cur_win then 84 | table.insert(wins_to_tag, w) 85 | end 86 | end 87 | for _, w in ipairs(wins_to_tag) do 88 | create_tag_float(w) 89 | end 90 | end 91 | 92 | function M.remove_buffertags() 93 | for _, float in ipairs(float_wins) do 94 | if vim.api.nvim_win_is_valid(float) then 95 | vim.api.nvim_win_close(float, true) 96 | end 97 | end 98 | float_wins = {} 99 | end 100 | 101 | local au_id = nil 102 | 103 | local enabled = false 104 | 105 | function M.enable() 106 | au_id = vim.api.nvim_create_autocmd( 107 | {"WinEnter", "CursorHold"}, 108 | {callback = M.display_buffertags} 109 | ) 110 | enabled = true 111 | -- run it so an initial window move isn't necessary 112 | M.display_buffertags() 113 | end 114 | 115 | function M.disable() 116 | if au_id ~= nil then 117 | vim.api.nvim_del_autocmd(au_id) 118 | end 119 | enabled = false 120 | M.remove_buffertags() 121 | end 122 | 123 | function M.toggle() 124 | if enabled then 125 | M.disable() 126 | else 127 | M.enable() 128 | end 129 | end 130 | 131 | function M.setup(config) 132 | if config ~= nil then 133 | for k, v in pairs(config) do 134 | c.config[k] = v 135 | end 136 | end 137 | 138 | vim.api.nvim_create_user_command("BuffertagToggle", M.toggle, { 139 | desc = "Toggle the Buffertag feature on and off." 140 | }) 141 | 142 | -- toggle it on. 143 | M.toggle() 144 | end 145 | 146 | return M 147 | --------------------------------------------------------------------------------