19

Very simple approach: Move to the first line you want to delete. Record a macro: qa3ddjq Repeat it with a high number: 1000@a Step three will repeat the macro a thousand times or until an error is encountered. Hitting end of file (hence no lines to delete) produces an error and repetition of the macro is canceled. See :help recording.


17

The easiest solution to me would be: :%norm j3dd That is: %: for every line norm: run the following keys as if in normal mode j3dd: go down on line then delete 3 lines So from the first line, go down to the second one and delete the next 3 lines. The second Text I want to keep. is now on the second line. Go down one line, delete 3. Rinse and repeat. ...


6

You have some great solutions already available. Here is another one: :g/^/if line('.')%4!=1|:s/^/DELETE ME/|endif :g/^DELETE ME/d First, we perform an action on every line (:g matching against the ^ (start of line)) and for every line number perform the result of linenumber % 4. If the result is unequal to 1, we add DELETE ME at the beginning of the line, ...


5

This is not exactly what you want, but you could visually select your lines, then run this global command: g/^/exe 'norm! "adiwD' | exe 'norm! '.@a.'p' ├───┘│ ├────┘ │ │ └ paste unnamed register as many times as the number in register `a` │ └ delete word in unnamed register ...


5

I think you can use this for specific line :10,15 norm! @d If you want something like until line, you can use this instead :.,15 norm! @d Or a more visual way, by selecting the lines you want to change via Visual mode and then execute the command :norm! @d EDIT! You can also use 15: from normal mode to execute the macro for the next 15 lines 15: norm!...


4

I know this is the vi channel, but to me this is a sed problem. sed -ne 'p;n;n;n' <file >newfile So you can wrangle it into a vi solution: :0 !Gsed -ne 'p;n;n;n'


4

Another way that also works across files is to use :h :vimgrep with g flag: Without the 'g' flag each line is added only once. With 'g' every match is added. The workflow is: Init your search pattern with /your pattern, record your macro in q. Find all matching in your interested files: vimgrep //g **/*.cpp **/*.h Reverse ...


3

Search for your pattern using /, then play your macro @@—you can record a new macro for this by doing /pattern<CR>qqn@aq Assuming @a holds your original macro. Then @q will jump to the next occurrence and play your macro. (For this case, you may need qqn@anq.) In this case, you also do :%substitute/pattern/"&"/g


3

It can be done with a substitution with a sub-replace-expression: :%s/\ze\(\s*\)private \w\+ \(\w\+\)/\=submatch(1).'@Column(name="'.substitute(submatch(2), '\u', '_\l&', 'g').'");'."\r" For more help see: :h :s :h sub-replace-expression :h \zs :h submatch() :h substitute() :h /\u :h sub-replace-special :h s/\l


3

An alternative (I suppose we start on the line 1, and delete the lines 2-4, 6-8 and so on, as per an example text): while line(".") < line("$") silent +1delete _ 3 endwhile If prefer doing this interactively, you can make use of the "command-line register". That is, press :+1del 3<CR> and then 1000@:


2

"e("w)P: the part in brackets is supposed to result in something like "paste content of e for a w number of times" which doesn't really seem to work out. How to apply a register (as a count) to a command? The direct answer to this is that you need to use :normal! to run a normal mode command and :execute to assemble it from a string. You can then refer ...


2

If you have tpope's vim-repeat, you can do something like the following: nnoremap S :call Stamp()<CR> function Stamp() abort normal! "_diwP silent! call repeat#set("S", -1) endfunction You can do it without the function, but this is a bit clearer in my opinion.


2

You can use 3Rf0<Esc>. The R command is similar to r, but it replaces multiple characters and not just a single one. It takes an <Esc> to leave Insert (Replace) mode. You can also use . to repeat a Replace action, and you can repeat it with a count. For example, you can use Rf0<Esc> to replace the first instance, followed by l2. if you ...


2

One great way to have access to multiple commands in your history is to use the command-line window, which you can access with the q: normal-mode command, or by pressing Ctrl+F from the Ex : command-line prompt. From that window, you can yank the sequence of commands you're interested on (e.g. using a motion or visual mode), then quit the command window (...


2

FWIW, I have a similar mapping on C-o. Extracted as a standalone script, it should give something like this: cno <expr> <c-o> <sid>operate_and_get_next() augroup operate_and_get_next au! au CmdlineEnter : call timer_start(0, {-> s:operate_and_get_next_remember('on_leave')}) augroup END let s:HISTORY_MAX_SIZE = 10 fu s:...


2

If you're using the command line, like so: nnoremap <LEADER>t :!echo "Yay"<CR> (just an example) You can add <C-u> after the : to erase all undesired characters: nnoremap <LEADER>t :<C-u>!echo "Yay"<CR> " Also works with `<CMD>` in neovim: nnoremap <LEADER>t <CMD>!echo "Yay"<CR> What happens ...


