Hotschke
Hotschke

Reputation: 10190

Filter ONLY several words (not the complete line) through an external command

I'd like to use an external Perl or Python script to change a selection of text in Vim into title case. As a user of these scripts, you can select the small words which are not capitalized.

However, I want to apply the filter only on a part of a line, not the complete line. Does anyone know how to do this?

Example line in LaTeX source code:

\item the title case in latex and ...

Should become

\item The Title Case in Latex and ...

The following command does not work:

:{visual}!{filter}

Upvotes: 7

Views: 995

Answers (3)

Hotschke
Hotschke

Reputation: 10190

All ex commands work linewise (due to vi/ex history). Therefore, it is not possible to use a filter only for selected words, only linewise.

This is documented in the helpfile of vim (version 8.0.x) under :h 10.3:

Note:
When using Visual mode to select part of a line, or using CTRL-V to select a block of text, the colon commands will still apply to whole lines. This might change in a future version of Vim.

To jump directly to this help section try to use :helpg colon\ commands.*apply.

For reference: A list of ex commands can be shown via :h ex-cmd-index.

related sx.questions are:

Upvotes: 3

Hotschke
Hotschke

Reputation: 10190

Finally, I've found a plugin for what I had in mind:

vis - Extended Visual Mode Commands, Substitutes, and Searches vimscript #1159 (github mirror)

:'<,'>B !titlecase

Upvotes: 1

kikuchiyo
kikuchiyo

Reputation: 3421

This example is partially working, but does not capitalize the last word in the visually selected text. Idea was to reduce work-load by staying in Vim. Get this to work on the last word in the visual selection and you are there. :) Per updated specs, pass "\\|" delimeted list of small words, with first letter capitalized.

" Visually select some text
":call title_case_selection:()
" and probably want to map it to some abbreviation
"

function title_case_selection:( list_of_words_bar_delimited )
    let g:start_column=virtcol("'<") - 1
    let g:end_column=virtcol("'>") + 1
    let g:substitution_command=':s/\%>'.g:start_column.'v\<\(\w\)\(\w*\)\>\%<'.g:end_column.'v/\u\1\L\2/g'
    call feedkeys ( g:substitution_command )
    call feedkeys ("\<cr>", 't')
    let g:substitution_command=':s/\%>'.g:start_column.'v\<\('.a:list_of_words_bar_delimited.'\)\>\%<'.g:end_column.'v/\L\1/g'
    call feedkeys ( g:substitution_command )
    call feedkeys ("\<cr>", 't')
endfunction

"abba zabba is a very yummy candy! <- Visually select this line

:call title_case_selection:("Is\\|A")

Upvotes: 1

Related Questions