Switch from f to F in Vim without , - vim

After using the f{char} motion, is it possible to change directions so ; will go backwards (as if you used F{char})? (And vice-versa and with tT.)
I'm going to try using , as LocalLeader and I have this to let me access , again:
let maplocalleader = ','
nnoremap <LocalLeader><LocalLeader> <LocalLeader>
But I wonder if I can map <LocalLeader>; to make ; switch between acting like ; and ,. I don't see anywhere the character for f is stored, so can I do this?

No, this cannot be done, unless you re-implement the f command yourself (which isn't so difficult as it sounds; there are actually plugins that enhance it to search in subsequent lines, too). It can be done for n / N (via v:searchforward), though.
In general, I would advise from employing such clever "tricks"; they retrain your muscle memory, and cause problems in other environments with vi-like keybindings (Pentadactyl, Bash, readline, some IDEs). Rather, rethink your approach to mappings.

Related

How to do mark-like mapping in vim

The m normal command accepts a letter just after it to set a "letter" mark.
I would like to create a similar command that works across tabs... But my problem is with the binding : Is there a simple way to bind for example M<letter> to a function or a command or should I manually repeat all the possibilities ?
As romainl has already said, no.
Covering this for good measure (and in case someone else comes along later), you can only practically map upper-case letters. As is outlined in the documentation, lower-case marks are only valid within a single file. Upper-case ones, that the Vim docs calls "file marks", are valid from anywhere. Unless you have some dark magic function to resolve ambiguous file marks, you probably only need a single for loop mapping the upper-case letters, if you're going with the brute-force option.
That said, there are a couple alternatives here as well.
As far as I know, the only "dynamic" bit of a command is a count (or a range, but unless you want to map characters to a number (and handle ranges and other fun stuff:tm:), I don't recommend this approach:
" The <C-U> is required for all uses. If you want a function,
" you'd need :<C-U>call YourFunction()<cr>
nnoremap M :<C-U>echom v:count<cr>
See also :h v:count, which states:
Note: the <C-U> is required to remove the line range that you get when typing ':' after a count.
You can then run 26M, decode v:count as Z, and then do whatever fancy lookup from there.
The second alternative, and the one proposed by romainl and by far the most used one in cases like this (source: experience and lots of code browsing), is using a for loop to brute-force map letters:
for i in range(char2nr('A'), char2nr('Z'))
exec 'nnoremap M' . nr2char(i) ':echo "This is where the appropriate function call goes"<cr>'
endfor
Which produces all 26 mappings.
And the final approach is abusing getchar(). This means a single mapping, but at the expense of doing additional processing:
func! Func()
let c = getchar()
echo c
" Character processing (the `echo` isn't required) here
endfunc
nnoremap M :call Func()<cr>
You can decide which works for you, but I strongly suggest preferring option 2, as this gives you map timeouts and clear definitions, and more obvious conflict detection.

Is there any way to use '.' key instead of ';' key to repeat inline search ('f' key) in vim

I'm new to vim and I learned f key can be repeated by ; key today.
However I've already use ; key as Leader.
Is there any way to use . key instead?
Sure, you can map . to do the job of ;:
nnoremap . ;
However, then you lose the function of . (repeat the last change), unless you remap that.
Risking to sound preachy, but it will be long-term much better for you to adapt to Vim, than to try to adapt Vim to you — at least until you are no longer a beginner. In this case, for example, I'd say . (repeat last command) is a much more important function than ; (repeat last f-search) is, especially since leader can be \ as is the default, or Space, as keys with much less to lose.

Move relative to the end of line in Vim

Imagine I have a sentence like this:
Block chain, the decentralised public ledger that records transactions on the bitcoin network.
And if my cursor is at the end of the first word, is there a way to move relative to the end of the sentence rather than from the cursor position? Think of something like, the first c from right hand side is where I want to go, is there a way to reach rather than going to the end first and using F to reach the c ($Fc).
Yes, Vim has (an abundance of) motions that move relative to the current (cursor) position: l, w, f among them. And you can re-position the cursor easily with many motions: ^, 0, $, gm. When combined, that means you can reach almost any place with just a few keystrokes, and it's possible to remember each of those quite easily.
Given that there's a limit to available keys (and that Vim out of the box already uses most of them!), and a limit to what you can memorize, I think that's a perfect balance. In that light, I think $Fc is nothing to worry about (just compare with other editors!)
If that particular motion's inefficiency bothers you, you can always write a custom mapping (and assign one of the few available keys), but that doesn't scale well.
If you think $Fc 3 keystrokes is too many......
operator + target char have already 2 strokes.
We can dynamic capture the target char. But to make it 2 strokes, we have to scarify a normal mode key, I don't know which one you don't use, I just cannot find one on my keyboard, so as example I use the <F6> you can change it as you like.
This mapping allows you press <F6>c to that place, of course, c could be any character.
nnoremap <expr> <space> '$F'. nr2char(getchar())
And this won't work if the target char, i.e (c) is at the EOL. Well you can do further checking, e.g. write your own function to do it, if you think it is really necessary.
Personally I don't think it is worthwhile. Just get used to the $Fx.

Autocomplete/abbrev with calculation in Vim?

I'm trying to script something like this in Vim, and it's raising a series of questions for me. I'm sure it's possible.
Whenever I insert a number followed by a capital F, like 88F, I would like Vim to automatically convert that to 88°F (31°C) -- that is, expanding the expression but also converting Fahrenheit to Celsius.
What's the best way to trigger that sort of inline expansion? And the best way to run the calculation?
This is the refactoring of #kev’s answer that won’t force you to use <C-v>F and won’t touch any registers:
inoremap <expr> F ((col('.')>1 && getline('.')[col('.')-2]=~#'^\d$')?(printf(' °F (%d °C)', float2nr((matchstr(getline('.')[:(col('.')-2)], '\d\+$')-32)/1.8))):('F'))
Note that you must not use imap unless you know exactly why.
Update:
Assuming that you use dot as a decimal separator, do not use scientific notation or common (for programming languages) truncations like .1==0.1, 10.==10.0:
inoremap <expr> F ((col('.')>1 && getline('.')[col('.')-2]=~#'^\d$')?(printf(' °F (%.1g °C)', (str2float(matchstr(getline('.')[:(col('.')-2)], '\v\-?\d+(\.\d+)?$'))-32)/1.8)):('F'))
:imap F <ESC>ciw<C-R>=printf('%d°F (%d°C)', str2nr(#"), float2nr((str2nr(#")-32)/1.8))<CR>
It will expand 88F to 88°F (31°C) in insert-mode
note: if you want to type the character F, press Ctrl-VF.

Vim motion vertical version of f & t?

In vim, I really love f & t in Normal mode. Are there vertical versions of these? If not, what's the best way to jump so many lines downward to a word that I see? Do I just have to count the lines and do 12j or something?
Can you use /foo (or ?foo for backwards)? I tend to use that more than t or f anyway.
I think you'll love the EasyMotion plugin.
You'll type <leader>fb to go to a b, horizontally and vertically.
(you can also find the vim.org mirror git here)
Try vim-sneak, a plugin I wrote for this very reason. It enables you to jump to any location in three keystrokes by specifying the first two characters of the target:
s{char}{char}
For example, sab moves the cursor to the next instance of the string "ab". And Sab moves backwards to the previous instance of "ab".
It also supports:
visual mode
operations (like dzab, czab, and yzab)
operation-repeat with .
motion-repeat with ; and ,
vim-sneak is similar to vim-seek, with many improvements.

Resources