0

What's the Vim's version of Emacs's upcase-initials-region?

Viz., how do I capitalize only the first letter in words (preferably without a regex)?

4 Answers 4

2

There is nothing built-in as far as I know.

I don't know how smart upcase-initials-region in emacs is, assuming it just capitalizes beginning of the words in the region...

The easiest way would be using :s command with regex which for some reason you prefer not to use, but still:

:s/\<./\u&/g

You can turn into a command:

command! -range UpcaseInitials <line1>,<line2>s/\<./\u&/g

asciicast

1

I tend to use the abolish plugin and its coercion mode for changing case (beyond simple upper/lower case transformations, for which gu, gU, and g~ work well).

For example, crt was the titlecase coercion. It’s documentation is gone, but the feature should still exist (commit reference).

2
  • It seems something could be done with gu,gU,g~… but maybe not without recording a macro?
    – Geremia
    Feb 22 at 18:03
  • Perhaps something like guiw~ for an individual word @Geremia
    – D. Ben Knoble
    Feb 22 at 23:27
1

I've been using this on a visual selection:

:s/\<\(\w\)\(\w*\)\>/\u\1\L\2/g

I need to try Maxim Kim's approach in this thread, though, because its so much simpler.

6
  • 1
    Actually your version might be better, as it lowercases the rest of the word.
    – Maxim Kim
    Feb 22 at 22:47
  • @MaximKim I wish I could say it's mine, but I stole it from somewhere. I still want to see firsthand what yours does. If I don't use a particular regex frequently, it looks like someone picked up the phone while I was connected to a BBS.
    – MDeBusk
    Feb 22 at 23:25
  • Note that if you want the selection to be more fine-grained than linewise, you’d need \%V
    – D. Ben Knoble
    Feb 22 at 23:26
  • It hadn't occurred to me before jut now, but this doesn't do the job properly if the line has words contaianing an apostrophe. "maybe she's born with it; maybe it's maybelline" becomes "Maybe She'S Born With It; Maybe It'S Maybelline."
    – MDeBusk
    Feb 22 at 23:31
  • 1
    With a slightly modified regex :s/\v<(\w)(\S+)/\u\1\L\2/g, you would lowercase all non-whitespace characters \S. I also used + instead of * to skip single-letter words completely. Good if there's an "a" in the title, bad if the title starts with "A" :-)
    – Friedrich
    Feb 23 at 12:17
1

Using macros

A macro solution was suggested in the comments. I did already think about it but there's one problem I could not solve. Let's hope someone smarter than me can figure something out.

The commands to capitalize the letter under the cursor and jump to the next word is quite simply gUlw. To record it as a macro in register uppercase, type qugUlwq. Now we can @u through a line. So far, so good.

Usually, we'd record a recursive macro like quqqugUlw@uq to run several times. Problem is, that w will jump to the next word - even if it's on the next line. This makes sense in the general case but here it will capitalize every word until the end of the buffer. We'd need to force a failure at the end of the line. While I could come up with a complicated solution, why make it complicated if you can just use :substitute?

The best I can suggest with a macro is hitting @@ repeatedly - which does not really live up the ease of use of other answers.

Using external commands

Another way to do it without regular expressions is to filter the line through an external command. Using :.! to delegate to a simple Python script that applies title-case (or at least Python's flawed stab at it) could look like this:

:.!python -c "import fileinput; [print(i.title(), end='') for i in fileinput.input()]"

Or as a mapping to e.g. F4:

:nnoremap <F4> <Cmd>.!python -c "import fileinput; [print(i.title(), end='') for i in fileinput.input()]"<CR>

Feel free to pick your favorite scripting language instead. Is it possible to call Emacs in scripting mode and call its upcase-initials-region?

But really... regular expressions

There's nothing evil about regular expressions. Sure, they may be hard to read at times, sometimes you really need to decipher them but they're just a tool. Using the best tool for the job means using :s with a regex to capitalize every word.

3
  • 1
    I wonder about title-casing fOo: I suggest guiw~ in comments below, but there may be words for which you don’t want to change the casing of inner letters (and for which your approach is therefor superior).
    – D. Ben Knoble
    Feb 22 at 23:29
  • @D.BenKnoble good point. I'm totally ignorant of Emacs and followed OP's description to the letter: "capitalize first letter of each word". Proper title casing is even more complicated as there are some words that never get capitalized, e.g. articles. I never tried vim-abolish but I guess a plugin would be the way to go.
    – Friedrich
    Feb 23 at 8:54
  • RE: ignore of emacs; uh, same :)
    – D. Ben Knoble
    Feb 23 at 14:15

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.