tags:

views:

177

answers:

3

I have a shared library (in binary form; I have the source) that I use to invert/cycle between symbols in source files in Visual Studio.

I would like to be able to use the same functionality in vi and/or Vim.

Specifically, what I'd like to do is the following scenario:

  • the cursor is on a word
  • I press a key-sequence, e.g. CTRL-I
  • vi/Vim works out the whole of the word I'm on
  • vi/Vim invokes my shared library, passing the word, and receiving the invert/cycle replacement
  • vi/Wim replaces the original word with the new word

I don't have any clue if/how to get vi/Vim to do this, and I'm not having any luck searching.

Any advice gratefully received ...

+6  A: 

Try

inoremap <C-i> <esc>"hciw<C-R>=libcall('path/to/your.dll', 'func', @h)<CR>

What it does:

  • create map for insert mode <Ctrl+i>
  • <esc> switch to normal mode "hciw move word under cursor into the register h
  • <C-r>= insert into cursor position result of the next expression
  • libcall(...) calls function in the run-time library.
  • @h is the value of the 'h' register.

In case you want to use simple binary that can be ran from the command line you can use

inoremap <C-i> <esc>"hciw<C-R>=substitute(system('mybin --word='.@h), "\n", '', 'g')<CR>
Mykola Golubyev
+1 - Thanks, I'll try that out
dcw
+1 - much simpler than my solution!
Paolo Tedesco
NB: libcall() is not one _more_ solution. It is _the_ solution. system() does not answer OP's need: to call a function in a shared library. Moreover system() output must be parsed to trim the "\n$".
Luc Hermitte
@Luc: "In binary form". I though it means "binary" executable.
Mykola Golubyev
It's not all "\n", but the last "\n" that needs to be trimmed.
Luc Hermitte
@Luc: I think it doesn't matter for this case.
Mykola Golubyev
As long it is just a word, it's OK. If it is a multilines code snippet, it does matter. As anyway we are OT already with system(), we can give the simplified "ultimate" system() answer built on matchstr(), or the optimized one using a temporary variable, a test, and [0:-2]/strpart().
Luc Hermitte
+1  A: 

I don't know how to call a shared library from normal vim scripts, but if you can create a python wrapper for your library and you're using vim version greateri than 7, you might do it calling a python script within vim.
First of all, check if you have python support enabled: type

:version

inside vim to list the available features; if it has python support, you should see a '+python' somewhere (a '-python' otherwise). If you do not have python enabled, you may refer to this post to compile vim with python support.

Then, you could could map a key to call a python function with the word currently under the cursor:

python << EOF
import vim
import MySharedLibraryPythonBinding

def MyFunction():
    # get word under cursor
    x = vim.eval('expand ("<cword>")')
    # get replacement
    MySharedLibraryPythonBinding.GetReplacement(x)
    # replace contents (you'll need some work here...)
    vim.current.line = "add something sensible here..."
EOF

nmap <F3> :py MyFunction( expand("<cword>") )<CR>

This is not of course a fully working solution, but I hope it will put you on the good route.

Paolo Tedesco
+1 - Thanks, I'll check it out.
dcw
+1  A: 

There are many ways to do it (:h expand(), ...). One of them is the following)

:nnoremap triggerkeysequence ciw<c-r>=libcall('path/to/your.dll', 'your_function',@")<cr>

BTW: <c-i> is <tab>, are you sure you want to override the action on this key?

Luc Hermitte
+1 - Thanks, I'll check it out.
dcw
BTW, you may have to strip a trailing '\n'. In system() case (which does not respond to your needs), this is sure, in libcall() case I don't know.
Luc Hermitte
Should I update my answer according to your comment?
Mykola Golubyev
Feel free to do as you wish.
Luc Hermitte