" unicodePlugin : A completion plugin for Unicode glyphs " Author: C.Brabandt " Version: 0.17 " Copyright: (c) 2009 by Christian Brabandt " The VIM LICENSE applies to unicode.vim, and unicode.txt " (see |copyright|) except use "unicode" instead of "Vim". " No warranty, express or implied. " *** *** Use At-Your-Own-Risk! *** *** " " GetLatestVimScripts: 2822 17 :AutoInstall: unicode.vim " --------------------------------------------------------------------- if exists("g:unicode_URL") let s:unicode_URL=g:unicode_URL else "let s:unicode_URL='http://www.unicode.org/Public/UNIDATA/Index.txt' let s:unicode_URL='http://www.unicode.org/Public/UNIDATA/UnicodeData.txt' endif if !exists("g:UnicodeShowPreviewWindow") let g:UnicodeShowPreviewWindow = 0 endif " HTML entitities let s:html = {} let s:html[0x0022] = """ let s:html[0x0026] = "&" let s:html[0x0027] = "'" let s:html[0x003C] = "<" let s:html[0x003E] = ">" let s:html[0x0022] = """ let s:html[0x0026] = "&" let s:html[0x0027] = "'" let s:html[0x003C] = "<" let s:html[0x003E] = ">" let s:html[0x00A0] = " " let s:html[0x00A1] = "¡" let s:html[0x00A2] = "¢" let s:html[0x00A3] = "£" let s:html[0x00A4] = "¤" let s:html[0x00A5] = "¥" let s:html[0x00A6] = "¦" let s:html[0x00A7] = "§" let s:html[0x00A8] = "¨" let s:html[0x00A9] = "©" let s:html[0x00AA] = "ª" let s:html[0x00AB] = "«" let s:html[0x00AC] = "¬" let s:html[0x00AD] = "­" let s:html[0x00AE] = "®" let s:html[0x00AF] = "¯" let s:html[0x00B0] = "°" let s:html[0x00B1] = "±" let s:html[0x00B2] = "²" let s:html[0x00B3] = "³" let s:html[0x00B4] = "´" let s:html[0x00B5] = "µ" let s:html[0x00B6] = "¶" let s:html[0x00B7] = "·" let s:html[0x00B8] = "¸" let s:html[0x00B9] = "¹" let s:html[0x00BA] = "º" let s:html[0x00BB] = "»" let s:html[0x00BC] = "¼" let s:html[0x00BD] = "½" let s:html[0x00BE] = "¾" let s:html[0x00BF] = "¿" let s:html[0x00C0] = "À" let s:html[0x00C1] = "Á" let s:html[0x00C2] = "Â" let s:html[0x00C3] = "Ã" let s:html[0x00C4] = "Ä" let s:html[0x00C5] = "Å" let s:html[0x00C6] = "Æ" let s:html[0x00C7] = "Ç" let s:html[0x00C8] = "È" let s:html[0x00C9] = "É" let s:html[0x00CA] = "Ê" let s:html[0x00CB] = "Ë" let s:html[0x00CC] = "Ì" let s:html[0x00CD] = "Í" let s:html[0x00CE] = "Î" let s:html[0x00CF] = "Ï" let s:html[0x00D0] = "Ð" let s:html[0x00D1] = "Ñ" let s:html[0x00D2] = "Ò" let s:html[0x00D3] = "Ó" let s:html[0x00D4] = "Ô" let s:html[0x00D5] = "Õ" let s:html[0x00D6] = "Ö" let s:html[0x00D7] = "×" let s:html[0x00D8] = "Ø" let s:html[0x00D9] = "Ù" let s:html[0x00DA] = "Ú" let s:html[0x00DB] = "Û" let s:html[0x00DC] = "Ü" let s:html[0x00DD] = "Ý" let s:html[0x00DE] = "Þ" let s:html[0x00DF] = "ß" let s:html[0x00E0] = "à" let s:html[0x00E1] = "á" let s:html[0x00E2] = "â" let s:html[0x00E3] = "ã" let s:html[0x00E4] = "ä" let s:html[0x00E5] = "å" let s:html[0x00E6] = "æ" let s:html[0x00E7] = "ç" let s:html[0x00E8] = "è" let s:html[0x00E9] = "é" let s:html[0x00EA] = "ê" let s:html[0x00EB] = "ë" let s:html[0x00EC] = "ì" let s:html[0x00ED] = "í" let s:html[0x00EE] = "î" let s:html[0x00EF] = "ï" let s:html[0x00F0] = "ð" let s:html[0x00F1] = "ñ" let s:html[0x00F2] = "ò" let s:html[0x00F3] = "ó" let s:html[0x00F4] = "ô" let s:html[0x00F5] = "õ" let s:html[0x00F6] = "ö" let s:html[0x00F7] = "÷" let s:html[0x00F8] = "ø" let s:html[0x00F9] = "ù" let s:html[0x00FA] = "ú" let s:html[0x00FB] = "û" let s:html[0x00FC] = "ü" let s:html[0x00FD] = "ý" let s:html[0x00FE] = "þ" let s:html[0x00FF] = "ÿ" let s:html[0x0152] = "Œ" let s:html[0x0153] = "œ" let s:html[0x0160] = "Š" let s:html[0x0161] = "š" let s:html[0x0178] = "Ÿ" let s:html[0x0192] = "ƒ" let s:html[0x02C6] = "ˆ" let s:html[0x02DC] = "˜" let s:html[0x0391] = "Α" let s:html[0x0392] = "Β" let s:html[0x0393] = "Γ" let s:html[0x0394] = "Δ" let s:html[0x0395] = "Ε" let s:html[0x0396] = "Ζ" let s:html[0x0397] = "Η" let s:html[0x0398] = "Θ" let s:html[0x0399] = "Ι" let s:html[0x039A] = "Κ" let s:html[0x039B] = "Λ" let s:html[0x039C] = "Μ" let s:html[0x039D] = "Ν" let s:html[0x039E] = "Ξ" let s:html[0x039F] = "Ο" let s:html[0x03A0] = "Π" let s:html[0x03A1] = "Ρ" let s:html[0x03A3] = "Σ" let s:html[0x03A4] = "Τ" let s:html[0x03A5] = "Υ" let s:html[0x03A6] = "Φ" let s:html[0x03A7] = "Χ" let s:html[0x03A8] = "Ψ" let s:html[0x03A9] = "Ω" let s:html[0x03B1] = "α" let s:html[0x03B2] = "β" let s:html[0x03B3] = "γ" let s:html[0x03B4] = "δ" let s:html[0x03B5] = "ε" let s:html[0x03B6] = "ζ" let s:html[0x03B7] = "η" let s:html[0x03B8] = "θ" let s:html[0x03B9] = "ι" let s:html[0x03BA] = "κ" let s:html[0x03BB] = "λ" let s:html[0x03BC] = "μ" let s:html[0x03BD] = "ν" let s:html[0x03BE] = "ξ" let s:html[0x03BF] = "ο" let s:html[0x03C0] = "π" let s:html[0x03C1] = "ρ" let s:html[0x03C2] = "ς" let s:html[0x03C3] = "σ" let s:html[0x03C4] = "τ" let s:html[0x03C5] = "υ" let s:html[0x03C6] = "φ" let s:html[0x03C7] = "χ" let s:html[0x03C8] = "ψ" let s:html[0x03C9] = "ω" let s:html[0x03D1] = "ϑ" let s:html[0x03D2] = "ϒ" let s:html[0x03D6] = "ϖ" let s:html[0x2002] = " " let s:html[0x2003] = " " let s:html[0x2009] = " " let s:html[0x200C] = "‌" let s:html[0x200D] = "‍" let s:html[0x200E] = "‎" let s:html[0x200F] = "‏" let s:html[0x2013] = "–" let s:html[0x2014] = "—" let s:html[0x2018] = "‘" let s:html[0x2019] = "’" let s:html[0x201A] = "‚" let s:html[0x201C] = "“" let s:html[0x201D] = "”" let s:html[0x201E] = "„" let s:html[0x2020] = "†" let s:html[0x2021] = "‡" let s:html[0x2022] = "•" let s:html[0x2026] = "…" let s:html[0x2030] = "‰" let s:html[0x2032] = "′" let s:html[0x2033] = "″" let s:html[0x2039] = "‹" let s:html[0x203A] = "›" let s:html[0x203E] = "‾" let s:html[0x2044] = "⁄" let s:html[0x20AC] = "€" let s:html[0x2111] = "ℑ" let s:html[0x2118] = "℘" let s:html[0x211C] = "ℜ" let s:html[0x2122] = "™" let s:html[0x2135] = "ℵ" let s:html[0x2190] = "←" let s:html[0x2191] = "↑" let s:html[0x2192] = "→" let s:html[0x2193] = "↓" let s:html[0x2194] = "↔" let s:html[0x21B5] = "↵" let s:html[0x21D0] = "⇐" let s:html[0x21D1] = "⇑" let s:html[0x21D2] = "⇒" let s:html[0x21D3] = "⇓" let s:html[0x21D4] = "⇔" let s:html[0x2200] = "∀" let s:html[0x2202] = "∂" let s:html[0x2203] = "∃" let s:html[0x2205] = "∅" let s:html[0x2207] = "∇" let s:html[0x2208] = "∈" let s:html[0x2209] = "∉" let s:html[0x220B] = "∋" let s:html[0x220F] = "∏" let s:html[0x2211] = "∑" let s:html[0x2212] = "−" let s:html[0x2217] = "∗" let s:html[0x221A] = "√" let s:html[0x221D] = "∝" let s:html[0x221E] = "∞" let s:html[0x2220] = "∠" let s:html[0x2227] = "∧" let s:html[0x2228] = "∨" let s:html[0x2229] = "∩" let s:html[0x222A] = "∪" let s:html[0x222B] = "∫" let s:html[0x2234] = "∴" let s:html[0x223C] = "∼" let s:html[0x2245] = "≅" let s:html[0x2248] = "≈" let s:html[0x2260] = "≠" let s:html[0x2261] = "≡" let s:html[0x2264] = "≤" let s:html[0x2265] = "≥" let s:html[0x2282] = "⊂" let s:html[0x2283] = "⊃" let s:html[0x2284] = "⊄" let s:html[0x2286] = "⊆" let s:html[0x2287] = "⊇" let s:html[0x2295] = "⊕" let s:html[0x2297] = "⊗" let s:html[0x22A5] = "⊥" let s:html[0x22C5] = "⋅" let s:html[0x2308] = "⌈" let s:html[0x2309] = "⌉" let s:html[0x230A] = "⌊" let s:html[0x230B] = "⌋" let s:html[0x2329] = "⟨" let s:html[0x232A] = "⟩" let s:html[0x25CA] = "◊" let s:html[0x2660] = "♠" let s:html[0x2663] = "♣" let s:html[0x2665] = "♥" let s:html[0x2666] = "♦" let s:file=matchstr(s:unicode_URL, '[^/]*$') let s:directory = expand(":p:h")."/unicode" let s:UniFile = s:directory . '/UnicodeData.txt' fu! unicode#CompleteUnicode(findstart,base) "{{{1 if !exists("s:numeric") let s:numeric=0 endif if a:findstart let line = getline('.') let start = col('.') - 1 while start > 0 && line[start - 1] =~ '\w\|+' let start -= 1 endwhile if line[start] =~# 'U' && line[start+1] == '+' && col('.')-1 >=start+2 let s:numeric=1 else let s:numeric=0 endif return start else if exists("g:showDigraphCode") let s:showDigraphCode=g:showDigraphCode else let s:showDigraphCode = 0 endif if s:numeric let complete_list = filter(copy(s:UniDict), \ 'printf("%04X", v:val) =~? "^0*".a:base[2:]') else let complete_list = filter(copy(s:UniDict), 'v:key =~? a:base') endif for [key, value] in sort(items(complete_list), "CompareList") "let key=matchstr(key, "^[^0-9 ]*") let dg_char=GetDigraphChars(value) if s:showDigraphCode if !empty(dg_char) let fstring = printf("U+%04X %s (%s):'%s'", value, key, dg_char, \ nr2char(value)) else let fstring=printf("U+%04X %s:%s", value, key, nr2char(value)) endif else let fstring=printf("U+%04X %s:'%s'", value, key, nr2char(value)) endif let istring = printf("U+%04X %s%s:'%s'", value, key, \ empty(dg_char) ? '' : '('.dg_char.')', nr2char(value)) if s:unicode_complete_name let dict = {'word':key, 'abbr':fstring} if g:UnicodeShowPreviewWindow call extend(dict, {'info': istring}) endif call complete_add(dict) else let dict = {'word':nr2char(value), 'abbr':fstring} if g:UnicodeShowPreviewWindow call extend(dict, {'info': istring}) endif call complete_add(dict) endif if complete_check() break endif endfor return {} endif endfu fu! unicode#CompleteDigraph() "{{{1 let prevchar=getline('.')[col('.')-2] let prevchar1=getline('.')[col('.')-3] let dlist=GetDigraph() if prevchar !~ '\s' && !empty(prevchar) let filter1 = '( v:val[0] == prevchar1 && v:val[1] == prevchar)' let filter2 = 'v:val[0] == prevchar || v:val[1] == prevchar' let dlist1 = filter(copy(dlist), filter1) if empty(dlist1) let dlist = filter(dlist, filter2) let col=col('.')-1 else let dlist = dlist1 let col=col('.')-2 endif unlet dlist1 else let col=col('.') endif let tlist=[] for args in dlist let t=matchlist(args, '^\(..\)\s<\?\(..\?\)>\?\s\+\(\d\+\)$') if !empty(t) let format=printf("'%s' %s U+%04X",t[1], t[2], t[3]) call add(tlist, {'word':nr2char(t[3]), 'abbr':format, \ 'info': printf("Abbrev\tGlyph\tCodepoint\n%s\t%s\tU+%04X", \ t[1],t[2],t[3])}) endif endfor call complete(col, tlist) return '' endfu fu! unicode#SwapCompletion() "{{{1 if !exists('s:unicode_complete_name') let s:unicode_complete_name = 1 endif if exists('g:unicode_complete_name') let s:unicode_complete_name = g:unicode_complete_name else let s:unicode_complete_name = !s:unicode_complete_name endif echo "Unicode Completion Names " . \ (s:unicode_complete_name ? 'ON':'OFF') endfu fu! unicode#Init(enable) "{{{1 if !exists("s:unicode_complete_name") let s:unicode_complete_name = 0 endif if a:enable let b:oldfunc=&l:cfu if (CheckDir()) let s:UniDict = UnicodeDict() setl completefunc=unicode#CompleteUnicode set completeopt+=menuone inoremap =unicode#CompleteDigraph() nnoremap un :call unicode#SwapCompletion() endif else if exists("b:oldfunc") && !empty(b:oldfunc) let &l:cfu=b:oldfunc else setl completefunc= endif unlet! s:UniDict if maparg("un", 'n') nunmap un endif if maparg("") iunmap endif endif echo "Unicode Completion " . (a:enable? 'ON' : 'OFF') endfu fu! unicode#GetUniChar(...) "{{{1 try if (CheckDir()) if !exists("s:UniDict") let s:UniDict=UnicodeDict() endif let msg = [] " Get glyph at Cursor " need to use redir, cause we also want to capture combining chars redir => a | exe "silent norm! ga" | redir end let a = substitute(a, '\n', '', 'g') " Special case: no character under cursor if a == 'NUL' call add(msg, "'NUL' U+0000 NULL") "call add(msg, "No character under cursor!") return endif let dlist = GetDigraph() " Split string, in case cursor was on a combining char for item in split(a, 'Octal \d\+\zs \?') let glyph = substitute(item, '^<\(<\?[^>]*>\?\)>.*', '\1', '') let dec = substitute(item, '.*>\?> \+\(\d\+\),.*', '\1', '') " Check for control char (has no name) if dec <= 0x1F || ( dec >= 0x7F && dec <= 0x9F) if dec == 0 let dec = 10 endif let dig = filter(copy(dlist), 'v:val =~ ''\D''.dec.''$''') call add(msg, printf("'%s' U+%04X %s", glyph, dec, \ empty(dig) ? '' : '('.dig[0][0:1].')')) " CJK Unigraphs start at U+4E00 and go until U+9FFF elseif dec >= 0x4E00 && dec <= 0x9FFF call add(msg, printf("'%s' U+%04X CJK Ideograph", glyph, dec)) elseif dec >= 0xF0000 && dec <= 0xFFFFD call add(msg, printf("'%s' U+%04X character from Plane 15 for private use", \ glyph, dec)) elseif dec >= 0x100000 && dec <= 0x10FFFD call add(msg, printf("'%s' U+%04X character from Plane 16 for private use", \ glyph, dec)) else let dict = filter(copy(s:UniDict), 'v:val == dec') if empty(dict) " not found call add(msg, printf("Character '%s' U+%04X not found", glyph, dec)) return endif let dig = filter(copy(dlist), 'v:val =~ ''\D''.dec.''$''') if !empty(dig) let dchar = printf("(%s)", dig[0][0:1]) else let dchar = '' endif let html = GetHtmlEntity(dec) call add(msg, printf("'%s' U+%04X %s %s %s", glyph, values(dict)[0], \ keys(dict)[0], dchar, html)) endif endfor if exists("a:1") && !empty(a:1) exe "let @".a:1. "=join(msg)" endif "call OutputMessage(msg) else call add(msg, printf("Can't determine char under cursor, %s not found", s:UniFile)) endif finally call OutputMessage(msg) endtry endfun fu! unicode#OutputDigraphs(match, bang) "{{{1 let screenwidth = 0 let digit = a:match + 0 for dig in sort(GetDigraph(), 'CompareDigraphs') " display digraphs that match value if dig !~# a:match && digit == 0 continue endif let item = matchlist(dig, '\(..\)\s\(\%(\s\s\)\|.\{,4\}\)\s\+\(\d\+\)$') " if digit matches, we only want to display digraphs matching the " decimal values if digit > 0 && digit !~ item[3] continue endif let screenwidth += strdisplaywidth(dig) + 2 " if the output is too wide, echo an output if screenwidth > &columns || !empty(a:bang) let screenwidth = 0 echon "\n" endif echohl Title echon item[2] echohl Normal echon item[1]. " ". item[3] . " " endfor endfu fu! GetDigraphChars(code) "{{{1 let dlist = GetDigraph() let ddict = {} for digraph in dlist let key=matchstr(digraph, '\d\+$')+0 let val=split(digraph) let ddict[key] = val[0] endfor return get(ddict, a:code, '') endfu fu! UnicodeDict() "{{{1 let dict={} let list=readfile(s:UniFile) for glyph in list let val = split(glyph, ";") let Name = val[1] let dict[Name] = str2nr(val[0],16) endfor return dict endfu fu! CheckUniFile(force) "{{{1 if (!filereadable(s:UniFile) || (getfsize(s:UniFile) == 0)) || a:force call s:WarningMsg("File " . s:UniFile . " does not exist or is zero.") call s:WarningMsg("Let's see, if we can download it.") call s:WarningMsg("If this doesn't work, you should download ") call s:WarningMsg(s:unicode_URL . " and save it as " . s:UniFile) sleep 10 if exists(":Nread") sp +enew " Use the default download method. You can specify a different one, " using :let g:netrw_http_cmd="wget" exe ":lcd " . s:directory exe "0Nread " . s:unicode_URL $d _ exe ":w!" . s:UniFile if getfsize(s:UniFile)==0 call s:WarningMsg("Error fetching Unicode File from " . s:unicode_URL) return 0 endif bw else call s:WarningMsg("Please download " . s:unicode_URL) call s:WarningMsg("and save it as " . s:UniFile) call s:WarningMsg("Quitting") return 0 endif endif return 1 endfu fu! CheckDir() "{{{1 try if (!isdirectory(s:directory)) call mkdir(s:directory) endif catch call s:WarningMsg("Error creating Directory: " . s:directory) return 0 endtry return CheckUniFile(0) endfu fu! GetDigraph() "{{{1 if exists("s:dlist") && !empty(s:dlist) return s:dlist else redir => digraphs silent digraphs redir END let s:dlist=[] let s:dlist=map(split(substitute(digraphs, "\n", ' ', 'g'), \ '..\s<\?.\{1,2\}>\?\s\+\d\{1,5\}\zs'), \ 'substitute(v:val, "^\\s\\+", "", "")') " special case: digraph 57344: starts with 2 spaces "return filter(dlist, 'v:val =~ "57344$"') let idx=match(s:dlist, '57344$') let s:dlist[idx]=' '.s:dlist[idx] return s:dlist endif endfu fu! CompareList(l1, l2) "{{{1 return a:l1[1] == a:l2[1] ? 0 : a:l1[1] > a:l2[1] ? 1 : -1 endfu fu! CompareDigraphs(d1, d2) "{{{1 let d1=matchstr(a:d1, '\d\+$')+0 let d2=matchstr(a:d2, '\d\+$')+0 if d1 == d2 return 0 elseif d1 > d2 return 1 else return -1 endif endfu fu! OutputMessage(msg) " {{{1 redraw echohl Title if type(a:msg) == type([]) " List for item in a:msg echom item endfor elseif type(a:msg) == type("") " string echom a:msg endif echohl Normal endfu fu! WarningMsg(msg) "{{{1 echohl WarningMsg let msg = "UnicodePlugin: " . a:msg if exists(":unsilent") == 2 unsilent echomsg msg else echomsg msg endif echohl Normal endfun fu! GetHtmlEntity(hex) "{{{1 return get(s:html, a:hex, '') endfu " Modeline "{{{1 " vim: ts=4 sts=4 fdm=marker com+=l\:\" fdl=0