views:

295

answers:

4

Hi

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?

e.g.

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

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

TIA

A: 

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 :)

myme
thanks, but I didn't want this, I know storing in registers("aymotion) would do, but I was looking for some divine auto completion :P
Aman Jain
I'm not entirely certain "Autocomplete" really describes what you're doing here.
Bryan Ross
A: 

It is not quite auto-completion, but you could define an abbreviation - e.g.

: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.

Dave Kirby
no, that was just an example, i meant in general, one can't keep on adding abbreviations.
Aman Jain
+1  A: 

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. yank it.
  5. paste it, wherever. :-)
Michael Foukarakis
+3  A: 

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.

Maxim Kim