0

I am writing a small plugin to manage my address book (the actual plugin interfaces with the abook program). I use a special buffer (nofile) and I redraw the entire buffer each time something changes.

I create the buffer (and have a mapping to call this function)

" creates a special buffer
function! MkAbook()
  let g:abook_prevbuf = bufnr('%')  " save current buffer
  if g:abook_buf
    execute 'buffer ' . string(g:abook_buf)
  else
    edit [abook]
  endif
  setlocal buftype=nofile
  setlocal nomodifiable
  setlocal filetype=abook
  setlocal nobuflisted
  call AbookDraw()
endfunction

And I clear and draw the entire buffer when it opens (and when it is changed).

" fakes a change in buffer
function! AbookDraw()
  " this is a dummy variable, I actually build it from a file
  let b:dict = {
  \   'header1' : 'content1'
  \ , 'header2' : 'content2'
  \ }
  setlocal modifiable
  " clear the buffer
  normal ggdG
  put! ='abook list'
  put  ='=========='
  put  =''
  for k in keys(b:dict)
    put ='[' . k . ']'
    put =b:dict[k]
    put =''
  endfor
  setlocal nomodifiable
  setlocal nomodified
endfunction

My issue is that put ='string' seems like a hack. I am also worried about the execution speed. Other options I have thought of are:

let content  = "abook list\n"
let content += "==========\n"
...
put =content

And

let content = []
call add(content, "abook list")
call add(content, "==========")
...
call append(line('$'), content)

Which is the most efficient way to perform this?

(I believe that, once the amount of things to redraw everytime becomes big, execution speed will become important.)


In other words, the question is about execution speed. I do not yet have a buffer big enough to measure the execution speed of each method in a consistent manner.

Has anyone measured Vim's execution speed of different draw-an-entire-buffer methods?

7
  • I'm not sure I understand exactly what problem you're trying to solve, but would UltiSnips fit the bill? Jul 31 '16 at 6:40
  • 1
    You could build a list with let foo = [ "abook list", "==========", ... ] and replace the content of the buffer with call setline(1, foo).
    – romainl
    Jul 31 '16 at 12:55
  • @SatoKatsura - ultisnips is nice but it is python based, limits my ability to use it on crap machines (read: AIX). In general i'm looking for a theoretical execution speed difference, or a way to properly measure the execution speed.
    – grochmal
    Jul 31 '16 at 15:37
  • 1
    I still don't have the faintest idea what problem you're trying to solve. That is, I understand what you're saying, but I fail to make sense of it. To measure execution speed of Vim commands see :h profile and :h reltime(). If you're worried about VimL being slow then generate the buffer by some other means (shell script, Perl, whatever) and read it in Vim. Jul 31 '16 at 16:58
  • 1
    put is no hack. But if you are need to setup several lines, it is usually easiest to use setline() or append() Cannot tell, how much difference this makes from a performance perspective, but my guess is, you won't notice. Jul 31 '16 at 18:09
1

I believe it is fine to use either :put or setline(). But as you are reading the contents from an external program, you could consider :read !:

:[range]r[ead] [++opt] !{cmd}
            Execute {cmd} and insert its standard output below
            the cursor or the specified line.  A temporary file is
            used to store the output of the command which is then
            read into the buffer.  'shellredir' is used to save
            the output of the command, which can be set to include
            stderr or not.  {cmd} is executed like with ":!{cmd}",
            any '!' is replaced with the previous command |:!|.
            See |++opt| for the possible values of [++opt].

You could use the regular :read to insert the header from a template file, and :$read! <cmd> to include information from your abook program.

But if it is already working and you don't notice any delays, you should consider leaving it as it is; from the great book "The Practice of Programming":

Thus the first principle of optimization is don't. Is the program good enough already? Knowing how a program will be used and the environment it runs in, is there any benefit to making it faster? Programs written for assignments in a college class are never used again; speed rarely matters. Nor will speed matter for most personal programs, occasional tools, test frameworks, experiments, and prototypes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.