Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

vim

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}
like image 907
Hotschke Avatar asked Dec 06 '11 16:12

Hotschke


2 Answers

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:

  • Save selected text (partial line) from Vim
  • How can I save a text block in visual mode to a file in Vim? (note, marked answer also works linewise)
like image 58
Hotschke Avatar answered Sep 24 '22 16:09

Hotschke


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")

like image 39
kikuchiyo Avatar answered Sep 22 '22 16:09

kikuchiyo