Skip to content

Commit 213a00b

Browse files
committed
Add Nerd Font Glyph width autofix feature
1 parent a2ac4d9 commit 213a00b

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

autoload/nerdfont.vim

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,14 @@ endfunction
3636

3737
let g:nerdfont#default = get(g:, 'nerdfont#default',
3838
\ g:nerdfont#path#extension#defaults['.'])
39+
40+
if exists('*setcellwidths') && get(g:, 'nerdfont#autofix_cellwidths', 1)
41+
try
42+
call nerdfont#cellwidths#fix()
43+
catch
44+
echohl WarningMsg
45+
echo '[nerdfont]: Failed to fix cellwidths of nerd font glyphs.'
46+
echo '[nerdfont]: Disable this autofix feature by setting `g:nerdfont#autofix_cellwidths` to 0.'
47+
echohl None
48+
endtry
49+
endif

autoload/nerdfont/cellwidths.vim

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
" https://github.com/ryanoasis/nerd-fonts/wiki/Glyph-Sets-and-Code-Points#overview
2+
" Codicons ea60 - ebeb
3+
" Devicons e700 - e7c5
4+
" Font Awesome f000 - f2e0
5+
" Font Awesome Extension e200 - e2a9
6+
" Font Logos f300 - f372
7+
" IEC Power Symbols 23fb - 23fe
8+
" IEC Power Symbols 2b58
9+
" Material Design f0001-f1af0
10+
" Material Design f500 - fd46
11+
" Octicons 2665
12+
" Octicons 26a1
13+
" Octicons f400 - f532
14+
" Pomicons e000 - e00a
15+
" Powerline e0a0 - e0a2
16+
" Powerline e0b0 - e0b3
17+
" Powerline Extra e0a3
18+
" Powerline Extra e0b4 - e0c8
19+
" Powerline Extra e0ca
20+
" Powerline Extra e0cc - e0d4
21+
" Seti-UI + Custom e5fa - e6b1
22+
" Weather Icons e300 - e3e3
23+
const g:nerdfont#cellwidths#code_points = {
24+
\ 'Codicons': [[0xea60, 0xebeb]],
25+
\ 'Devicons': [[0xe700, 0xe7c5]],
26+
\ 'Font Awesome': [[0xf000, 0xf2e0]],
27+
\ 'Font Awesome Extension': [[0xe200, 0xe2a9]],
28+
\ 'Font Logos': [[0xf300, 0xf372]],
29+
\ 'IEC Power Symbols': [[0x23fb, 0x23fe], 0x2b58],
30+
\ 'Material Design': [[0xf0001, 0xf1af0], [0xf500, 0xfd46]],
31+
\ 'Octicons': [0x2665, 0x26a1, [0xf400, 0xf532]],
32+
\ 'Pomicons': [[0xe000, 0xe00a]],
33+
\ 'Powerline': [[0xe0a0, 0xe0a2], [0xe0b0, 0xe0b3]],
34+
\ 'Powerline Extra': [0xe0a3, [0xe0b4, 0xe0c8], 0xe0ca, [0xe0cc, 0xe0d4]],
35+
\ 'Seti-UI + Custom': [[0xe5fa, 0xe6b1]],
36+
\ 'Weather Icons': [[0xe300, 0xe3e3]],
37+
\}
38+
39+
function! nerdfont#cellwidths#fix() abort
40+
let l:values = reduce(values(g:nerdfont#cellwidths#code_points), { a, v -> a + v })
41+
let l:values = map(l:values, {_, v -> type(v) is# v:t_list ? v : [v, v]})
42+
let l:values = s:norm(l:values)
43+
let l:list = map(l:values, {_, v -> type(v) is# v:t_list ? v + [2] : [v, v, 2]})
44+
call setcellwidths(l:list)
45+
endfunction
46+
47+
function! s:compare(lhs, rhs) abort
48+
return a:lhs[0] == a:rhs[0]
49+
\ ? a:lhs[1] == a:rhs[1]
50+
\ ? 0
51+
\ : a:lhs[1] < a:rhs[1]
52+
\ ? -1
53+
\ : 1
54+
\ : a:lhs[0] < a:rhs[0]
55+
\ ? -1
56+
\ : 1
57+
endfunction
58+
59+
function! s:norm(ranges) abort
60+
call uniq(sort(a:ranges, 's:compare'), 's:compare')
61+
let l:oldvalues = a:ranges
62+
let l:newvalues = [a:ranges[0]]
63+
let l:oldsize = len(l:oldvalues)
64+
let l:newsize = len(l:newvalues)
65+
let l:retries = 0
66+
while l:oldsize != l:newsize || l:retries < 5
67+
for l:idx in range(len(l:oldvalues))
68+
let l:lhs = remove(l:newvalues, -1)
69+
let l:rhs = l:oldvalues[l:idx]
70+
call extend(l:newvalues, s:merge(l:lhs, l:rhs))
71+
endfor
72+
call uniq(sort(l:newvalues, 's:compare'), 's:compare')
73+
let l:oldsize = len(l:oldvalues)
74+
let l:newsize = len(l:newvalues)
75+
let l:oldvalues = l:newvalues
76+
let l:retries += 1
77+
endwhile
78+
return l:oldvalues
79+
endfunction
80+
81+
function! s:merge(a, b) abort
82+
if a:a[0] <= a:b[0] && a:b[1] <= a:a[1]
83+
" a: -------------
84+
" b: ------
85+
return [[a:a[0], a:a[1]]]
86+
elseif a:b[0] <= a:a[0] && a:a[1] <= a:b[1]
87+
" a: ------
88+
" b: -------------
89+
return [[a:b[0], a:b[1]]]
90+
elseif a:a[0] <= a:b[0] && a:b[0] <= a:a[1]
91+
" a: --------
92+
" b: ------
93+
return [[a:a[0], max([a:a[1], a:b[1]])]]
94+
elseif a:b[0] <= a:a[0] && a:a[0] <= a:b[1]
95+
" a: ------
96+
" b: --------
97+
return [[a:b[0], max([a:a[1], a:b[1]])]]
98+
endif
99+
return [a:a, a:b]
100+
endfunction

doc/nerdfont.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ VARIABLE *nerdfont-variable*
5454
>
5555
let g:nerdfont#default = 'glyph for default path'
5656
<
57+
*g:nerdfont#autofix_cellwidths*
58+
Automatically set cellwidth of nerdfont glyphs to 2. Disable it if you
59+
faced font width issue.
60+
5761
*g:nerdfont#directory#customs*
5862
A custom glyph mappings for directory.
5963
>

0 commit comments

Comments
 (0)