2

You can come up with something relatively simple, following and tinkering what vim has described in :h :map-operator: As an example I came up with in about 15 minutes of experimenting: nmap <silent> gi :set opfunc=InsertToTextObject<CR>g@ vmap <silent> gi :<C-U>call InsertToTextObject(visualmode(), 1)<CR> nmap <silent> ...


2

Yet another solution g/^\s*private/copy. | normal! -2dwdw"_C@Column(name = "^R=substitute(@-, '\(\l\)\(\u\)', '\1_\l\2', 'g')^M") An explanation: g/^\s*private/... for all lines starting with "<spaces>private" copy. | normal! ... make a copy of the current line then enter normal mode command -2dwdw"_C up one line ...


2

Check out :help global. It basically filters out the lines that don't match the pattern. So you can do :'<,'>global/<pattern to select lines based on>/substitute/pool: MANAGED_POOL_CTS/<etc.>/. Or :g/MANAGED_POOL_CTS/normal! opubsub_topic: "projects/foo/topics/bar". (Edited with @statox's example) Or, you could execute a macro. ...


1

I would combine it with the :g command: :g/^\s*check\>/s/=/VS/ This selects all lines that has a "check" as the first word and then executes s/=/VS/ on this line. This will replace the first = with VS. You can also use the substitution flags gc if you like to replase all equal signs and want to confirm every substitution: :g/^\s*check\>/s/=/...


1

If you'd accept a solution that requires a Vim plug-in (specifically for the snake case coercion), then I could recommend one that involves recording a macro to process each line. In particular, you would have to install plug-in vim-abolish, which includes a cr operation to do case coersion, in particular crs (or equivalently cr_) for snake_case. So you ...


1

Another possible answer is using vim-visual-multi. First, select the pattern everywhere. To do so, use \\/ and then \\A to select all. And then \\@ with the macro register. In your case, you could have done S" instead of using the macro after \\A.


1

an alternative: you want to keep any lines: 1, 4, etc. You could use: awk '!((FNR-1)%3)' file > newfile # awk: when a condition is given without action: # prints the lines for which the condition returns 0. # FNR designates the line number in the current file. # a%3 : takes the modulus of a and 3. ( 0%3=0, 1%3=1, 2%3=2, 3%...


1

You can use system() instead of :!. As the question is specific to Neovim, it makes sense to pass command as a List (not supported in Vim!) to execute the application directly (w/o shell): au BufWritePost *.sh,*.zsh,.zshrc \ silent call system(['ctags', '--language-force=sh', fnameescape(expand('%'))]) Also note that shell quoting rules won't apply ...


1

Do note that vim's documentation says :{range}![!]{filter} [!][arg] *:range!* Filter {range} lines through the external program {filter}. Vim replaces the optional bangs with the latest given command and appends the optional [arg]. So :!! should reuse the latest-given command. It's unclear which of the two ...


1

There isn't really a native command to repeat a change without including the inserted text as part of the repeat. You mentioned using a macro, but recording it (using the q command) can be tricky, since you want to end it inside insert mode. It turns out you can actually do that using qacit<C-O>q to record only cit in @a, which you can use to ...


1

This is a bug registered on March 17th, 2019 and reported on February 24th, 2019. From :help known-bugs: Bug: script written with "-W scriptout" contains Key codes, while the script read with "-s scriptin" expects escape codes. Probably "scriptout" needs to be adjusted. (Daniel Steinberg, 2019 Feb 24, #4041) As of this writing, it doesn't have a priority ...


1

It looks like a nasty bug. When writing a script out, Vim uses its "<>-notation" for keycodes, i.e. "\<BS>" (<80>kb) for backspace key, "\<del>" (<80>kD) for delete key, etc. However, they only get converted back into "real" keys if pumped through :normal. While -s or :source! simply allow them to pass through! It's also ...


1

Here's yet another method: Type qq to start recording a macro, Type "wdiw to delete the number into the "w register, Type "ede to delete the word into the "e register, Type iCtrl-R= to enter insert mode and start using the expression register. See :help i_CTRL-R_=. Type repeat(@e, @w), which is now an expression that evaluates to apples repeated four times, ...


1

You can indeed do this by recording a macro in vanilla Vim. Type the following series of keystrokes: qqfSpaceraA SpaceCtrl-VEscEsc0d$@"x+q You now have in register "q a macro that will convert a single line. You can replay this on the remaining 6 lines by typing 6@q. Converting the plural nouns into singular nouns is left as an exercise for the reader. ...


Only top voted, non community-wiki answers of a minimum length are eligible