Calling into a shared object on a key-sequence from vi/Vim - vim

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

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>

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.

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?

Related

Vim backslash in command

I feel like this is a very stupid question, but I can't seem to find the answer to this anywhere. I'm relatively new to vim. After a fresh install I installed the vim-LaTeX plugin, or the LaTeX-suite for vim. It works correctly apart for the fact that there are some commands I don't understand. It gives the following instruction:
To do this, visually select a portion of the text and press \ll while in visual mode. The visually selected portion will be saved to a temporary file with the preamble from the current document prepended. Latex-Suite will then switch focus to this temporary file and compile it
But if I press '\' it does nothing and double l moves the cursor to the right. I don't understand what I'm supposed to be doing, and I feel incredibly stupid. Sorry if off-topic.
The \ is the default value for the :help <Leader> key. Plugins are encouraged to start all default mappings with <Leader>. If you've redefined it, you need to use that key instead.
Otherwise, you need to press V \ L L (without Shift) in quick succession (by default within one second).
If you want to find out whether the plugin has been successfully installed and there's actually an action behind those keys, you can use either:
:verbose vmap <Leader>ll
:verbose vmap \ll
If Vim says No mapping found, or just lists other mappings starting with some of the keys, the plugin isn't installed properly, or you're not using it right.
Press v to go into visual mode. Then you can use your arrow keys to select text. After you've selected the text you want, type \ll.
That should be it.

vim - navigating characters in command mode

Relatively new to VIM and having a great time using it.
One very minor annoyance I've been having is command mode character navigation when I want to revise a command. I'm used to using readline shortcuts on the regular (non-vim) command line but these shortcuts don't seem to work in : command mode.
For example, using ctrl + b to go back a character ends up sending me to the start of the line, or using alt + f to go forward a word ends up clearing the line and exiting command mode.
The only way I've found to navigate in command mode is to use the arrow keys, but I'm under the impression you should avoid the arrow keys in vim for max efficiency.
What is the standard way to navigate around in : command mode? Do vim users usually use the arrow keys here? Is there a different way to modify commands?
As a more concrete example, I've been using vimgrep a lot to search through files. I'll do a command like:
:vimgrep /font-family/j my-project/**/*.less | cope
Later, I'll want to use the same search but look for a different property, so I hit : then ctrl + p to access my previous vimgrep. Now here I have to use the arrow keys to navigate backwards to the search string and modify it. It would be much faster if I could use readline to navigate backwards by word then delete by word.
For small edits, Backspace and light use of the cursor keys should be fine. For anything larger, I would advise to use the command-line window:
In the command-line window the command line can be edited just like editing
text in any window.
So, there's no need to mentally switch to readline key mappings; just use the full editing power (including any custom mappings) of Vim!
You can switch via <C-F> from the command-line, or directly enter it (from normal mode) by pressing q: instead of :. All the details can be found at :help cmdline-window.
I like this question. Long time vim user, but new-ish here, so I can't vote it up. But indeed, perhaps unofficially, many vim fans feel that most of the time the goal is to not have your hands leave home row position (fingers move, hands relatively still).
I will admit, when it comes to command mode, I use the arrows. With P being on my pinky finger, I would miss-hit ctrl-P a lot, and it's faster to slide my right hand down (on my Natural keyboard) and find the up-arrow by quick feel, instantly, to do the same thing. Once I'm there, left-right arrows are also easy to find without looking or delay. Also Ctrl-arrows let you skip by word.
One of the great things about vim is the :help. I have easily spent tens of hours over the years reading through it, and it solves 95% of my problems if I have enough time and working-memory to push deep enough into it.
Here is what I found for :help readline:
READLINE readline.vim ft-readline-syntax
The readline library is primarily used by the BASH shell, which adds
quite a few commands and options to the ones already available. To
highlight these items as well you can add the following to your
|vimrc| or just type it in the command line before loading a file with
the readline syntax:
let readline_has_bash = 1
This will add highlighting for the commands that BASH (version 2.05a
and later, and part earlier) adds.
Give it a try! (I am using vim 7.4)
You can see a list of the default key binds with :help cmdline-history (scroll down a bit) and :help ex-edit-index.
You can remap this with cnoremap:
cnoremap <C-b> <Left>
cnoremap <C-a> <C-b>
" .. Probably more
Note that using cmap will probably get you into problems here since the right-hand side is the currently mapped action, whereas with cnoremap the right-hand side it will always use the native Vim action.

vim cmap lhs only at the beginning

I have a mapping
:cnoremap ch call ShowHistoryMatching
The problem is that the ch characters expand to the right sentence in any case they are typed, no matter if at the beginning or later in the cmap input.
The problem is when I try to search for words in vim using / or ? e.g. for
/cache - it will be expanded using the mapping above.
How can I set the mapping ch to be extended only when it occurs at the beginning of the command?
cmap's are notoriously tricky because they often execute in the wrong context. Some better alternatives:
Use a normal mapping e.g. nnoremap <leader>ch :call ShowHistoryMatching()<cr>
Create a command e.g. command Ch call ShowHistoryMatching()
Use a the cmdalias.vim plugin
Use a more clever abbreviation as described in vim change :x function to delete buffer instead of save & quit post. Similar technique to cmdailias.vim.
Personally I would just create a new command.
You can use the getcmdpos() function to determine if you're at the beginning of the line or somewhere else. This technique can replace a built-in command using an abbreviation or you can adapt it for use in a mapping, possibly with an <expr> mapping.

Using Ack.vim on visual selection

Currently I have this mapping in my ~/.vimrc
noremap <Leader>a :Ack <cword><cr>
which enables me to search for a word under the cursor.
I would like to search for a current visual selection instead, because sometimes words are not enough.
Is there a way I can send visual selection to ack.vim?
You can write a visual-mode map that yanks the highlighted text and then pastes it verbatim (properly escaped) onto the vim command-line:
vnoremap <Leader>a y:Ack <C-r>=fnameescape(#")<CR><CR>
This solution uses the <C-r>= trick that allows you to enter a kind of second-level command-line, which allows you to enter any vimscript expression, which is then evaluated, and the result is stringified and pasted onto the (original, first-level) command-line where the cursor is.
A slight disadvantage of this approach is that it commandeers the unnamed register, which you may not want.
While bgoldst's answer should work just fine, you could also consider my fork of ack.vim: https://github.com/AndrewRadev/ack.vim
It comes with a working :Ack command in visual mode, and a few other extras that I've summarized at the top of the README.
At the time of this writing this is the default behaviour of Ack.
Just do the following:
move your cursor on any word in normal mode (for instance, hit Esc button to enter in normal mode, you know...)
type :Ack with no argument
it will search for the word under the cursor
Usually I select text during a search in a file (for instance put cursor inside word and type * repeateadly) the type :Ack to look for that word in other files of the project.

How to refer to key combinations in vim keybinding that works on the query line

I use pandoc markdown in text files and want to automate links that refer to internal textnodes. For example I have a link like [\%110lund] going to the word "und" in line 110. To automate the jumping process I defined a keybinding:
nnoremap <Leader>l vi[y/<ctrl+r>0<CR>
Unfortunately <ctrl+r> is written as the query string instead of performed to copy the visual selection.
So my question is how do I have to notate <ctrl+r>0 at this location so that it is actually performed instead of written out
Use c+r instead of ctrl+r.
In order to avoid confusion, I am striking out the incorrect edit that someone else made, rather than reverting it. In the context of a vim mapping (such as the :nnoremap of this question) the following should be typed literally. For example, <c-r> really means 5 characters.
Use <c-r> instead of <ctrl+r>.
See :help keycodes for more options.

Resources