Podcast #128: We chat with Kent C Dodds about why he loves React and discuss what life was like in the dark days before Git. Listen now.
12

Well, you can combine the "backward search" motion and the delete operator: d?$<Enter>


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


9

Try d0kJx Deletes backwards to the beginning of the line, moves up, then joins the two lines and then removes the space in between the two joined lines. You don't have to leave normal mode with this.


8

The feasibility of deleting parts of lines is elusive and a better vimmer than I will have to explain that. If anyone cares to donate an explanation I'd be happy to add it to this answer. But it's quite possible to delete groups of rows that match a beginning pattern and an ending pattern. The most obvious way, I think, is to combine the :global and :delete ...


7

The easy way: join the lines in the logical blocks before sorting. In detail: mark the lines join the indented lines to the lines above: :'<,'>s/\n /^A/ mark the lines again: gv sort them: :'<,'>sort mark the lines one more time: gv split the lines back and restore indentation: :'<,'>s/^A/\r /g ^A above is the character Ctrl-A (ASCII SOH)...


6

There is a :folddoclosed command which iterates over all closed folds (just like :g command for the whole buffer) and executes one or more commands on them. So I would close all folds, convert each fold into one long line by replacing the end-of-line with a unique marker, shuffle the lines around, and replace the markers with line-breaks. Something along zM ...


5

It turns out something along these lines works (although there might well be better ways) -- using a substitute-without-substituting command instead of a global command: Starting with the answer here: How to show all unique types of a pattern? :%s/[A-Za-z]*\>/\=add(b:types, submatch(0))/ng I went with: let @a='' :%s/func\s*(\_[^;]\{-\};/\=setreg('A', ...


5

I've released a vim plugin that pretty closely matches this behavior. Instead of scrolling by exactly N lines, this maps <C-u>, <C-d> (half window) and <C-j>, <C-k> (quarter window) to scroll as close to N lines as possible due to the wrapped lines, then moves the cursor back to the original relative line position in the Vim window. ...


5

There are a few ways you could do this. The way I would probably do it is this: :%norm I-<space> Note that the <space> should be a literal space, not the text <space>. This simply applies the set of keystrokes I-<space> to every line in the buffer. Uppercase I enters insert mode on the first non-whitespace character of the current ...


5

The two commands below will reduce every line to the first sequence of non-whitespace character followed by a space: from 0.453945 -2.14126e-54 3.40152e-49 101325 214.355 to 0.453945 <-- space But your question is a little confusing so I'm not sure I understood what you want. With a substitution: :%s/\(\S\+\s\).*/\1 With a macro: :%normal! WD


5

yes, you can do with the ^M character in your abbrev, for example: iabbrev Doc #^M# function :^M#^M# returns :^M# will be transformed into: # # function : # # returns : # To get ^M you need to type <C-v> <CR>.


5

To obtain this result you could use :substitute, for example with the cursor on the first line: :s/\u\+/{\0}/g \u\+ one or more uppercase character: equivalent to [A-Z]\+, see:h \u \0 whole matched pattern, see :h sub-replace-special g is a flag needed to replace all occurrences in the line unless gdefault is on To affect more than one line, you can ...


4

What happens if you run: :let @a="" :MSExecNormalCmd "Ay after you have your blocks visually selected? ... the idea (even if the above doesn't work) is still to yank-append each visually selected block to the same register. But, since you use a specific plugin, you are the one who should know how to do it (i.e. reading the plugin's help).


4

I can't use first backreference (\1) instead of hardcoded string Well, you haven't captured anything in the search so \1 has no value in the replacement. You can use a matched text later in the pattern, as a back-reference, as well as in the replacement. :%s/^\(.*\)\n\1/\1/ This allows you to find a line (\(.*\)) which has a duplicate line immediately ...


4

:/baa/,/quz/s/baa/bar/ works, but that will only work with the first occurrence of baa. If you want to replace all occurrences of baa with bar that come before quz: ,/quz/s/baa/bar If your scenario calls for replacing all occurrences of baa if quz is found: /quz/,%s/baa/bar That will replace all occurrences of baa with bar if quz is found. This is ...


4

A macro is certainly capable of doing this. Starting with the first three lines as a template entry 100/1/1 fields value 1 other section 1 is valid Place your cursor on the first line and execute: qqy2EnterjjoEscp$CtrlajCtrlajCtrlakk0q qq Start a macro in register q y2Enter Yank three lines jjoEscp Copy the lines below inserting an extra blank line ...


4

vimscript option For the result: 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 Next "commands" solves it: :for i in range(6)|call setline(i, repeat(' ', (i-1)*2).getline(i))|endfor For the result: 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 Not really sure about the "rule" :) Another option with "...


3

Seems like a great job for macros. Peter Rincker's may be fewer keystrokes, but I feel it's worth mentioning as if you need a more specific range than the whole file, it's a little easier to modify. With your cursor on the first column of the first line do the following: qq to start a macro Wysiw'+ Uses ys on second WORD (Just like Peter's) and moves to ...


3

You can use :normal to run a series of normal commands on lines in the buffer. :%norm Wysiw' This will skip to the second WORD and then use surround's ys command to surround with ' on the current iw text object. It does this for every line in the buffer, %. For more help see: :h :norm :h :range


3

With visual mode: hvk$d Explanation h - Move one to the left v - Start visual mode k$ - Move to the end of the previous line d - Delete selection


3

Probably not exactly the solution you expect, but I'd rather use something like this: :g/^/ if search('^' . getline('.'), 'wn') != line('.') | delete | endif This will also remove duplicates (since you do mention unique sentences), e.g. This This is my first line, but longer. This is my first line, but longer. This is my first line becomes: This is my ...


3

There's something almost perverse in doing this with ex, akin to chopping a tree with a razor blade, or drinking a bucket of water through a straw. But if you stop and think for a few minutes about what you're doing, it's relatively straightforward: ex +'/aa\_.\{-}cc/' +'normal gny' +new +'normal P' +'%p' -scqa! file Translation, for the less masochistic ...


3

If you wanted to delete entire line starting with a space, This pattern will be useful. :g/^\s.*/d g -global ^ - start of the line \s - space .* - anything after that d - delete If you want the starting whitespace to remain, but delete the remaining content, you can use, :%s/^\(\s\+\).*/\1/g


3

I'm not entirely sure what you want to accomplish, but from what I understand, you want to easily create boxes using commands/functions. Maybe this will help you get started on a solution. function! s:makebox(...) abort let width = str2nr(a:1) let height = a:0 < 2 ? width : str2nr(a:2) let margin = a:0 > 2 ? str2nr(a:3) : 0 let r_margin = ...


3

Depending on what you want to perform (copy and paste or cut and paste), you could try one of the 2 following commands: :g/\v^(class|\tdef)/t$ :g/\v^(class|\tdef)/m$ To duplicate (copy and paste) the current line after the last one, you can use the :t command: :t$ Like most Ex commands :t can be prefixed with an optional range, and like most Ex commands, ...


3

Edit: Actually, you could do it with a single global command: g/^/if str2nr(getline('.')) <= str2nr(getline(line('.')-1)) | d_ | endif Old answer: Maybe you could try these 2 global commands: :g/^/if str2nr(getline('.')) <= str2nr(getline(search('[^x]$', 'bnW'))) | s/$/x/ | endif :g/x$/d_ The first one should append an x at the end of any line ...


3

This feels like a job for awk: $ awk '$1 > x {x = $1;print}' in_file.txt Or using filter, :[range]!, inside of Vim: :%!awk '$1 > x {x = $1;print}' For more help, see: :h :range! :h :range


2

You can use a filter. I would probably use sed for arbitrary multi-line matching. There is a drawback in that there is no way in sed to do non-greedy matching, but in certain cases you can work around that. (For example, add only one line at a time until you get a match, then do the substitute, as below.) Your examples aren't using non-greedy matching in ...


2

You are close. If you can live with an error "E16: invalid range" make the delete command delete the next line: :g/^\(.*\).*\n\1$/+d Using :g with patterns matching several lines is tricky and this works for your special case, but it does not always work as one expect it. Another alternative is to simply use the :s command: :%s/^\(\(.*\).*\)\n\2$/\1 ...


2

Ok, it was very close and this actually worked: :/baa/,/quz/s/baa/bar/


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