├── .gitignore ├── LICENSE ├── README.md ├── autoload └── fern │ └── renderer │ └── nerdfont.vim ├── doc └── fern-renderer-nerdfont.txt └── plugin └── fern_renderer_nerdfont.vim /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 Alisue, hashnote.net 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🌿 fern-renderer-nerdfont.vim 2 | 3 | [![fern renderer](https://img.shields.io/badge/🌿%20fern-plugin-yellowgreen)](https://github.com/lambdalisue/fern.vim) 4 | 5 | ![Screenshot](https://user-images.githubusercontent.com/546312/92318275-83115f80-efbe-11ea-854e-78fe22ce2a35.png) 6 | 7 | [fern.vim](https://github.com/lambdalisue/fern.vim) plugin which add file type icons through [lambdalisue/nerdfont.vim](https://github.com/lambdalisue/nerdfont.vim). 8 | 9 | ## Requirements 10 | 11 | - [lambdalisue/nerdfont.vim](https://github.com/lambdalisue/nerdfont.vim) 12 | - [Nerd Fonts](https://www.nerdfonts.com/) 13 | 14 | ## Usage 15 | 16 | Set `g:fern#renderer` to `"nerdfont"` like: 17 | 18 | ```vim 19 | let g:fern#renderer = "nerdfont" 20 | ``` 21 | 22 | ## See also 23 | 24 | - [lambdalisue/glyph-palette.vim](https://github.com/lambdalisue/glyph-palette.vim) - Apply individual colors on icons 25 | - [lambdalisue/fern-renderer-devicons.vim](https://github.com/lambdalisue/fern-renderer-devicons.vim) - Use devicons instead 26 | -------------------------------------------------------------------------------- /autoload/fern/renderer/nerdfont.vim: -------------------------------------------------------------------------------- 1 | scriptencoding utf-8 2 | 3 | let s:PATTERN = '^$~.*[]\/' 4 | let s:Config = vital#fern#import('Config') 5 | let s:AsyncLambda = vital#fern#import('Async.Lambda') 6 | 7 | let s:STATUS_NONE = g:fern#STATUS_NONE 8 | let s:STATUS_COLLAPSED = g:fern#STATUS_COLLAPSED 9 | 10 | function! fern#renderer#nerdfont#new() abort 11 | let default = fern#renderer#default#new() 12 | return extend(copy(default), { 13 | \ 'render': funcref('s:render'), 14 | \ 'syntax': funcref('s:syntax'), 15 | \ 'highlight': funcref('s:highlight'), 16 | \}) 17 | endfunction 18 | 19 | function! s:render(nodes) abort 20 | let options = { 21 | \ 'leading': g:fern#renderer#nerdfont#leading, 22 | \ 'padding': g:fern#renderer#nerdfont#padding, 23 | \ 'root_symbol': g:fern#renderer#nerdfont#root_symbol, 24 | \ 'indent_markers': g:fern#renderer#nerdfont#indent_markers, 25 | \ 'root_leading': g:fern#renderer#nerdfont#root_leading, 26 | \} 27 | let base = len(a:nodes[0].__key) 28 | 29 | if options.indent_markers 30 | let length_nodes = len(a:nodes) 31 | let levels = {} 32 | 33 | for i in range(length_nodes - 1, 0, -1) 34 | let node = a:nodes[i] 35 | let node._renderer_nerdfont_level = len(node.__key) - base 36 | let node._renderer_nerdfont_last = get(levels, node._renderer_nerdfont_level, 0) isnot# 1 ? 1 : 0 37 | 38 | for key in keys(levels) 39 | if key > node._renderer_nerdfont_level 40 | let levels[key] = 0 41 | endif 42 | endfor 43 | 44 | let levels[node._renderer_nerdfont_level] = 1 45 | endfor 46 | 47 | for i in range(length_nodes) 48 | let node = a:nodes[i] 49 | let last_marker = i is# 0 ? [0] : a:nodes[i - 1]._renderer_nerdfont_marker 50 | let node._renderer_nerdfont_marker = [repeat([0], node._renderer_nerdfont_level)][0] 51 | let current_length = len(node._renderer_nerdfont_marker) 52 | 53 | for ii in range(min([len(last_marker), current_length])) 54 | let node._renderer_nerdfont_marker[ii] = last_marker[ii] 55 | endfor 56 | 57 | if node._renderer_nerdfont_last is# 1 && i isnot# 0 58 | let node._renderer_nerdfont_marker[current_length - 1] = 1 59 | endif 60 | endfor 61 | endif 62 | 63 | let Profile = fern#profile#start('fern#renderer#nerdfont#s:render') 64 | return s:AsyncLambda.map(copy(a:nodes), { v, -> s:render_node(v, base, options) }) 65 | \.finally({ -> Profile() }) 66 | endfunction 67 | 68 | function! s:syntax() abort 69 | syntax match FernLeaf /\s*\zs.*[^/].*$/ transparent contains=FernLeafSymbol 70 | syntax match FernBranch /\s*\zs.*\/.*$/ transparent contains=FernBranchSymbol 71 | syntax match FernRoot /\%1l.*/ transparent contains=FernRootSymbol 72 | execute printf( 73 | \ 'syntax match FernRootSymbol /%s/ contained nextgroup=FernRootText', 74 | \ escape(g:fern#renderer#nerdfont#root_symbol, s:PATTERN), 75 | \) 76 | 77 | syntax match FernLeafSymbol /. / contained nextgroup=FernLeafText 78 | syntax match FernBranchSymbol /. / contained nextgroup=FernBranchText 79 | 80 | syntax match FernRootText /.*\ze.*$/ contained nextgroup=FernBadgeSep 81 | syntax match FernLeafText /.*\ze.*$/ contained nextgroup=FernBadgeSep 82 | syntax match FernBranchText /.*\ze.*$/ contained nextgroup=FernBadgeSep 83 | syntax match FernBadgeSep // contained conceal nextgroup=FernBadge 84 | syntax match FernBadge /.*/ contained 85 | 86 | syntax match FernIndentMarkers /[│└]/ 87 | setlocal concealcursor=nvic conceallevel=2 88 | endfunction 89 | 90 | function! s:highlight() abort 91 | highlight default link FernRootSymbol Comment 92 | highlight default link FernRootText Comment 93 | highlight default link FernLeafSymbol Directory 94 | highlight default link FernLeafText None 95 | highlight default link FernBranchSymbol Statement 96 | highlight default link FernBranchText Statement 97 | highlight default link FernIndentMarkers NonText 98 | endfunction 99 | 100 | function! s:render_node(node, base, options) abort 101 | let level = len(a:node.__key) - a:base 102 | if level is# 0 103 | let suffix = a:node.label =~# '/$' ? '' : '/' 104 | let padding = a:options.root_symbol ==# '' ? '' : a:options.padding 105 | return a:options.root_leading . a:options.root_symbol . padding . a:node.label . suffix . '' . a:node.badge 106 | endif 107 | let leading = '' 108 | 109 | if a:options.indent_markers 110 | let indent_length = len(a:node._renderer_nerdfont_marker) 111 | 112 | for i in range(indent_length) 113 | let indent = a:node._renderer_nerdfont_marker[i] 114 | 115 | if indent is# 0 116 | let leading = leading . '│ ' 117 | elseif indent is# 1 && i is# indent_length - 1 118 | let leading = leading . '└ ' 119 | else 120 | let leading = leading . ' ' 121 | endif 122 | endfor 123 | else 124 | let leading = repeat(a:options.leading, level - 1) 125 | endif 126 | 127 | let symbol = s:get_node_symbol(a:node) 128 | let suffix = a:node.status ? '/' : '' 129 | return a:options.root_leading . leading . symbol . a:node.label . suffix . '' . a:node.badge 130 | endfunction 131 | 132 | function! s:get_node_symbol(node) abort 133 | if a:node.status is# s:STATUS_NONE 134 | let symbol = s:find(a:node.bufname, 0) 135 | elseif a:node.status is# s:STATUS_COLLAPSED 136 | let symbol = s:find(a:node.bufname, 'close') 137 | else 138 | let symbol = s:find(a:node.bufname, 'open') 139 | endif 140 | return symbol 141 | endfunction 142 | 143 | " Check if nerdfont has installed or not 144 | try 145 | call nerdfont#find('') 146 | function! s:find(bufname, isdir) abort 147 | return nerdfont#find(a:bufname, a:isdir) . g:fern#renderer#nerdfont#padding 148 | endfunction 149 | catch /^Vim\%((\a\+)\)\=:E117:/ 150 | function! s:find(bufname, isdir) abort 151 | return a:isdir is# 0 ? '| ' : a:isdir ==# 'open' ? '|- ' : '|+ ' 152 | endfunction 153 | call fern#logger#error( 154 | \ 'nerdfont.vim is not installed. fern-renderer-nerdfont.vim requires nerdfont.vim', 155 | \) 156 | endtry 157 | 158 | call s:Config.config(expand(':p'), { 159 | \ 'leading': ' ', 160 | \ 'padding': ' ', 161 | \ 'root_symbol': '', 162 | \ 'indent_markers': 0, 163 | \ 'root_leading': ' ', 164 | \}) 165 | 166 | let g:fern#renderer#nerdfont#root_leading = get(g:, 'fern#renderer#nerdfont#root_leading', g:fern#renderer#nerdfont#leading) 167 | -------------------------------------------------------------------------------- /doc/fern-renderer-nerdfont.txt: -------------------------------------------------------------------------------- 1 | *fern-renderer-nerdfont.txt* fern plugin to render nerdfont 2 | 3 | ============================================================================= 4 | CONTENTS *fern-renderer-nerdfont-contents* 5 | 6 | INTRODUCTION |fern-renderer-nerdfont-introduction| 7 | USAGE |fern-renderer-nerdfont-usage| 8 | INTERFACE |fern-renderer-nerdfont-interface| 9 | VARIABLE |fern-renderer-nerdfont-variable| 10 | COLORS |fern-renderer-nerdfont-colors| 11 | 12 | 13 | ============================================================================= 14 | INTRODUCTION *fern-renderer-nerdfont-introduction* 15 | 16 | *fern-renderer-nerdfont.vim* is a |fern.vim| plugin which add nerdfont 17 | support. 18 | 19 | 20 | ============================================================================= 21 | USAGE *fern-renderer-nerdfont-usage* 22 | 23 | Install https://github.com/lambdalisue/nerdfont.vim and set "nerdfont" to 24 | |g:fern#renderer| like: 25 | > 26 | let g:fern#renderer = "nerdfont" 27 | < 28 | 29 | ============================================================================= 30 | INTERFACE *fern-renderer-nerdfont-interface* 31 | 32 | ----------------------------------------------------------------------------- 33 | VARIABLE *fern-renderer-nerdfont-variable* 34 | 35 | *g:fern#renderer#nerdfont#leading* 36 | A |String| which is prepended to each node to indicates the nested 37 | level of the node. 38 | 39 | For example, when the value is "~~", the renderer output become: 40 | > 41 | root 42 | |- deep 43 | ~~|- alpha 44 | ~~~~|- beta 45 | ~~~~~~| gamma 46 | < 47 | Default: " " 48 | 49 | *g:fern#renderer#nerdfont#padding* 50 | A |String| which is placed between the symobl and the label. 51 | Add more spaces to regulate the position of the label after the 52 | symbol. 53 | Default: " " 54 | 55 | *g:fern#renderer#nerdfont#root_symbol* 56 | A |String| used as a symbol of root node. 57 | Default: "" 58 | 59 | *g:fern#renderer#nerdfont#indent_markers* 60 | Set 1 to enable fern indent markers. 61 | Enabling this option may affect performance. 62 | Default: 0 63 | 64 | *g:fern#renderer#nerdfont#root_leading* 65 | A |String| to add a lead (padding) in front 66 | of the root level nodes. 67 | Default: |g:fern#renderer#nerdfont#leading| 68 | 69 | Example, with root_leading set to "" (shown below with 70 | *number* set): 71 | > 72 | 1│root 73 | 2│ file1.txt 74 | 3│ file2.txt 75 | < 76 | With root_leading set to "@ ": 77 | > 78 | 1│@ root 79 | 2│@  file1.txt 80 | 3│@  file2.txt 81 | < 82 | 83 | ----------------------------------------------------------------------------- 84 | COLORS *fern-renderer-nerdfont-colors* 85 | 86 | Use glyph-palette.vim to apply colors on Nerd Fonts. 87 | https://github.com/lambdalisue/glyph-palette.vim 88 | 89 | 90 | ============================================================================= 91 | vim:tw=78:fo=tcq2mM:ts=8:ft=help:norl 92 | -------------------------------------------------------------------------------- /plugin/fern_renderer_nerdfont.vim: -------------------------------------------------------------------------------- 1 | if exists('g:fern_renderer_nerdfont_loaded') 2 | finish 3 | endif 4 | let g:fern_renderer_nerdfont_loaded = 1 5 | 6 | call extend(g:fern#renderers, { 7 | \ 'nerdfont': function('fern#renderer#nerdfont#new'), 8 | \}) 9 | --------------------------------------------------------------------------------