diff --git a/after/plugin/buftabicons.vim b/after/plugin/buftabicons.vim new file mode 100644 index 0000000..710e740 --- /dev/null +++ b/after/plugin/buftabicons.vim @@ -0,0 +1,154 @@ +" Sets the highlighting for the given group +fun! s:X(group, fg, bg, attr) + if a:fg != "" + exec "silent hi " . a:group . " guifg=#" . a:fg + endif + if a:bg != "" + exec "silent hi " . a:group . " guibg=#" . a:bg + endif + if a:attr != "" + exec "silent hi " . a:group . " gui=" . a:attr + endif +endfun + +let s:file_extension_colors = { + \ 'default' : 'ffffff', + \ 'styl' : '8dc149', + \ 'sass' : 'f55385', + \ 'scss' : 'f55385', + \ 'htm' : 'e37933', + \ 'html' : 'e37933', + \ 'erb' : 'cc3e44', + \ 'slim' : 'd4843e', + \ 'ejs' : 'cbcb41', + \ 'css' : '519aba', + \ 'less' : '03589c', + \ 'md' : '519aba', + \ 'mdx' : '519aba', + \ 'markdown' : '519aba', + \ 'rmd' : '519aba', + \ 'json' : 'cbcb41', + \ 'js' : 'cbcb41', + \ 'mjs' : 'cbcb41', + \ 'jsx' : '519aba', + \ 'rb' : 'cc3e44', + \ 'php' : 'a074c4', + \ 'py' : '519aba', + \ 'pyc' : '519aba', + \ 'pyo' : '519aba', + \ 'pyd' : '519aba', + \ 'coffee' : '905532', + \ 'mustache' : 'd4843e', + \ 'hbs' : 'd4843e', + \ 'conf' : '6d8086', + \ 'ini' : '6d8086', + \ 'yml' : '6d8086', + \ 'yaml' : '6d8086', + \ 'toml' : '6d8086', + \ 'bat' : '6d8086', + \ 'jpg' : '3affdb', + \ 'jpeg' : '3affdb', + \ 'bmp' : '3affdb', + \ 'png' : '3affdb', + \ 'webp' : '3affdb', + \ 'gif' : '3affdb', + \ 'ico' : '3affdb', + \ 'twig' : '8dc149', + \ 'cpp' : '519aba', + \ 'cxx' : '519aba', + \ 'cc' : '519aba', + \ 'cp' : '519aba', + \ 'c' : '519aba', + \ 'cs' : '519aba', + \ 'h' : '519aba', + \ 'hh' : '519aba', + \ 'hpp' : '519aba', + \ 'hxx' : '519aba', + \ 'hs' : 'f5c06f', + \ 'lhs' : 'f5c06f', + \ 'lua' : '519aba', + \ 'java' : 'cc3e44', + \ 'sh' : '4d5a5e', + \ 'fish' : '8dc149', + \ 'bash' : '4d5a5e', + \ 'zsh' : '4d5a5e', + \ 'ksh' : '4d5a5e', + \ 'csh' : '4d5a5e', + \ 'awk' : 'ffffff', + \ 'ps1' : '4d5a5e', + \ 'ml' : 'e37933', + \ 'mli' : 'e37933', + \ 'diff' : '4d5a5e', + \ 'db' : 'f55385', + \ 'sql' : 'f55385', + \ 'dump' : 'f55385', + \ 'clj' : '8dc149', + \ 'cljc' : '8dc149', + \ 'cljs' : '8dc149', + \ 'edn' : '519aba', + \ 'scala' : 'cc3e44', + \ 'go' : '519aba', + \ 'dart' : '03589c', + \ 'xul' : 'e37933', + \ 'sln' : '854cc7', + \ 'suo' : '854cc7', + \ 'pl' : '519aba', + \ 'pm' : '519aba', + \ 't' : '519aba', + \ 'rss' : 'e37933', + \ 'f#' : '03589c', + \ 'fsscript' : '519aba', + \ 'fsx' : '519aba', + \ 'fs' : '519aba', + \ 'fsi' : '519aba', + \ 'rs' : '519aba', + \ 'rlib' : '519aba', + \ 'd' : 'cc3e44', + \ 'erl' : 'a90533', + \ 'hrl' : 'f55385', + \ 'ex' : 'a074c4', + \ 'exs' : 'a074c4', + \ 'eex' : 'a074c4', + \ 'leex' : 'ffffff', + \ 'vim' : '019833', + \ 'ai' : 'e37933', + \ 'psd' : '03589c', + \ 'psb' : '03589c', + \ 'ts' : '519aba', + \ 'tsx' : '519aba', + \ 'jl' : '9558be', + \ 'pp' : 'ffffff', + \ 'vue' : '8dc149', + \ 'elm' : 'ffffff', + \ 'swift' : 'e37933', + \ 'dockerfile' : '519aba', + \ 'git' : 'e37933', + \ 'license' : 'cbcb41', + \ 'xcplayground' : 'd4843e' +\} + +if !exists('g:BufTabLineHiColor') + let g:BufTabLineHiColor = {} +endif + +for [key, val] in items(s:file_extension_colors) + if !has_key(g:BufTabLineHiColor, key) + let g:BufTabLineHiColor[key] = val + endif +endfor + +for [key, val] in items(g:BufTabLineHiColor) + let icon_identifier = 'buftablineIcon_'.key + + if exists('g:WebDevIconsUnicodeDecorateFileNodesExtensionSymbols["'.key.'"]') + let icon = g:WebDevIconsUnicodeDecorateFileNodesExtensionSymbols[key] + exec 'silent syn match '.icon_identifier.' "\zs'.icon.'\ze"' + exec 'hi def link '.icon_identifier.' BufTabLineNumCurrent' + endif + + if val != '' + call s:X(icon_identifier, val, '', '') + endif +endfor + + diff --git a/autoload/buftabline/util.vim b/autoload/buftabline/util.vim new file mode 100644 index 0000000..3df8b50 --- /dev/null +++ b/autoload/buftabline/util.vim @@ -0,0 +1,180 @@ +let s:file_extension_matches = [ + \ 'default' , + \ 'styl' , + \ 'sass' , + \ 'scss' , + \ 'htm' , + \ 'html' , + \ 'erb' , + \ 'slim' , + \ 'ejs' , + \ 'css' , + \ 'less' , + \ 'md' , + \ 'mdx' , + \ 'markdown' , + \ 'rmd' , + \ 'json' , + \ 'js' , + \ 'mjs' , + \ 'jsx' , + \ 'rb' , + \ 'php' , + \ 'py' , + \ 'pyc' , + \ 'pyo' , + \ 'pyd' , + \ 'coffee' , + \ 'mustache' , + \ 'hbs' , + \ 'conf' , + \ 'ini' , + \ 'yml' , + \ 'yaml' , + \ 'toml' , + \ 'bat' , + \ 'jpg' , + \ 'jpeg' , + \ 'bmp' , + \ 'png' , + \ 'webp' , + \ 'gif' , + \ 'ico' , + \ 'twig' , + \ 'cpp' , + \ 'cxx' , + \ 'cc' , + \ 'cp' , + \ 'c' , + \ 'cs' , + \ 'h' , + \ 'hh' , + \ 'hpp' , + \ 'hxx' , + \ 'hs' , + \ 'lhs' , + \ 'lua' , + \ 'java' , + \ 'sh' , + \ 'fish' , + \ 'bash' , + \ 'zsh' , + \ 'ksh' , + \ 'csh' , + \ 'awk' , + \ 'ps1' , + \ 'ml' , + \ 'mli' , + \ 'diff' , + \ 'db' , + \ 'sql' , + \ 'dump' , + \ 'clj' , + \ 'cljc' , + \ 'cljs' , + \ 'edn' , + \ 'scala' , + \ 'go' , + \ 'dart' , + \ 'xul' , + \ 'sln' , + \ 'suo' , + \ 'pl' , + \ 'pm' , + \ 't' , + \ 'rss' , + \ 'f#' , + \ 'fsscript' , + \ 'fsx' , + \ 'fs' , + \ 'fsi' , + \ 'rs' , + \ 'rlib' , + \ 'd' , + \ 'erl' , + \ 'hrl' , + \ 'ex' , + \ 'exs' , + \ 'eex' , + \ 'leex' , + \ 'vim' , + \ 'ai' , + \ 'psd' , + \ 'psb' , + \ 'ts' , + \ 'tsx' , + \ 'jl' , + \ 'pp' , + \ 'vue' , + \ 'elm' , + \ 'swift' , + \ 'dockerfile' , + \ 'git' , + \ 'license' , + \ 'xcplayground' +\] + +let s:file_node_exact_matches = { + \ 'gruntfile.coffee' : 'gruntfile', + \ 'gruntfile.js' : 'gruntfile', + \ 'gruntfile.ls' : 'procfile', + \ 'gulpfile.coffee' : 'gulpfile', + \ 'gulpfile.js' : 'gulpfile', + \ 'gulpfile.ls' : 'gulpfile', + \ 'mix.lock' : 'mix', + \ 'dropbox' : 'dropbox', + \ '.gitconfig' : 'git', + \ '.gitignore' : 'git', + \ '.gitlab-ci.yml' : 'git', + \ '.bashrc' : 'bashrc', + \ '.zshrc' : 'bashrc', + \ '.vimrc' : 'vim', + \ '.gvimrc' : 'vim', + \ '_vimrc' : 'vim', + \ '_gvimrc' : 'vim', + \ '.bashprofile' : 'bashrc', + \ 'favicon.ico' : 'favicon', + \ 'license' : 'license', + \ 'procfile' : 'procfile', + \ 'dockerfile' : 'dockerfile', + \ 'docker-compose.yml' : 'dockerfile', + \ 'makefile' : 'makefile', + \ 'cmakelists.txt' : 'cmake', +\} + +let s:file_node_pattern_matches = { + \ '.*jquery.*\.js$' : 'jquery', + \ '.*angular.*\.js$' : 'angular', + \ '.*backbone.*\.js$' : 'backbone', + \ '.*require.*\.js$' : 'requirejs', + \ '.*materialize.*\.js$' : 'materialize', + \ '.*materialize.*\.css$' : 'materialize', + \ '.*mootools.*\.js$' : 'mootols', + \ '.*vimrc.*' : 'vim' +\} + +function! buftabline#util#getftp(fname) + " Exact match + for [key, val] in items(s:file_node_exact_matches) + if a:fname =~ '\c'.key.'$' + return val + endif + endfor + " Pattern match + for [key, val] in items(s:file_node_exact_matches) + if a:fname =~ key + return val + endif + endfor + " Extension match + let fext = fnamemodify(a:fname, ':e') + for key in s:file_extension_matches + if fext == key + return key + endif + endfor + " None match + return 'default' +endfunction + + diff --git a/doc/buftabline.txt b/doc/buftabline.txt index dc54ac9..416c9ca 100644 --- a/doc/buftabline.txt +++ b/doc/buftabline.txt @@ -52,7 +52,17 @@ effect immediately unless you force an update: > *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'. + it indicates whether the buffer is 'modified' or/and is 'readonly'. + + +*g:buftabline_indicators_mod* string (default '+') + + What to display when a buffer is 'modified' + + +*g:buftabline_indicators_ro* string (default '-') + + What to display when a buffer is 'readonly' *g:buftabline_separators* boolean (default off) @@ -63,6 +73,12 @@ effect immediately unless you force an update: > separator will be highlighted the same way as the tab to its left.) +*g:buftabline_path* boolean (default off) + + When on, the buffer's relative file path to the working directory is + indicated on the right of the tabline + + *g:buftabline_plug_max* number (default 10) The number of |buftabline-mappings| that will be created by the plugin. @@ -124,14 +140,23 @@ 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') +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') +*BufTabLineNumCurrent* |BufTabLineCurrent| Buffer number +*BufTabLineNumActive* |BufTabLineActive| (same as buffer's) +*BufTabLineNumHidden* |BufTabLineHidden| (same as buffer's) +*BufTabLineNumModifiedCurrent* |BufTabLineNumCurrent| (same as buffer's) +*BufTabLineNumModifiedActive* |BufTabLineNumActive| (same as buffer's) +*BufTabLineNumModifiedHidden* |BufTabLineNumHidden| (same as buffer's) +*BufTabLineCharModifiedCurrent* |BufTabLineModifiedCurrent| Buffer indicator +*BufTabLineCharModifiedActive* |BufTabLineModifiedActive| (same as buffer's) +*BufTabLineCharModifiedHidden* |BufTabLineModifiedHidden| (same as buffer's) ============================================================================== diff --git a/plugin/buftabline.vim b/plugin/buftabline.vim index fccfd6d..6224599 100644 --- a/plugin/buftabline.vim +++ b/plugin/buftabline.vim @@ -32,16 +32,30 @@ scriptencoding utf-8 hi default link BufTabLineCurrent TabLineSel hi default link BufTabLineActive PmenuSel hi default link BufTabLineHidden TabLine +hi default link BufTabLinePath BufTabLineCurrent hi default link BufTabLineFill TabLineFill hi default link BufTabLineModifiedCurrent BufTabLineCurrent hi default link BufTabLineModifiedActive BufTabLineActive hi default link BufTabLineModifiedHidden BufTabLineHidden +hi default link BufTabLineNumCurrent BufTabLineCurrent +hi default link BufTabLineNumActive BufTabLineActive +hi default link BufTabLineNumHidden BufTabLineHidden +hi default link BufTabLineNumModifiedCurrent BufTabLineNumCurrent +hi default link BufTabLineNumModifiedActive BufTabLineNumActive +hi default link BufTabLineNumModifiedHidden BufTabLineNumHidden +hi default link BufTabLineCharModifiedCurrent BufTabLineModifiedCurrent +hi default link BufTabLineCharModifiedActive BufTabLineModifiedActive +hi default link BufTabLineCharModifiedHidden BufTabLineModifiedHidden -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', 2) -let g:buftabline_plug_max = get(g:, 'buftabline_plug_max', 10) +let g:buftabline_numbers = get(g:, 'buftabline_numbers', 0) +let g:buftabline_icons = get(g:, 'buftabline_icons', 0) +let g:buftabline_indicators = get(g:, 'buftabline_indicators', 0) +let g:buftabline_indicators_mod = get(g:, 'buftabline_indicators_mod', '+') +let g:buftabline_indicators_ro = get(g:, 'buftabline_indicators_ro', '-') +let g:buftabline_path = get(g:, 'buftabline_path', 0) +let g:buftabline_separators = get(g:, 'buftabline_separators', 0) +let g:buftabline_show = get(g:, 'buftabline_show', 2) +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")') @@ -60,10 +74,14 @@ 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 show_num = g:buftabline_numbers == 1 + let show_path = g:buftabline_path == 1 + let show_ord = g:buftabline_numbers == 2 + let show_idc = g:buftabline_indicators + let show_icon = g:buftabline_icons + let mod_char = g:buftabline_indicators_mod + let ro_char = g:buftabline_indicators_ro + 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) @@ -76,27 +94,34 @@ function! buftabline#render() 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 = { 'num': bufnum, 'pre': '', 'idx': screen_num } 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.ftp = 'default' 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 pre = '' + + let ftp = buftabline#util#getftp(tab.path) + + let mod = getbufvar(bufnum, '&mod') + let ro = getbufvar(bufnum, '&ro') + if mod || ro let tab.hilite = 'Modified' . tab.hilite - if show_mod | let pre = '+' . pre | endif + if show_idc | let pre = (ro ? ro_char : '') . (mod ? mod_char : '') | endif endif - if strlen(pre) | let tab.pre = pre . ' ' | endif + if strlen(ftp) | let tab.ftp = ftp | 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 . ' !' : '!' ) + let tab.label = ( show_idc ? '!' . screen_num : screen_num ? screen_num . ' !' : '!' ) else " unnamed file - let tab.label = ( show_mod && getbufvar(bufnum, '&mod') ? '+' : '' ) - \ . ( screen_num ? screen_num : '*' ) + let tab.label = ( screen_num ? screen_num : '*' ) + \ . ( show_idc && getbufvar(bufnum, '&mod') ? mod_char : '' ) endif let tabs += [tab] endfor @@ -124,7 +149,18 @@ function! buftabline#render() 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') . ' ' + let current = tab.hilite =~ 'Current$' + if show_icon && exists("*WebDevIconsGetFileTypeSymbol") + let icon = (current ? ' %#buftablineIcon_'. tab.ftp : ' %#BufTabLineActive') . '#' . WebDevIconsGetFileTypeSymbol(tab.path) + let tab.label = lpad . '%#BufTabLineNum' . tab.hilite . '#' . tab.idx . icon . ' %#BufTabLine' . tab.hilite . '#' . substitute(strtrans(tab.label), '%', '%%', 'g') + " let tab.label = lpad . '%#BufTabLineNum' . tab.hilite . '#' . tab.idx . ' %#BufTabLine' . tab.hilite . '#' . (show_icon && exists("*WebDevIconsGetFileTypeSymbol") ? WebDevIconsGetFileTypeSymbol(tab.path).' ' : '') . substitute(strtrans(tab.label), '%', '%%', 'g') + else + let tab.label = lpad . '%#BufTabLineNum' . tab.hilite . '#' . tab.idx . ' %#BufTabLine' . tab.hilite . '#' . substitute(strtrans(tab.label), '%', '%%', 'g') + endif + if strlen(tab.pre) + let tab.label = tab.label . '%#BufTabLineChar' . tab.hilite . '#' . tab.pre + endif + if centerbuf == tab.num let halfwidth = tab.width / 2 let lft.width += halfwidth @@ -163,8 +199,13 @@ function! buftabline#render() if len(tabs) | let tabs[0].label = substitute(tabs[0].label, lpad, ' ', '') | endif let swallowclicks = '%'.(1 + tabpagenr('$')).'X' + let activeFilePath = '' + " Hide term path 'term:///' + if show_path && expand('%:~:.') !~ '^term:' + let activeFilePath = '%#BufTabLinePath#%=%{expand("%:~:.")} ' + endif return s:tablineat - \ ? join(map(tabs,'"%#BufTabLine".v:val.hilite."#" . "%".v:val.num."@'.s:sid.'switch_buffer@" . strtrans(v:val.label)'),'') . '%#BufTabLineFill#' . swallowclicks + \ ? join(map(tabs,'"%#BufTabLine".v:val.hilite."#" . "%".v:val.num."@'.s:sid.'switch_buffer@" . strtrans(v:val.label)'),'') . '%#BufTabLineFill#' . activeFilePath . swallowclicks \ : swallowclicks . join(map(tabs,'"%#BufTabLine".v:val.hilite."#" . strtrans(v:val.label)'),'') . '%#BufTabLineFill#' endfunction