commit 641aee7737dae469ade75a0f2c0577d182672782
parent 8119d8500464ee533942b5dc92ff9d3b874ed2c4
Author: Jake Bauer <jbauer@paritybit.ca>
Date: Tue, 7 Mar 2023 17:53:03 -0500
Add vim-buftabline
Diffstat:
6 files changed, 397 insertions(+), 6 deletions(-)
diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim
@@ -1,6 +1,7 @@
"Plugins Used:
-" vim-monochrome — (colorscheme)
" vim-commentary — (shortcuts for (un)commenting lines/blocks of code)
+" vim-buftabline — (show a tab line for buffers)
+" vim-monochrome — (custom colorscheme)
" vim-fastline — (custom status bar)
let mapleader = ","
diff --git a/.config/nvim/pack/bundle/start/vim-buftabline/LICENSE b/.config/nvim/pack/bundle/start/vim-buftabline/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Aristotle Pagaltzis
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/.config/nvim/pack/bundle/start/vim-buftabline/doc/buftabline.txt b/.config/nvim/pack/bundle/start/vim-buftabline/doc/buftabline.txt
@@ -0,0 +1,143 @@
+*buftabline.txt* Use the tabline to render buffer tabs
+
+ BUFTABLINE by Aristotle Pagaltzis
+
+==============================================================================
+0. Contents *buftabline*
+
+ 1. Intro ....................................... |buftabline-intro|
+ 2. Configuration settings ...................... |buftabline-config|
+ 3. Mappings .................................... |buftabline-mappings|
+ 4. Tab coloring and colorscheme support ........ |buftabline-colors|
+ 5. Source ...................................... |buftabline-source|
+
+
+==============================================================================
+1. Intro *buftabline-intro*
+
+This plugin takes over the 'tabline' and renders the buffer list in it instead
+of a tab list. It is designed with the ideal that it should Just Work: drop it
+into your setup and you're done. There is only minimal configurable behavior.
+
+
+==============================================================================
+2. Configuration settings *buftabline-config*
+
+Changes to any of the plugin's configuration settings at runtime will not take
+effect immediately unless you force an update: >
+ :call buftabline#update(0)
+<
+
+*g:buftabline_show* number (default 2)
+
+ The value of this option specifies when the line with buffer labels will
+ be displayed:
+ 0: never
+ 1: only if there are at least two buffers
+ 2: always
+ This is analogous to the 'showtabline' setting, only for the |buftabline|.
+
+
+*g:buftabline_numbers* number (default 0)
+
+ The value of this option specifies how to number the buffer labels:
+ 0: no numbering
+ 1: buffer number
+ 2: ordinal number
+ The buffer number corresponds to Vim's internal buffer number as shown by
+ the |:ls| command, whereas the ordinal number is a simple sequential count
+ from left to right.
+
+
+*g:buftabline_indicators* boolean (default off)
+
+ When on, the buffer's state is indicated in the buffer label. Currently
+ the only state indicated is whether the buffer is 'modified'.
+
+
+*g:buftabline_separators* boolean (default off)
+
+ When on, a vertical line is drawn inbetween tabs. (This is not strictly
+ correct. The effect is actually achieved by replacing the space on the
+ left side of each tab with U+23B8 LEFT VERTICAL BOX LINE. Therefore the
+ separator will be highlighted the same way as the tab to its left.)
+
+
+*g:buftabline_plug_max* number (default 10)
+
+ The number of |buftabline-mappings| that will be created by the plugin.
+ You can request more of them or turn off the functionality entirely by
+ setting this to 0. Note it only has an effect before loading the plugin,
+ not if you change it later.
+
+
+==============================================================================
+3. Mappings *buftabline-mappings*
+
+To switch buffers by their ordinal number (|g:buftabline_numbers| = 2) you can
+map keys to the |<Plug>| mappings provided by this plugin: >
+ nmap <leader>1 <Plug>BufTabLine.Go(1)
+ nmap <leader>2 <Plug>BufTabLine.Go(2)
+ nmap <leader>3 <Plug>BufTabLine.Go(3)
+ nmap <leader>4 <Plug>BufTabLine.Go(4)
+ nmap <leader>5 <Plug>BufTabLine.Go(5)
+ nmap <leader>6 <Plug>BufTabLine.Go(6)
+ nmap <leader>7 <Plug>BufTabLine.Go(7)
+ nmap <leader>8 <Plug>BufTabLine.Go(8)
+ nmap <leader>9 <Plug>BufTabLine.Go(9)
+ nmap <leader>0 <Plug>BufTabLine.Go(10)
+<
+There is also a |<Plug>| mapping which always switches to the last buffer: >
+ nmap <leader>0 <Plug>BufTabLine.Go(-1)
+<
+On Mac OS, you probably want to use a |<D-| mapping instead, which will emulate
+the standard Cmd+1, Cmd+2, etc. keybindings for this feature: >
+ nmap <D-1> <Plug>BufTabLine.Go(1)
+ nmap <D-2> <Plug>BufTabLine.Go(2)
+ nmap <D-3> <Plug>BufTabLine.Go(3)
+ nmap <D-4> <Plug>BufTabLine.Go(4)
+ nmap <D-5> <Plug>BufTabLine.Go(5)
+ nmap <D-6> <Plug>BufTabLine.Go(6)
+ nmap <D-7> <Plug>BufTabLine.Go(7)
+ nmap <D-8> <Plug>BufTabLine.Go(8)
+ nmap <D-9> <Plug>BufTabLine.Go(9)
+ nmap <D-0> <Plug>BufTabLine.Go(10)
+ " or to go to the last buffer:
+ nmap <D-0> <Plug>BufTabLine.Go(-1)
+<
+You can ask for more (or fewer) than the default 10 <Plug> mappings using the
+|g:buftabline_plug_max| setting.
+
+==============================================================================
+4. Tab coloring and colorscheme support *buftabline-colors*
+
+This plugin uses several custom highlight groups to render the buffer tabs.
+The custom groups are linked to several other built-in Vim highlight groups
+that should provide a sensible default which automatically harmonizes with
+your |colorscheme|.
+
+However, if you dislike your colorscheme's chosen tabline colours, you can
+override the default links in your |vimrc| -- c.f. |:hi-link|.
+
+Or if you are a colorscheme designer (|44.1|), you can add support to your
+colorscheme for this plugin specifically.
+
+The highlight groups and their default links are as follows:
+
+Custom group Default link Meaning
+*BufTabLineCurrent* |TabLineSel| Buffer shown in current window
+*BufTabLineActive* |PmenuSel| Buffer shown in other window
+*BufTabLineHidden* |TabLine| Buffer not currently visible
+*BufTabLineFill* |TabLineFill| Empty area
+*BufTabLineModifiedCurrent* |BufTabLineCurrent| (Same as linked but 'modified')
+*BufTabLineModifiedActive* |BufTabLineActive| (Same as linked but 'modified')
+*BufTabLineModifiedHidden* |BufTabLineHidden| (Same as linked but 'modified')
+
+
+==============================================================================
+5. Source *buftabline-source*
+
+https://github.com/ap/vim-buftabline
+
+
+vim:tw=78:et:ft=help:norl:
diff --git a/.config/nvim/pack/bundle/start/vim-buftabline/plugin/buftabline.vim b/.config/nvim/pack/bundle/start/vim-buftabline/plugin/buftabline.vim
@@ -0,0 +1,216 @@
+" Vim global plugin for rendering the buffer list in the tabline
+" Licence: The MIT License (MIT)
+" Commit: $Format:%H$
+" {{{ Copyright (c) 2015 Aristotle Pagaltzis <pagaltzis@gmx.de>
+"
+" Permission is hereby granted, free of charge, to any person obtaining a copy
+" of this software and associated documentation files (the "Software"), to deal
+" in the Software without restriction, including without limitation the rights
+" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+" copies of the Software, and to permit persons to whom the Software is
+" furnished to do so, subject to the following conditions:
+"
+" The above copyright notice and this permission notice shall be included in
+" all copies or substantial portions of the Software.
+"
+" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+" THE SOFTWARE.
+" }}}
+
+if v:version < 700
+ echoerr printf('Vim 7 is required for buftabline (this is only %d.%d)',v:version/100,v:version%100)
+ finish
+endif
+
+scriptencoding utf-8
+
+hi default link BufTabLineCurrent TabLineSel
+hi default link BufTabLineActive PmenuSel
+hi default link BufTabLineHidden TabLine
+hi default link BufTabLineFill TabLineFill
+hi default link BufTabLineModifiedCurrent BufTabLineCurrent
+hi default link BufTabLineModifiedActive BufTabLineActive
+hi default link BufTabLineModifiedHidden BufTabLineHidden
+
+let g:buftabline_numbers = get(g:, 'buftabline_numbers', 0)
+let g:buftabline_indicators = get(g:, 'buftabline_indicators', 0)
+let g:buftabline_separators = get(g:, 'buftabline_separators', 0)
+let g:buftabline_show = get(g:, 'buftabline_show', 1)
+let g:buftabline_plug_max = get(g:, 'buftabline_plug_max', 10)
+
+function! buftabline#user_buffers() " help buffers are always unlisted, but quickfix buffers are not
+ return filter(range(1,bufnr('$')),'buflisted(v:val) && "quickfix" !=? getbufvar(v:val, "&buftype")')
+endfunction
+
+function! s:switch_buffer(bufnum, clicks, button, mod)
+ execute 'buffer' a:bufnum
+endfunction
+
+function s:SID()
+ return matchstr(expand('<sfile>'), '<SNR>\d\+_')
+endfunction
+
+let s:dirsep = fnamemodify(getcwd(),':p')[-1:]
+let s:centerbuf = winbufnr(0)
+let s:tablineat = has('tablineat')
+let s:sid = s:SID() | delfunction s:SID
+function! buftabline#render()
+ let show_num = g:buftabline_numbers == 1
+ let show_ord = g:buftabline_numbers == 2
+ let show_mod = g:buftabline_indicators
+ let lpad = g:buftabline_separators ? nr2char(0x23B8) : ' '
+
+ let bufnums = buftabline#user_buffers()
+ let centerbuf = s:centerbuf " prevent tabline jumping around when non-user buffer current (e.g. help)
+
+ " pick up data on all the buffers
+ let tabs = []
+ let path_tabs = []
+ let tabs_per_tail = {}
+ let currentbuf = winbufnr(0)
+ let screen_num = 0
+ for bufnum in bufnums
+ let screen_num = show_num ? bufnum : show_ord ? screen_num + 1 : ''
+ let tab = { 'num': bufnum, 'pre': '' }
+ let tab.hilite = currentbuf == bufnum ? 'Current' : bufwinnr(bufnum) > 0 ? 'Active' : 'Hidden'
+ if currentbuf == bufnum | let [centerbuf, s:centerbuf] = [bufnum, bufnum] | endif
+ let bufpath = bufname(bufnum)
+ if strlen(bufpath)
+ let tab.path = fnamemodify(bufpath, ':p:~:.')
+ let tab.sep = strridx(tab.path, s:dirsep, strlen(tab.path) - 2) " keep trailing dirsep
+ let tab.label = tab.path[tab.sep + 1:]
+ let pre = screen_num
+ if getbufvar(bufnum, '&mod')
+ let tab.hilite = 'Modified' . tab.hilite
+ if show_mod | let pre = '+' . pre | endif
+ endif
+ if strlen(pre) | let tab.pre = pre . ' ' | endif
+ let tabs_per_tail[tab.label] = get(tabs_per_tail, tab.label, 0) + 1
+ let path_tabs += [tab]
+ elseif -1 < index(['nofile','acwrite'], getbufvar(bufnum, '&buftype')) " scratch buffer
+ let tab.label = ( show_mod ? '!' . screen_num : screen_num ? screen_num . ' !' : '!' )
+ else " unnamed file
+ let tab.label = ( show_mod && getbufvar(bufnum, '&mod') ? '+' : '' )
+ \ . ( screen_num ? screen_num : '*' )
+ endif
+ let tabs += [tab]
+ endfor
+
+ " disambiguate same-basename files by adding trailing path segments
+ while len(filter(tabs_per_tail, 'v:val > 1'))
+ let [ambiguous, tabs_per_tail] = [tabs_per_tail, {}]
+ for tab in path_tabs
+ if -1 < tab.sep && has_key(ambiguous, tab.label)
+ let tab.sep = strridx(tab.path, s:dirsep, tab.sep - 1)
+ let tab.label = tab.path[tab.sep + 1:]
+ endif
+ let tabs_per_tail[tab.label] = get(tabs_per_tail, tab.label, 0) + 1
+ endfor
+ endwhile
+
+ " now keep the current buffer center-screen as much as possible:
+
+ " 1. setup
+ let lft = { 'lasttab': 0, 'cut': '.', 'indicator': '<', 'width': 0, 'half': &columns / 2 }
+ let rgt = { 'lasttab': -1, 'cut': '.$', 'indicator': '>', 'width': 0, 'half': &columns - lft.half }
+
+ " 2. sum the string lengths for the left and right halves
+ let currentside = lft
+ let lpad_width = strwidth(lpad)
+ for tab in tabs
+ let tab.width = lpad_width + strwidth(tab.pre) + strwidth(tab.label) + 1
+ let tab.label = lpad . tab.pre . substitute(strtrans(tab.label), '%', '%%', 'g') . ' '
+ if centerbuf == tab.num
+ let halfwidth = tab.width / 2
+ let lft.width += halfwidth
+ let rgt.width += tab.width - halfwidth
+ let currentside = rgt
+ continue
+ endif
+ let currentside.width += tab.width
+ endfor
+ if currentside is lft " centered buffer not seen?
+ " then blame any overflow on the right side, to protect the left
+ let [lft.width, rgt.width] = [0, lft.width]
+ endif
+
+ " 3. toss away tabs and pieces until all fits:
+ if ( lft.width + rgt.width ) > &columns
+ let oversized
+ \ = lft.width < lft.half ? [ [ rgt, &columns - lft.width ] ]
+ \ : rgt.width < rgt.half ? [ [ lft, &columns - rgt.width ] ]
+ \ : [ [ lft, lft.half ], [ rgt, rgt.half ] ]
+ for [side, budget] in oversized
+ let delta = side.width - budget
+ " toss entire tabs to close the distance
+ while delta >= tabs[side.lasttab].width
+ let delta -= remove(tabs, side.lasttab).width
+ endwhile
+ " then snip at the last one to make it fit
+ let endtab = tabs[side.lasttab]
+ while delta > ( endtab.width - strwidth(strtrans(endtab.label)) )
+ let endtab.label = substitute(endtab.label, side.cut, '', '')
+ endwhile
+ let endtab.label = substitute(endtab.label, side.cut, side.indicator, '')
+ endfor
+ endif
+
+ if len(tabs) | let tabs[0].label = substitute(tabs[0].label, lpad, ' ', '') | endif
+
+ let swallowclicks = '%'.(1 + tabpagenr('$')).'X'
+ return s:tablineat
+ \ ? join(map(tabs,'"%#BufTabLine".v:val.hilite."#" . "%".v:val.num."@'.s:sid.'switch_buffer@" . strtrans(v:val.label)'),'') . '%#BufTabLineFill#' . swallowclicks
+ \ : swallowclicks . join(map(tabs,'"%#BufTabLine".v:val.hilite."#" . strtrans(v:val.label)'),'') . '%#BufTabLineFill#'
+endfunction
+
+function! buftabline#update(zombie)
+ set tabline=
+ if tabpagenr('$') > 1 | set guioptions+=e showtabline=2 | return | endif
+ set guioptions-=e
+ if 0 == g:buftabline_show
+ set showtabline=1
+ return
+ elseif 1 == g:buftabline_show
+ " account for BufDelete triggering before buffer is actually deleted
+ let bufnums = filter(buftabline#user_buffers(), 'v:val != a:zombie')
+ let &g:showtabline = 1 + ( len(bufnums) > 1 )
+ elseif 2 == g:buftabline_show
+ set showtabline=2
+ endif
+ set tabline=%!buftabline#render()
+endfunction
+
+augroup BufTabLine
+autocmd!
+autocmd VimEnter * call buftabline#update(0)
+autocmd TabEnter * call buftabline#update(0)
+autocmd BufAdd * call buftabline#update(0)
+autocmd FileType qf call buftabline#update(0)
+autocmd BufDelete * call buftabline#update(str2nr(expand('<abuf>')))
+augroup END
+
+for s:n in range(1, g:buftabline_plug_max) + ( g:buftabline_plug_max > 0 ? [-1] : [] )
+ let s:b = s:n == -1 ? -1 : s:n - 1
+ execute printf("noremap <silent> <Plug>BufTabLine.Go(%d) :<C-U>exe 'b'.get(buftabline#user_buffers(),%d,'')<cr>", s:n, s:b)
+endfor
+unlet! s:n s:b
+
+if v:version < 703
+ function s:transpile()
+ let [ savelist, &list ] = [ &list, 0 ]
+ redir => src
+ silent function buftabline#render
+ redir END
+ let &list = savelist
+ let src = substitute(src, '\n\zs[0-9 ]*', '', 'g')
+ let src = substitute(src, 'strwidth(strtrans(\([^)]\+\)))', 'strlen(substitute(\1, ''\p\|\(.\)'', ''x\1'', ''g''))', 'g')
+ return src
+ endfunction
+ exe "delfunction buftabline#render\n" . s:transpile()
+ delfunction s:transpile
+endif
diff --git a/.config/nvim/pack/bundle/start/vim-monochrome/colors/monochrome-light.vim b/.config/nvim/pack/bundle/start/vim-monochrome/colors/monochrome-light.vim
@@ -23,8 +23,8 @@ let s:accent = ['#6C6C6C', 242]
let s:cursorline = ['#DADADA', 253]
let s:comment = ['#585858', 240]
let s:faded = ['#D0D0D0', 252]
-let s:menu = ['#BCBCBC', 250]
-let s:menusel = ['#9E9E9E', 247]
+let s:menu = ['#9E9E9E', 247]
+let s:menusel = ['#BCBCBC', 250]
let s:default_fg = s:black
let s:default_bg = s:white
@@ -81,6 +81,11 @@ call s:hi('ErrorMsg', s:red, s:default_bg)
call s:hi('StatusLine', s:black, s:faded)
call s:hi('StatusLineNC', s:black, s:faded)
+" Tabs
+call s:hi('TabLine', s:black, s:menusel)
+call s:hi('TabLineSel', s:black, s:faded, s:bold)
+call s:hi('TabLineFill', s:black, s:menu)
+
" Tildes at the bottom of a buffer, etc.
call s:hi('NonText', s:accent)
@@ -104,7 +109,7 @@ call s:hi('helpNote')
" Popup menu.
call s:hi('Pmenu', s:black, s:menu)
-call s:hi('PmenuSel', s:black, s:menusel)
+call s:hi('PmenuSel', s:black, s:menusel, s:bold)
" Notes.
call s:hi('Todo', s:black, s:default_bg, s:bold)
@@ -203,7 +208,7 @@ call s:hi('htmlLink', s:blue, s:default_bg, s:underline)
call s:hi('htmlArg', s:default_fg, s:default_bg)
" --- Gemini -------------------------------------------------------------------
-" Based off of the following plugin: https://tildegit.org/sloum/gemini-vim-syntax
+" Based on this plugin: https://tildegit.org/sloum/gemini-vim-syntax
call s:hi('gmiHeader', s:black, s:default_bg, s:bold)
call s:hi('gmiLinkStart', s:black, s:default_bg, s:bold)
call s:hi('gmiLinkURL', s:blue, s:default_bg, s:underline)
diff --git a/.config/nvim/pack/bundle/start/vim-monochrome/colors/monochrome.vim b/.config/nvim/pack/bundle/start/vim-monochrome/colors/monochrome.vim
@@ -79,6 +79,11 @@ call s:hi('ErrorMsg', s:red, s:default_bg)
call s:hi('StatusLine', s:white, s:faded)
call s:hi('StatusLineNC', s:white, s:faded)
+" Tabs
+call s:hi('TabLine', s:white, s:faded)
+call s:hi('TabLineSel', s:white, s:accent, s:bold)
+call s:hi('TabLineFill', s:white, s:black)
+
" Tildes at the bottom of a buffer, etc.
call s:hi('NonText', s:faded)
@@ -201,7 +206,7 @@ call s:hi('htmlLink', s:blue, s:default_bg, s:underline)
call s:hi('htmlArg', s:default_fg, s:default_bg)
" --- Gemini -------------------------------------------------------------------
-" Bsed off of the following plugin: https://tildegit.org/sloum/gemini-vim-syntax
+" Based on this plugin: https://tildegit.org/sloum/gemini-vim-syntax
call s:hi('gmiHeader', s:white, s:default_bg, s:bold)
call s:hi('gmiLinkStart', s:white, s:default_bg, s:bold)
call s:hi('gmiLinkURL', s:blue, s:default_bg, s:underline)