1 " unicodePlugin : A completion plugin for Unicode glyphs
2 " Author: C.Brabandt <cb@256bit.org>
4 " Copyright: (c) 2009 by Christian Brabandt
5 " The VIM LICENSE applies to unicode.vim, and unicode.txt
6 " (see |copyright|) except use "unicode" instead of "Vim".
7 " No warranty, express or implied.
8 " *** *** Use At-Your-Own-Risk! *** ***
10 " GetLatestVimScripts: 2822 17 :AutoInstall: unicode.vim
12 " ---------------------------------------------------------------------
15 if exists("g:unicode_URL")
16 let s:unicode_URL=g:unicode_URL
18 "let s:unicode_URL='http://www.unicode.org/Public/UNIDATA/Index.txt'
19 let s:unicode_URL='http://www.unicode.org/Public/UNIDATA/UnicodeData.txt'
21 if !exists("g:UnicodeShowPreviewWindow")
22 let g:UnicodeShowPreviewWindow = 0
27 let s:html[0x0022] = """
28 let s:html[0x0026] = "&"
29 let s:html[0x0027] = "'"
30 let s:html[0x003C] = "<"
31 let s:html[0x003E] = ">"
32 let s:html[0x0022] = """
33 let s:html[0x0026] = "&"
34 let s:html[0x0027] = "'"
35 let s:html[0x003C] = "<"
36 let s:html[0x003E] = ">"
37 let s:html[0x00A0] = " "
38 let s:html[0x00A1] = "¡"
39 let s:html[0x00A2] = "¢"
40 let s:html[0x00A3] = "£"
41 let s:html[0x00A4] = "¤"
42 let s:html[0x00A5] = "¥"
43 let s:html[0x00A6] = "¦"
44 let s:html[0x00A7] = "§"
45 let s:html[0x00A8] = "¨"
46 let s:html[0x00A9] = "©"
47 let s:html[0x00AA] = "ª"
48 let s:html[0x00AB] = "«"
49 let s:html[0x00AC] = "¬"
50 let s:html[0x00AD] = "­"
51 let s:html[0x00AE] = "®"
52 let s:html[0x00AF] = "¯"
53 let s:html[0x00B0] = "°"
54 let s:html[0x00B1] = "±"
55 let s:html[0x00B2] = "²"
56 let s:html[0x00B3] = "³"
57 let s:html[0x00B4] = "´"
58 let s:html[0x00B5] = "µ"
59 let s:html[0x00B6] = "¶"
60 let s:html[0x00B7] = "·"
61 let s:html[0x00B8] = "¸"
62 let s:html[0x00B9] = "¹"
63 let s:html[0x00BA] = "º"
64 let s:html[0x00BB] = "»"
65 let s:html[0x00BC] = "¼"
66 let s:html[0x00BD] = "½"
67 let s:html[0x00BE] = "¾"
68 let s:html[0x00BF] = "¿"
69 let s:html[0x00C0] = "À"
70 let s:html[0x00C1] = "Á"
71 let s:html[0x00C2] = "Â"
72 let s:html[0x00C3] = "Ã"
73 let s:html[0x00C4] = "Ä"
74 let s:html[0x00C5] = "Å"
75 let s:html[0x00C6] = "Æ"
76 let s:html[0x00C7] = "Ç"
77 let s:html[0x00C8] = "È"
78 let s:html[0x00C9] = "É"
79 let s:html[0x00CA] = "Ê"
80 let s:html[0x00CB] = "Ë"
81 let s:html[0x00CC] = "Ì"
82 let s:html[0x00CD] = "Í"
83 let s:html[0x00CE] = "Î"
84 let s:html[0x00CF] = "Ï"
85 let s:html[0x00D0] = "Ð"
86 let s:html[0x00D1] = "Ñ"
87 let s:html[0x00D2] = "Ò"
88 let s:html[0x00D3] = "Ó"
89 let s:html[0x00D4] = "Ô"
90 let s:html[0x00D5] = "Õ"
91 let s:html[0x00D6] = "Ö"
92 let s:html[0x00D7] = "×"
93 let s:html[0x00D8] = "Ø"
94 let s:html[0x00D9] = "Ù"
95 let s:html[0x00DA] = "Ú"
96 let s:html[0x00DB] = "Û"
97 let s:html[0x00DC] = "Ü"
98 let s:html[0x00DD] = "Ý"
99 let s:html[0x00DE] = "Þ"
100 let s:html[0x00DF] = "ß"
101 let s:html[0x00E0] = "à"
102 let s:html[0x00E1] = "á"
103 let s:html[0x00E2] = "â"
104 let s:html[0x00E3] = "ã"
105 let s:html[0x00E4] = "ä"
106 let s:html[0x00E5] = "å"
107 let s:html[0x00E6] = "æ"
108 let s:html[0x00E7] = "ç"
109 let s:html[0x00E8] = "è"
110 let s:html[0x00E9] = "é"
111 let s:html[0x00EA] = "ê"
112 let s:html[0x00EB] = "ë"
113 let s:html[0x00EC] = "ì"
114 let s:html[0x00ED] = "í"
115 let s:html[0x00EE] = "î"
116 let s:html[0x00EF] = "ï"
117 let s:html[0x00F0] = "ð"
118 let s:html[0x00F1] = "ñ"
119 let s:html[0x00F2] = "ò"
120 let s:html[0x00F3] = "ó"
121 let s:html[0x00F4] = "ô"
122 let s:html[0x00F5] = "õ"
123 let s:html[0x00F6] = "ö"
124 let s:html[0x00F7] = "÷"
125 let s:html[0x00F8] = "ø"
126 let s:html[0x00F9] = "ù"
127 let s:html[0x00FA] = "ú"
128 let s:html[0x00FB] = "û"
129 let s:html[0x00FC] = "ü"
130 let s:html[0x00FD] = "ý"
131 let s:html[0x00FE] = "þ"
132 let s:html[0x00FF] = "ÿ"
133 let s:html[0x0152] = "Œ"
134 let s:html[0x0153] = "œ"
135 let s:html[0x0160] = "Š"
136 let s:html[0x0161] = "š"
137 let s:html[0x0178] = "Ÿ"
138 let s:html[0x0192] = "ƒ"
139 let s:html[0x02C6] = "ˆ"
140 let s:html[0x02DC] = "˜"
141 let s:html[0x0391] = "Α"
142 let s:html[0x0392] = "Β"
143 let s:html[0x0393] = "Γ"
144 let s:html[0x0394] = "Δ"
145 let s:html[0x0395] = "Ε"
146 let s:html[0x0396] = "Ζ"
147 let s:html[0x0397] = "Η"
148 let s:html[0x0398] = "Θ"
149 let s:html[0x0399] = "Ι"
150 let s:html[0x039A] = "Κ"
151 let s:html[0x039B] = "Λ"
152 let s:html[0x039C] = "Μ"
153 let s:html[0x039D] = "Ν"
154 let s:html[0x039E] = "Ξ"
155 let s:html[0x039F] = "Ο"
156 let s:html[0x03A0] = "Π"
157 let s:html[0x03A1] = "Ρ"
158 let s:html[0x03A3] = "Σ"
159 let s:html[0x03A4] = "Τ"
160 let s:html[0x03A5] = "Υ"
161 let s:html[0x03A6] = "Φ"
162 let s:html[0x03A7] = "Χ"
163 let s:html[0x03A8] = "Ψ"
164 let s:html[0x03A9] = "Ω"
165 let s:html[0x03B1] = "α"
166 let s:html[0x03B2] = "β"
167 let s:html[0x03B3] = "γ"
168 let s:html[0x03B4] = "δ"
169 let s:html[0x03B5] = "ε"
170 let s:html[0x03B6] = "ζ"
171 let s:html[0x03B7] = "η"
172 let s:html[0x03B8] = "θ"
173 let s:html[0x03B9] = "ι"
174 let s:html[0x03BA] = "κ"
175 let s:html[0x03BB] = "λ"
176 let s:html[0x03BC] = "μ"
177 let s:html[0x03BD] = "ν"
178 let s:html[0x03BE] = "ξ"
179 let s:html[0x03BF] = "ο"
180 let s:html[0x03C0] = "π"
181 let s:html[0x03C1] = "ρ"
182 let s:html[0x03C2] = "ς"
183 let s:html[0x03C3] = "σ"
184 let s:html[0x03C4] = "τ"
185 let s:html[0x03C5] = "υ"
186 let s:html[0x03C6] = "φ"
187 let s:html[0x03C7] = "χ"
188 let s:html[0x03C8] = "ψ"
189 let s:html[0x03C9] = "ω"
190 let s:html[0x03D1] = "ϑ"
191 let s:html[0x03D2] = "ϒ"
192 let s:html[0x03D6] = "ϖ"
193 let s:html[0x2002] = " "
194 let s:html[0x2003] = " "
195 let s:html[0x2009] = " "
196 let s:html[0x200C] = "‌"
197 let s:html[0x200D] = "‍"
198 let s:html[0x200E] = "‎"
199 let s:html[0x200F] = "‏"
200 let s:html[0x2013] = "–"
201 let s:html[0x2014] = "—"
202 let s:html[0x2018] = "‘"
203 let s:html[0x2019] = "’"
204 let s:html[0x201A] = "‚"
205 let s:html[0x201C] = "“"
206 let s:html[0x201D] = "”"
207 let s:html[0x201E] = "„"
208 let s:html[0x2020] = "†"
209 let s:html[0x2021] = "‡"
210 let s:html[0x2022] = "•"
211 let s:html[0x2026] = "…"
212 let s:html[0x2030] = "‰"
213 let s:html[0x2032] = "′"
214 let s:html[0x2033] = "″"
215 let s:html[0x2039] = "‹"
216 let s:html[0x203A] = "›"
217 let s:html[0x203E] = "‾"
218 let s:html[0x2044] = "⁄"
219 let s:html[0x20AC] = "€"
220 let s:html[0x2111] = "ℑ"
221 let s:html[0x2118] = "℘"
222 let s:html[0x211C] = "ℜ"
223 let s:html[0x2122] = "™"
224 let s:html[0x2135] = "ℵ"
225 let s:html[0x2190] = "←"
226 let s:html[0x2191] = "↑"
227 let s:html[0x2192] = "→"
228 let s:html[0x2193] = "↓"
229 let s:html[0x2194] = "↔"
230 let s:html[0x21B5] = "↵"
231 let s:html[0x21D0] = "⇐"
232 let s:html[0x21D1] = "⇑"
233 let s:html[0x21D2] = "⇒"
234 let s:html[0x21D3] = "⇓"
235 let s:html[0x21D4] = "⇔"
236 let s:html[0x2200] = "∀"
237 let s:html[0x2202] = "∂"
238 let s:html[0x2203] = "∃"
239 let s:html[0x2205] = "∅"
240 let s:html[0x2207] = "∇"
241 let s:html[0x2208] = "∈"
242 let s:html[0x2209] = "∉"
243 let s:html[0x220B] = "∋"
244 let s:html[0x220F] = "∏"
245 let s:html[0x2211] = "∑"
246 let s:html[0x2212] = "−"
247 let s:html[0x2217] = "∗"
248 let s:html[0x221A] = "√"
249 let s:html[0x221D] = "∝"
250 let s:html[0x221E] = "∞"
251 let s:html[0x2220] = "∠"
252 let s:html[0x2227] = "∧"
253 let s:html[0x2228] = "∨"
254 let s:html[0x2229] = "∩"
255 let s:html[0x222A] = "∪"
256 let s:html[0x222B] = "∫"
257 let s:html[0x2234] = "∴"
258 let s:html[0x223C] = "∼"
259 let s:html[0x2245] = "≅"
260 let s:html[0x2248] = "≈"
261 let s:html[0x2260] = "≠"
262 let s:html[0x2261] = "≡"
263 let s:html[0x2264] = "≤"
264 let s:html[0x2265] = "≥"
265 let s:html[0x2282] = "⊂"
266 let s:html[0x2283] = "⊃"
267 let s:html[0x2284] = "⊄"
268 let s:html[0x2286] = "⊆"
269 let s:html[0x2287] = "⊇"
270 let s:html[0x2295] = "⊕"
271 let s:html[0x2297] = "⊗"
272 let s:html[0x22A5] = "⊥"
273 let s:html[0x22C5] = "⋅"
274 let s:html[0x2308] = "⌈"
275 let s:html[0x2309] = "⌉"
276 let s:html[0x230A] = "⌊"
277 let s:html[0x230B] = "⌋"
278 let s:html[0x2329] = "⟨"
279 let s:html[0x232A] = "⟩"
280 let s:html[0x25CA] = "◊"
281 let s:html[0x2660] = "♠"
282 let s:html[0x2663] = "♣"
283 let s:html[0x2665] = "♥"
284 let s:html[0x2666] = "♦"
287 let s:file=matchstr(s:unicode_URL, '[^/]*$')
289 let s:directory = expand("<sfile>:p:h")."/unicode"
290 let s:UniFile = s:directory . '/UnicodeData.txt'
292 fu! unicode#CompleteUnicode(findstart,base) "{{{1
293 if !exists("s:numeric")
297 let line = getline('.')
298 let start = col('.') - 1
299 while start > 0 && line[start - 1] =~ '\w\|+'
302 if line[start] =~# 'U' && line[start+1] == '+' && col('.')-1 >=start+2
309 if exists("g:showDigraphCode")
310 let s:showDigraphCode=g:showDigraphCode
312 let s:showDigraphCode = 0
315 let complete_list = filter(copy(s:UniDict),
316 \ 'printf("%04X", v:val) =~? "^0*".a:base[2:]')
318 let complete_list = filter(copy(s:UniDict), 'v:key =~? a:base')
320 for [key, value] in sort(items(complete_list), "<sid>CompareList")
321 "let key=matchstr(key, "^[^0-9 ]*")
322 let dg_char=<sid>GetDigraphChars(value)
325 let fstring = printf("U+%04X %s (%s):'%s'", value, key, dg_char,
328 let fstring=printf("U+%04X %s:%s", value, key, nr2char(value))
331 let fstring=printf("U+%04X %s:'%s'", value, key, nr2char(value))
333 let istring = printf("U+%04X %s%s:'%s'", value, key,
334 \ empty(dg_char) ? '' : '('.dg_char.')', nr2char(value))
336 if s:unicode_complete_name
337 let dict = {'word':key, 'abbr':fstring}
338 if g:UnicodeShowPreviewWindow
339 call extend(dict, {'info': istring})
341 call complete_add(dict)
343 let dict = {'word':nr2char(value), 'abbr':fstring}
344 if g:UnicodeShowPreviewWindow
345 call extend(dict, {'info': istring})
347 call complete_add(dict)
358 fu! unicode#CompleteDigraph() "{{{1
359 let prevchar=getline('.')[col('.')-2]
360 let prevchar1=getline('.')[col('.')-3]
361 let dlist=<sid>GetDigraph()
362 if prevchar !~ '\s' && !empty(prevchar)
363 let filter1 = '( v:val[0] == prevchar1 && v:val[1] == prevchar)'
364 let filter2 = 'v:val[0] == prevchar || v:val[1] == prevchar'
366 let dlist1 = filter(copy(dlist), filter1)
368 let dlist = filter(dlist, filter2)
380 let t=matchlist(args, '^\(..\)\s<\?\(..\?\)>\?\s\+\(\d\+\)$')
382 let format=printf("'%s' %s U+%04X",t[1], t[2], t[3])
383 call add(tlist, {'word':nr2char(t[3]), 'abbr':format,
384 \ 'info': printf("Abbrev\tGlyph\tCodepoint\n%s\t%s\tU+%04X",
388 call complete(col, tlist)
392 fu! unicode#SwapCompletion() "{{{1
393 if !exists('s:unicode_complete_name')
394 let s:unicode_complete_name = 1
396 if exists('g:unicode_complete_name')
397 let s:unicode_complete_name = g:unicode_complete_name
399 let s:unicode_complete_name = !s:unicode_complete_name
401 echo "Unicode Completion Names " .
402 \ (s:unicode_complete_name ? 'ON':'OFF')
405 fu! unicode#Init(enable) "{{{1
406 if !exists("s:unicode_complete_name")
407 let s:unicode_complete_name = 0
412 let s:UniDict = <sid>UnicodeDict()
413 setl completefunc=unicode#CompleteUnicode
414 set completeopt+=menuone
415 inoremap <C-X><C-G> <C-R>=unicode#CompleteDigraph()<CR>
416 nnoremap <leader>un :call unicode#SwapCompletion()<CR>
419 if exists("b:oldfunc") && !empty(b:oldfunc)
425 if maparg("<leader>un", 'n')
428 if maparg("<C-X><C-G>")
432 echo "Unicode Completion " . (a:enable? 'ON' : 'OFF')
435 fu! unicode#GetUniChar(...) "{{{1
438 if !exists("s:UniDict")
439 let s:UniDict=<sid>UnicodeDict()
443 " Get glyph at Cursor
444 " need to use redir, cause we also want to capture combining chars
445 redir => a | exe "silent norm! ga" | redir end
446 let a = substitute(a, '\n', '', 'g')
447 " Special case: no character under cursor
449 call add(msg, "'NUL' U+0000 NULL")
450 "call add(msg, "No character under cursor!")
453 let dlist = <sid>GetDigraph()
454 " Split string, in case cursor was on a combining char
455 for item in split(a, 'Octal \d\+\zs \?')
457 let glyph = substitute(item, '^<\(<\?[^>]*>\?\)>.*', '\1', '')
458 let dec = substitute(item, '.*>\?> \+\(\d\+\),.*', '\1', '')
459 " Check for control char (has no name)
460 if dec <= 0x1F || ( dec >= 0x7F && dec <= 0x9F)
464 let dig = filter(copy(dlist), 'v:val =~ ''\D''.dec.''$''')
465 call add(msg, printf("'%s' U+%04X <Control Char> %s", glyph, dec,
466 \ empty(dig) ? '' : '('.dig[0][0:1].')'))
467 " CJK Unigraphs start at U+4E00 and go until U+9FFF
468 elseif dec >= 0x4E00 && dec <= 0x9FFF
469 call add(msg, printf("'%s' U+%04X CJK Ideograph", glyph, dec))
470 elseif dec >= 0xF0000 && dec <= 0xFFFFD
471 call add(msg, printf("'%s' U+%04X character from Plane 15 for private use",
473 elseif dec >= 0x100000 && dec <= 0x10FFFD
474 call add(msg, printf("'%s' U+%04X character from Plane 16 for private use",
477 let dict = filter(copy(s:UniDict), 'v:val == dec')
480 call add(msg, printf("Character '%s' U+%04X not found", glyph, dec))
483 let dig = filter(copy(dlist), 'v:val =~ ''\D''.dec.''$''')
485 let dchar = printf("(%s)", dig[0][0:1])
489 let html = <sid>GetHtmlEntity(dec)
490 call add(msg, printf("'%s' U+%04X %s %s %s", glyph, values(dict)[0],
491 \ keys(dict)[0], dchar, html))
494 if exists("a:1") && !empty(a:1)
495 exe "let @".a:1. "=join(msg)"
498 "call <sid>OutputMessage(msg)
500 call add(msg, printf("Can't determine char under cursor, %s not found", s:UniFile))
503 call <sid>OutputMessage(msg)
507 fu! unicode#OutputDigraphs(match, bang) "{{{1
509 let digit = a:match + 0
510 for dig in sort(<sid>GetDigraph(), '<sid>CompareDigraphs')
511 " display digraphs that match value
512 if dig !~# a:match && digit == 0
515 let item = matchlist(dig, '\(..\)\s\(\%(\s\s\)\|.\{,4\}\)\s\+\(\d\+\)$')
517 " if digit matches, we only want to display digraphs matching the
519 if digit > 0 && digit !~ item[3]
523 let screenwidth += strdisplaywidth(dig) + 2
525 " if the output is too wide, echo an output
526 if screenwidth > &columns || !empty(a:bang)
534 echon item[1]. " ". item[3] . " "
538 fu! <sid>GetDigraphChars(code) "{{{1
539 let dlist = <sid>GetDigraph()
542 let key=matchstr(digraph, '\d\+$')+0
543 let val=split(digraph)
544 let ddict[key] = val[0]
546 return get(ddict, a:code, '')
549 fu! <sid>UnicodeDict() "{{{1
551 let list=readfile(s:UniFile)
553 let val = split(glyph, ";")
555 let dict[Name] = str2nr(val[0],16)
560 fu! <sid>CheckUniFile(force) "{{{1
561 if (!filereadable(s:UniFile) || (getfsize(s:UniFile) == 0)) || a:force
562 call s:WarningMsg("File " . s:UniFile . " does not exist or is zero.")
563 call s:WarningMsg("Let's see, if we can download it.")
564 call s:WarningMsg("If this doesn't work, you should download ")
565 call s:WarningMsg(s:unicode_URL . " and save it as " . s:UniFile)
569 " Use the default download method. You can specify a different one,
570 " using :let g:netrw_http_cmd="wget"
571 exe ":lcd " . s:directory
572 exe "0Nread " . s:unicode_URL
574 exe ":w!" . s:UniFile
575 if getfsize(s:UniFile)==0
576 call s:WarningMsg("Error fetching Unicode File from " . s:unicode_URL)
581 call s:WarningMsg("Please download " . s:unicode_URL)
582 call s:WarningMsg("and save it as " . s:UniFile)
583 call s:WarningMsg("Quitting")
590 fu! <sid>CheckDir() "{{{1
592 if (!isdirectory(s:directory))
593 call mkdir(s:directory)
596 call s:WarningMsg("Error creating Directory: " . s:directory)
599 return <sid>CheckUniFile(0)
602 fu! <sid>GetDigraph() "{{{1
603 if exists("s:dlist") && !empty(s:dlist)
610 let s:dlist=map(split(substitute(digraphs, "\n", ' ', 'g'),
611 \ '..\s<\?.\{1,2\}>\?\s\+\d\{1,5\}\zs'),
612 \ 'substitute(v:val, "^\\s\\+", "", "")')
613 " special case: digraph 57344: starts with 2 spaces
614 "return filter(dlist, 'v:val =~ "57344$"')
615 let idx=match(s:dlist, '57344$')
616 let s:dlist[idx]=' '.s:dlist[idx]
622 fu! <sid>CompareList(l1, l2) "{{{1
623 return a:l1[1] == a:l2[1] ? 0 : a:l1[1] > a:l2[1] ? 1 : -1
626 fu! <sid>CompareDigraphs(d1, d2) "{{{1
627 let d1=matchstr(a:d1, '\d\+$')+0
628 let d2=matchstr(a:d2, '\d\+$')+0
638 fu! <sid>OutputMessage(msg) " {{{1
641 if type(a:msg) == type([])
646 elseif type(a:msg) == type("")
653 fu! <sid>WarningMsg(msg) "{{{1
655 let msg = "UnicodePlugin: " . a:msg
656 if exists(":unsilent") == 2
664 fu! <sid>GetHtmlEntity(hex) "{{{1
665 return get(s:html, a:hex, '')
668 " vim: ts=4 sts=4 fdm=marker com+=l\:\" fdl=0