5

Would you provide a key mapping for insert mode which could make letters between start of current word to current cursor uppercase?

Example:

  1. For string abcd efgh, and now cursor is flickering at the end following h, then I could get abcd EFGH.
  2. For string abcd efgh, and now cursor is flickering on g, then I could get abcd EFgh.

Please note, I know

gU

and

map! <C-F> <Esc>gUiw`]a

But it cannot meet my second example.

Thanks in advance!


Updated on GMT 2016/3/30, 2:26:

According to comment from Carpetsmoker and as I tried, gUb could meet my second example but not the first, while gUiw could meet my first example but not the second.

So would anyone help to implement necessary function or logic? Thus could meet my requirement completely.

Or any other solution is also appreciated.


Updated on GMT 2016/3/30, 3:19:

Currently, there are two solutions, one is from muru and the other is from myself. Both works as I tried and are acceptable to me. I mark muru one as the answer.


Updated on GMT 2016/3/31, 23:19:

With comments from tommcdo and VanLaser, I updated my solution, and to me it's the current best one.

Updated on GMT 2016/10/20, 14:25:

Regarding the solution of

nnoremap <C-f> gUvb`]

I just found a bug. For example, in normal mode, we have asdf qwer, and cursor is flicking on q when we press Ctrl-f, we will get ASDF Qwer, rather than expected asdf Qwer. So current best solution is

inoremap <C-f> <C-\><C-O>gUb<ESC>`]a

and

nnoremap <C-f> a<C-\><C-O>gUb<ESC>`]
  • 4
    You're running gU on the motion iw, which is inner word, meaning all of the word the cursor is currently on. Your first and second case are actually subtly different, since the first is "capitalize all letters in the previous word", while the second case is "capitalize all letters before the cursor but NOT the letter the cursor is on"... Replacing iw with b will almost do what you want, but more logic is needed to do exactly what you want... – Martin Tournoij Mar 30 '16 at 2:18
  • can you try gUb instead of gUiw ? – Sundeep Mar 30 '16 at 2:18
  • @Carpetsmoker and @ sp asic Thanks for above comments! – Qiu Yangfan Mar 30 '16 at 2:36
  • 1
    in 1, if the cursor is really after h, then gUb will give you abcd EFGH. Is the cursor on h or after h? – muru Mar 30 '16 at 2:48
  • @muru, in insert mode, if I just type efgh, the cursor will after h, while to use gUb, I need switch to normal mode with <ESC>, then cursor will move on h, right? – Qiu Yangfan Mar 30 '16 at 2:55
6

If you use <Esc>…a, the cursor will move to the character before the cursor after <Esc>. Use <c-\><c-o>:

CTRL-O          execute one command, return to Insert mode   i_CTRL-O
CTRL-\ CTRL-O   like CTRL-O but don't move the cursor        i_CTRL-\_CTRL-O

So:

inoremap <C-F> <C-\><C-O>gUb<Esc>`]a

The <Esc>…a is still needed to get the cursor back where it was.

5

Thanks to the hint of gUb from Carpetsmoker, I think out one solution as following:

inoremap <C-u> <ESC>gUlgUb`]la

Explanation:

  • gUl makes the current letter uppercase
  • gUb makes the letters from word beginning to current letter uppercase
  • `] moves cursor to the end of modification by gUb
  • l to move cursor right by on letter
  • a to get back to insert mode.


Updated on GMT 2016/3/31, 23:19:

With below comments from tommcdo and VanLaser, here provide a updated solution, which is simpler than my above one, and the best solution currently:

inoremap <C-f> <ESC>gUvbgi

Explanation:

  • gUvb makes the letters from word beginning to current letter(including the current letter with cursor flicking on) uppercase. Backwards motions often omit the character the cursor appears to be on, and putting v between the operator and motion fixes that in most cases
  • gi move cursor back to last insert position as insert mode.
  • 7
    There's also gUvb. Take a look at :help o_v -- in short, it inverts whether the pending motion will be inclusive or exclusive. Backwards motions often omit the character the cursor appears to be on, and putting v between the operator and motion fixes that in most cases. – tommcdo Mar 30 '16 at 11:24
  • 3
    Also gi is a shorter way to return to last insert cursor position ... which gives something like <Esc>gUvbgi :) – VanLaser Mar 30 '16 at 12:34
  • 2
    @VanLaser would <Esc>vbUgi be equivalent? – Sundeep Mar 31 '16 at 9:06
  • 1
    Indeed! And I think that's the shortest solution yet! (i.e. the "best" one) :) – VanLaser Mar 31 '16 at 9:30
0

If there are lines that contains uppercase words,

.,.+3s/\([A-Z]\)\([A-Z]\+\)/\=submatch(1).tolower(submatch(2))/g

will transform current line and subsequent 3 lines. the result is like below:

original:

  1. DO-IT-YOURSELF TRANQUILIZERS THAT BRING PEACE OF MIND 187

transformed:

  1. Do-It-Yourself Tranquilizers That Bring Peace Of Mind 187

to lowercase/uppercase is similar, but simpler.

  • That's a very nifty Ex command, but it appears to be only very tangentially related to the question. – Rich Jan 3 '18 at 14:27
  • Yes, indeed. NOT to answer the original question, in which case normal command with text-object fits much better. Just to add something of interest that might be helpful to who view this post. (that's one approach of how I improved my vim-fu) – qeatzy Jan 4 '18 at 11:14

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.