tags:

views:

65

answers:

2

What I have so far:

function! GetMarker()
    return system('echo $random `date` | md5sum | cut -d" " -f1')
endfunction

I would like to be able to do a :getmarker and have it insert the output of that system command at my cursor, with no new lines.

Also what is the difference between function! and function?

Edit: before any of you ask, I need the random string to mark sections in my code so I can find them again by referencing my notes in my todo wiki.

+1  A: 

You can trim/chomp the last newline with matchstr(), substitute, [:-2], etc

function s:GetMarker()
  let res = system('echo $random `date` | md5sum | cut -d" " -f1')
  " then either
  let res = matchstr(res, '.*\ze\n')
  " or
  let res = res[:-2]
  " or
  let res = substitute(res, '\n$', '', '')
  return res
endfunction
command! -nargs=0 GetMarker put=s:GetMarker()

Banging the function/command definition (with '!') will permit you to source the script where it is defined several times and thus to update the function/command you are maintaining without having to exit vim.

Luc Hermitte
This still inserts the hash on a new line, is there a way to get it to insert at the cursor?
Seamus
Yes. You will have to play with things like exe+normal. But commands are not the best construct for this kind of text manipulation.-> `command! -nargs=0 GetMarker exe "normal \<c-r>=s:GetMarker()\<esc>"`
Luc Hermitte
+1  A: 

Edit1. Take two. Trying to absorb the feedback from Luc. Without temp file (readfile() turned out to be not available in VIM 6.x I have on some systems).

:function InsertCmd( cmd )
:       let l = system( a:cmd )
:       let l = substitute(l, '\n$', '', '')
:       exe "normal a".l
:       redraw!
:endfunction

:imap <silent> <F5> <C-O>:call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>
:map <silent> <F5> :call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>

:put can't be used because it works line-wise. I replaced <Esc>...<Insert> with the all better <C-O>. I left redraw in, as it helps for the cases of called command produces output to the stderr.

Or using <C-R>=:

:function InsertCmd( cmd )
:       let l = system( a:cmd )
:       let l = substitute(l, '\n$', '', '')
:       return l
:endfunction

:imap <silent> <F5> <C-R>=InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>

Also what is the difference between function! and function?

Exclamation on the end of command most of the time means force to execute. (Looking in the :help is advised since different commands use ! differently, but VIM tries to document all forms of the commands.) In the case of the function it tells VIM to override previous definition of the function. E.g. if you put the code above into the func1.vim file, first time :source func1.vim would work fine, but the second time it would fail with error that function InsertCmd is already defined.


I did once before try to implement something similar here. I'm not good at VIM programming, thus it looks lame and the suggestion from Luc should take precedence.

Here it goes anyway:

:function InsertCmd( cmd )
:       exe ':silent !'.a:cmd.' > /tmp/vim.insert.xxx 2>/dev/null'
:       let l = readfile( '/tmp/vim.insert.xxx', '', 1 )
:       exe "normal a".l[0]
:       redraw!
:endfunction

:imap <silent> <F5> <Esc>:call InsertCmd( 'hostname' )<CR><Insert>
:map <silent> <F5> :call InsertCmd( 'hostname' )<CR>

Despite being lame, it works though.

Dummy00001
If there is one issue with your approach, it is related to the temporary file. Multiple users cannot use the same script. It's better to use tempname(). Otherwise, a few things may be enhanced: - no redraw, - return l[0], - and insert it with `<c-r>=` to avoid oddities with the cursor position.
Luc Hermitte
@Luc: `<c-r>=` - very very cool. `tempname()` - good to know too. Thanks for the advises.
Dummy00001
"Exclamation on the end of command means force to execute." That's not true. There are many counter-examples. See `:g`, `:delm`, `:put`, ...
Luc Hermitte
Thanks, this worked quite nicely.
Seamus
@Luc Hermitte: in the `!` part wording is changed. hope now it is better.
Dummy00001