简体   繁体   中英

Advanced vim autocompletion

I am trying to build a lexical analyzer using flex. Following is a line which shows a regular expression and its corresponding action.

[0-9] {printf("yada yada \n");} //regex1

Is there a way to reuse {printf("yada yada \\n");} from regex1 by auto-completion features of vim, so that I don't need to write the whole thing again while writing regex2?

eg

.* {printf("yada yada \n");} //regex2

This goes beyond word completion, so I was wondering is this doable in vim?

TIA

Have a look into :h complete-functions and :h 'completefunc' for details.

Or dive into the code below:

" Scan current buffer for everithing in { }.
fun! GetRegexes()
  let rx = '{.\+}'
  let res = []
  for line in getline(1, '$')
    if line =~ rx
      call add(res, matchstr(line, rx))
    endif
  endfor
  return res
endfun

fun! MyComplete(findstart, base)
  if a:findstart
    " locate the start of the completion
    let line = getline('.')
    let start = col('.') - 1
    while start > 0 && line[start] !~ '{'
      let start -= 1
    endwhile
    return start
  else
    let res = []
    for m in GetRegexes()
      if m =~ '^' . a:base
        call add(res, m)
      endif
    endfor
    return res
  endif
endfun
set completefunc=MyComplete
finish

[0-9] {printf("yada yada \n");}
[0-9] {printf("yada \n");}

If you save this file as compl.vim and source it with :so % command then you'll be able to start typing {pri and press Ctrl - X , Ctrl - U to invoke completion menu with 2 elements:

{printf("yada yada \n");}
{printf("yada \n");}

I believe you can adjust it to your needs.

You can save 2 functions into your .vimrc and set completefunc to MyComlete for buffer where you need that kind of completion.

It is not quite auto-completion, but you could define an abbreviation - eg

:iab yada {printf("yada yada \n");} 

Then in insert mode if you type

[0-9] yada<SPACE>

it will instantly replace yada with {printf("yada yada \\n");} .

See :h abbreviations for the full scoop.

Only slightly different than myme's answer:

  1. Navigate to the first brace {
  2. Enter visual mode with v
  3. Press % to navigate to the end of the block, until the last brace }
  4. y ank it.
  5. p aste it, wherever. :-)

Well, it might not be auto-completion, but it might do the trick for you. You could just save that action/print statement to a copy register in vim, and just paste it when it's appropriate.

  1. Navigate to the beginning of the action.
  2. Go to visual mode: v
  3. Move over the part of the text you want to copy/yank.
  4. To yank into register '1', type: "1y

Now the action is stored in register number one.

  1. Paste the content by doing: "1p (that p can be any paste command).

Hope this proves to be useful :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM