13

I think the following command should work : :%s/^\(.*\)\(\n\1\)\+$/\1/ Explanation : We use the substitution command on the whole file to change pattern into string : :%s/pattern/string/ Here pattern is ^\(.*\)\(\n\1\)\+$ and string is \1. pattern can be broken down like this : ^\(subpattern1\)\(subpattern2\)\+$ ^ and $ match respectively a ...


12

Possible explanation of the problem I think the reason why :g/;/j doesn't work is because the :g command operates with a 2-pass algorithm: during the first pass it marks the lines containing the pattern ; during the second pass it operates on the marked lines During the second pass, :g joins the line 1; with line 2; because 1; was marked during the first ...


10

Try the following: :%s;\v^(.*)(\n\1)+$;\1; As with saginaw's answer, this uses Vim's :substitute command. However, it takes advantage of a couple of extra features to improve readability: Vim lets us use any non-alphanumeric ASCII character except backslash (\), double-quote ("), or pipe (|) to divide our match/replace/flags text. Here, I selected ...


10

A substitution can be used to replace a pattern with the result of an expression like this: :keeppatterns %s;<inputs>\zs\_.\{-}\ze</inputs>;\=insert(readfile('test.txt'), '') See :help sub-replace-expression Note that keeppatterns prevents the substitute command from adding anything to the search history and preserves the "last search pattern ...


10

What comes after the second / is an Ex command. In this case you could use the :normal command, which executes its argument as if you typed it in normal mode (see :help :normal) :g/^#/normal I# or the :substitute command (see :help :substitute) :g/^#/substitute/^/#/ " Or just :g/^#/s/^/#/ but also you could use the :substitute command without the :g like ...


9

Try a global command: :g/^/exe ".w! line".line('.').".txt" :g/^/ Do a command for every line (you can adjust this regular expression if you only want to save certain lines, i.e. . for non-empty lines) exe "" execute the following command .w! save the current line and overwrite if already exists. (Remove ! if you don't want to auto-overwrite everything) "...


8

You could use the following command: :g/SPECIAL/.,.+3d Which can be detailled like this: :g/ Apply a command on all the lines matching a pattern SPECIAL/ The pattern to match .,.+3d The command to execute .,.+3 Is a range. "." represent the current line (i.e. the matched one It is updated each time a line is matched The full ...


8

If you want to remove ALL adjacent identical lines, not just Hold, you can do it extremely easily with an external filter from within vim: :%!uniq (in a Unix environment). If you want to do it directly in vim, it's actually very tricky. I think there is a way, but for the general case it is very tricky to make it 100% functional and I haven't worked out ...


8

This command does what you want: :let i = 1|g/^Do/s/^/\=i/|let i = i + 1 Explanation… let i = 1 initializes counter i, g/^Do/s/^/\=i/ prepends i to each line starting with Do, let i = i + 1 increments i. The trick is that the incrementation happens before the next substitution. --- edit --- If we used a single substitution, the counter would only be ...


8

Update: New official vim plugin cfilter Since 21.8.2018 (patch: 8.1.0311) the plugin cfilter is distributed with vim in $VIMRUNTIME. It is documented under :h cfilter-plugin. Load plugin cfilter when needed or load it always in your vimrc :packadd cfilter Using abbreviations in case of a vanilla vim this can be as short as :pa c<tab><cr>. ...


7

If I understand your post correctly, you had this snippet of C code : switch (result) { case CASE_1: return report("..."); case CASE_2: return report("..."); } And you wanted to transform it to : switch (result) { case CASE_1: report("..."); break; case CASE_2: report("..."); break; } I don't know all the details of the ...


7

Well, you can have perhaps more cases than you account for in your description: a header line can be preceded by 0, 1 or many empty lines, and can be followed by 0, 1 or many empty lines. In all these cases, you want to achieve a header line preceded and followed by exactly 1 line (if I got that right). With this description, the problem can be solved with ...


7

Why your command doesn't work The simple answer is the . as the end range for your :j command will match the space in your offending line. This means that your nearly empty line will not be removed/compressed. This can be solved by searching for \S (non-whitespace character) instead of . :g/^\s*$/,/\S/-j We can do better The following command will work ...


7

Using a substitution :%s/.\{100}\zs.*// Find 100 characters, .\{100} then start the match, \zs, and select the rest of the line, .*. Replace the match with nothing. For more help see: :h :s :h /\. :h /\{ :h \zs :h /\* Using filter :%!cut -c 1-100 Use filter, :!, with a range of the entire file, %. This will take the entire buffer and pass the text as ...


6

You can do this with a simple substitute command. Try this: :%s/\n,/, This removes a newline from every line containing a newline followed by a comma. You could also do it like this: :%s/\n\ze, The way this works is by marking the end of the selection to be removed, and the only text that will be removed is what matches before \ze. From :h /\ze ...


6

To create a custom command line command :command is a good choice: :command! -nargs=1 SL g/<args>/z#.1 You'll need to use a name that starts with a capital letter, though, so I'm using "SL" instead of "sl". Run with :SL pattern. The rest is pretty self-explanatory. Use a bang (!) after :command to allow subsequent overrides (good for including it in ...


5

An alternative approach to that from Gary is this: :g/^<inputs>/+,/^<\/inputs>/-d|-r dummy Which first deletes everything in the given pattern, than uses the :r command to read the data from file dummy. Now if you need to extract the filename from the lines between the <input>/</input> pattern, it gets a litte bit more complicated.


5

A possible workaround is to use a macro: qa/^subroutine<CR>f<space>/end subroutine<CR>$pq Which can be detailled like this: qa Record a macro in the a register /^subroutine<CR> Go to the next occurence of a subroutine declaration f<space> Go to the space separating "subroutine" and the name y$ ...


5

I'm guessing the problem is that :global operates linewise, so the \zs and \ze in your regex don't do anything; They still apply to the line that matched the entire pattern, not the line that the selection starts and ends on. For example, if you have the following text: foo bar and you do :g/foo\n\zsb/d This will delete foo rather than deleting bar. Keep ...


5

If you're willing to use one command by language you can do this: g/en-US/t.|s/en-US/en-GB g/en-GB/t.|s/fr-FR/en-GB As you can see we reuse your command, and add another one to be executed with the | character. Edit As suggested in the comments (Thank you @Doktor OSwaldo!) it is possible to put the command in a loop to avoid using it several time: let ...


5

You're confusing the passing of the register to :yank (Ex command) vs. y (normal mode). For the latter, instead of appending the register, it must come before the y command, and with the " prefix: "Ayi" (with register A, yank the inner " double quoted text) :let @a = '' | g/prop/normal! "Ayi" Note that as the yank is characterwise, all matches will be ...


4

One way to do it is to use the widely underappreciated \zs: :%s/report.*\zs/\r break;/ What this does is, look at lines containing report, find end of line, and add a new line with break. You could also achieve the same thing with global, but that would just complicate the command for no reason.


4

This seems to work, at least on a Unix system: :/<inputs>/+1,/<\/inputs>/-1!cat foo.txt It uses the {range}!{filter} command to filter the lines from one after <inputs> to one before </inputs> through the external program cat foo.txt. In this case, cat ignores its standard input, so the original lines are deleted and replaced by the ...


4

exec the norm command. From :h :norm: An alternative is to use :execute, which uses an expression as argument. This allows the use of printable characters to represent special characters. Example: :exe "normal \<c-w>\<c-w>" Note the usage of double quotes and the \ before < for the special characters. Your example would translate ...


4

Here's the macro solution by @statox, modified to deal with subroutine parameters and nested subroutines. This assumes you also have installed matchit: qaq - clear register @a qa - start recording in register @a /^\s*subroutine\zs<CR> - search for subroutine; \zs leaves cursor on the space following it y2w - yank the name; 2 because we want to ...


4

You could use a combination of :global, matchit and :normal!: :g/^\s*subroutine/norm ^whye^%$p Explanation: :g/^\s*subroutine: for all lines matching ^\s*subroutine, do: normal: enter normal mode (! means no mappings do not use norm!, as the ! removes the call to matchit (thanks @SatoKatsura)) ^ go to the first non-blank character (not 0, to handle nested ...


4

From the documentation (:h function-range-example): function Cont() range execute (a:firstline + 1) . "," . a:lastline . 's/^/\t\\ ' endfunction 4,8call Cont() You need to use execute to pass the variables to the g command. In your case, this simplified example should work (at least it works here): function! MyFunction() execute a:firstline . ',' . ...


4

@DJMcMayhem's solution is pretty good but Vim is pretty powerful so here is an alternative with the global command: :g/^,/normal! kJ That you can translate as "For every line which begins by a comma use the normal mode keys kJ i.e. to go the upper line and join it with the next one". Edit As @Christian Brabandt said in the comments you can also use gJ ...


4

You can use the expression register, see :h sub-replace-expression: :s/search/\=MyFunction(submatch(0))/ The submatch() function can also be used directly inside the function, which would make the syntax even simpler: :s/search/\=MyFunction()/ To give a concrete example of the latter variant, consider the following Vim function: function! MyFunction() ...


4

This is job for :substitute :%s/pattern\zs\s\+\S\+//g after the pattern (\zs), I match spaces (\s\+) followed by any number of non spaces (\S\+). If you really want dw and not dW, you'll prefer \(\k\@!.\)\+\k\+ instead of \s\+\S\+


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