Hi Christian,

On Tue, Feb 17, at 12:03 Christian Brabandt wrote:

> 
> Not bad! I have been thinking about it, and one could even implement a 
> custom completion function. You need to get 
> http://www.unicode.org/Public/UNIDATA/Index.txt and set the readfile() 
> expression according to the location of Index.txt Something simple 
> like this script could then be used to enter the characters.
> 
> ,----
> | function! CompleteDigraph(findstart,base)
> |   if a:findstart
> |     let line = getline('.')
> |     let start = col('.') - 1
> |     while start > 0 && line[start - 1] =~ '\a'
> |       let start -= 1
> |     endwhile
> |     return start
> |   else
> |     let list=readfile(expand("~/.vim/Index.txt")))
> |     let i=1
> |     let idx=match(list,a:base)
> |     while ( idx >= 0)
> |       let nr = str2nr(matchstr(list[idx], '\x\+$'),16)
> |       call complete_add({'word':nr2char(nr), 'abbr':list[idx], 'icase':1, 
> 'menu':nr2char(nr)})
> |       let i+=1
> |       let idx=match(list,a:base,0,i)
> |       if complete_check()
> |         break
> |       endif
> |     endwhile
> |     return {}
> |   endif
> | endfun
> | 
> | 
> | set completefunc=CompleteDigraph
> `----
> 
> This messes up the popup menu a little bit and I don't know how to fix 
> it. Other than that, I find it now easy enough to enter all kind of 
> characters. 

Very nice, yes!
It seems, that you can limit the matches on the popup menu, if you
previously entered a combination of letters that matches, like:

    greek<C-X><C-U>

I've never worked again with that kind of complete function and it was
a good chance to understand the mechanism.

Anyway, the problem I see, is that if you have to enter two digraphs on
the row, then scrolling down to the menu is a little bit hard and it's
getting slow, because every time it has to process the huge data file.

So by wondering if some preprocessing would help a little bit, I've tried
to implement another solution, which works in a different way.
I am not completely satisfied either (although both ways are way much
better than to look in the output of :digraphs), because it's a lot of
data to proceed (5330 lines) and in the first invocation it's a little
bit slow, but later is getting fast.


First I've created a dictionary from the Index.txt.
The script to generate the dictionary is attached.

Place those functions in ~/.vim/autoload/digraphs.vim
=================================
let s:digraphs = {
    \  'A WITH ACUTE, LATIN CAPITAL LETTER' : 'Á'  
    \, 'A WITH ACUTE, LATIN SMALL LETTER' : 'á'  
    ...
    another 5330 lines (generated by the attached script
    which it returns a list)
    Source the script and while within Index.txt opened in another
    buffer, use:
    let list = UnitoDic()
    then while on digraphs.vim
    0put = list
    ...
    \ }
 
function! digraph#list(A,L,P)
    let list = []
    for key in sort(keys(s:digraphs))
        call add(list, key.' : '.s:digraphs[key])
    endfor
    return filter(list, 'v:val =~ "^".a:A')
endfunction

function! digraph#complete()
    let digr = s:digraphs[split(input("Digraph: ", "", 
"customlist,digraph#list"), ' : ')[0]]
    return digr
endfunction
=================================

Add the imap in your vimrc.

imap <silent> <C-X><C-D> <C-R>= digraph#complete()<CR>

The nice thing is that you can limit the matches, if you type the
leading letters of the description, and you can use then Control-D or
tab to view and choose one of the Unicode characters.


> Christian

Regards,
Ag.

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

function! UnitoDic()
    let line = 1
    let list = ['let s:digraphs = {']
    while line <= line('$')
        let curline = substitute(getline(line), '''', '', 'g')
        if match(curline, '000A') != -1 || match(curline, '0027') != -1
            let line += 1
            continue
        endif
        let linelist = split(curline)
        let string{line} = join(linelist[:-2])
        if exists("string{line -1}")
            if match(string{line - 1}." $", string{line}) != -1
                let string{line} = string{line - 1}.' '
            endif
        endif
        if line == 1
            call add(list, '    \  '''.string{line}.''' : 
'''.nr2char(str2nr(linelist[-1], 16)).'''')
        else
            call add(list, '    \, '''.string{line}.''' : 
'''.nr2char(str2nr(linelist[-1], 16)).'''')
        endif
        let line += 1
    endwhile
    call add(list, '    \ }')
    return list
endfunction

" vim: et:ts=4 sw=4   

Reply via email to