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>`]
5
  • 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... Mar 30, 2016 at 2:18
  • can you try gUb instead of gUiw ?
    – Sundeep
    Mar 30, 2016 at 2:18
  • @Carpetsmoker and @ sp asic Thanks for above comments! Mar 30, 2016 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, 2016 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? Mar 30, 2016 at 2:55

3 Answers 3

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.

0
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.
4
  • 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, 2016 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, 2016 at 12:34
  • 2
    @VanLaser would <Esc>vbUgi be equivalent?
    – Sundeep
    Mar 31, 2016 at 9:06
  • 1
    Indeed! And I think that's the shortest solution yet! (i.e. the "best" one) :)
    – VanLaser
    Mar 31, 2016 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.

2
  • That's a very nifty Ex command, but it appears to be only very tangentially related to the question.
    – Rich
    Jan 3, 2018 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, 2018 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.