Hot answers tagged

14

You could try the following command: :let c=0 | g/^* /let c+=1 | s//\=c.'. ' First it initializes the variable c (let c=0), then it executes the global command g which looks for the pattern ^* (a beginning of line, followed by an asterisk and a space). Whenever a line containing this pattern is found, the global command executes the command: let c+=1 | s//...


9

This only works with a recent Vim version (that has :h v_g_CTRL-A): Block-select the list bullets (*) and replace them with 0 (cursor is on first *): Ctrl-v j j r 0. Reselect previous block and increment with counter: gv g Ctrl-a ... and that's it :) (If you want to have a dot after each number, change 1st step to: Ctrl-v j j s 0 . Esc)


9

Visually select the lines and execute this substitution command: :'<,'>s/*/\=line('.') - line("'<") + 1 . '.' See :help sub-replace-expression, :help line(), and :help '<. To avoid having to select the lines, backward and forward searches with offsets can be used to specify the substitution range like this: :?^[^*]?+1,/^[^*]/-1s/*/\=line('.') ...


6

In :<from>,<to>command, both <from> and <to> are relative to the current line. What you want is to make <to> relative to <from>. For this you need :help :;: :/foo/;,/bar/command where the cursor is moved to /foo/ first, which becomes the current line. :/<table class=.bar\_.\{-}\zs<tr/;,/table>/sort! n /.\{-}&...


6

A If you just want to quickly confirm the validity of the range (and it isn't too long), you can use the built-in :print or :number: :/<head/,/\/head>/print B Another idea would be (mis-)using the visual selection. The following custom command creates a linewise selection of the passed range: ":[range]SelectRange Create a linewise visual ...


5

To get the count given to <C-E>, you don't need to use the range to do it. There are two pre-defined variables you can use, v:count and v:count1, which contain the count given to the last normal mode command. The former should work for you, as it will be zero when no count has been given. The latter defaults to 1 in same situation. Here is a minimal ...


4

As I said in the comments I strongly recommend a plugin like nerdcommenter or vim-commentary to do stuff like this because they are well tested and handle a lot of corner cases. Now if you want to do it by yourself a solution could be the following. First create a function which takes two numbers as arguments and uses these numbers as the lines on which it ...


4

I looked into this, and I could not find a direct way of doing it. However, one possibility is to create an auxiliary function, that is: function! Range() range abort return RangeAux(a:firstline, a:lastline) endfunction function! RangeAux(lnum1, lnum2) abort echo a:lnum1 echo a:lnum2 endfunction 1,3call Range() call RangeAux(1,3)


4

Using ex Ex is the command-line successor to the venerable ed, a line-oriented editor. You can access ex-mode from vim by typing Q (unless you have it mapped). gQ gives an improved ex-mode. See :help Ex-mode. You can also start ex from the command line, just like vim: ex {file} Then you type your commands, and ex does them. All the :-style commands ...


3

I could be wrong but I think the atom \ze does take effect, it just doesn't prevent Vim to find a match on the group3 line. It's an empty match since you write \ze just after the anchor ^ which excludes everything afterwards. But even if it's empty, it's still something, the beginning of the line. Maybe you could use an offset: :/group2\n\zs/;,/^\ze\S/- p ...


3

You can express the penultimate line with $-1. So, in your case, to prepend X in front of all the lines from the fifth down to the second to last one, you could use the following substitution command: :5,$-1s/^/X You can find more information on how to write a range in :help :range.


3

Well actually you can use a litteral <ESC> character to chain commands like you would do normally: :'<,'>norm! A,^II+ This will insert a , at the end of each line, and a + at the start. To add the special ^I char, press C-v and ESC.


3

Here is a solution which comes from here. Note that might not be exactly what you're looking for since it's implies to use a visual (or normal) mode mapping instead of just an ex command. The idea is to create the following mapping which will allow you to keep in your buffer only the visually selected lines: vnoremap <key> :<C-U>1,'<-1:...


3

You can use the :yank ex command: :/pattern1/;/pattern2/yank a a is the register you want to use and has a default value. Note: You used ;, in your command. It should be either ; or ,, not both.


3

See this answer on stackoverflow. The example given is: function! PrintGivenRange() range echo "firstline ".a:firstline." lastline ".a:lastline " Do some more things endfunction command! -range PassRange <line1>,<line2>call PrintGivenRange() Thus you might want to create a function which would use the range and do the tmux call ...


3

@Karl's answer is pretty good but you can also use execute(): echo execute("1,2call Range()") You can even use variables for the range: let l1=1 let l2=2 echo execute(l1 . "," . l2 . "call Range()")


3

ex -s +'norm! gg"adiwdd' +'exec printf("%%s/^/%s : /", @a)' +'x' ex_txt norm! gg"adiwdd delete black in 1st line to register a, delete first line exec printf("%%s/^/%s : /", @a) add content of register a to start of every line. You can get content of register a via @a or getreg('a') in ex mode . check :h printf() if you have problem with %%. x save and exit ...


3

@D.BenKnoble has already given you a terrific answer explaining all the ins and outs of batch mode, but in case you were looking for a one liner similar to the one you already tried, here's one that I think is a bit simpler than the existing ones in the current answers: ex -sc 'norm!ggy$dd' -c '%norm!i^R0: ' -c 'x' file The first :normal command moves to ...


2

Per @statox comment... Using normal commands applied to ranges is the same as when they are used in scripts, requiring the normal function to be called. :?^[^\/][^\/]?+1,/^[^\/][^\/]/-1norm gq A very common example of this is applying a macro to each line in a visually selected area. Lets say you want to uppercase the last word on each line: qq$viwUq If ...


2

Another way: :let n = 1 | g/^* /s//\=printf('%d. ', n)/g | let n = n + 1


2

Here are two functions that you could use. Both takes as argument a pattern to search and a command to execute on the consecutive lines matching the pattern. You can call them with: call RangeFromPattern("^\s*-", "!sort -u") The first one goes to the first line of the buffer, searches for the first line matching the pattern, then goes to the last line of ...


2

As @romainl said, you can use the [ and ] marks for this purpose, e.g.: nnoremap gc `[v`] Pressing gc visually select the previous change. :'[,']s/var_name/varName/g Replace in the last modified lines every var_name with varName If you want to use it in your function you can get informations about the last changed lines like so: let firstline = line("'[...


2

You can define a function in your .vimrc: function! GetVisualSelection() let [lnum1, col1] = getpos("'<")[1:2] let [lnum2, col2] = getpos("'>")[1:2] let lines = getline(lnum1, lnum2) let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)] let lines[0] = lines[0][col1 - 1:] return join(lines, "\\n") ...


2

Have you looked at Quick search, limited to a C++ function all the techniques presented in this discussion shall apply to your question. I'm not sure my solution is checking the cursor is within a function definition. To check for improper uses, you have to define a function. There, first record the current line, and then check the first and last line you ...


2

In the following range, the offset is calculated from "the current line" which may or may not be a match for /foo: :/foo/,+23# You can use ; to make the first line matching foo the first line specifier of your range: :/foo/;.,+23# which gives you three line specifiers. You can use more semicolons to refine your range: :/foo/;/bar/;/baz/#


2

Almost right below your quote from documentation it also says: When separated with ';' the cursor position will be set to that line before interpreting the next line specifier. So while there seems to be no commands that are able to accept more than two specifiers, they still can be useful to adjust starting position of other specifiers. Example ...


2

My approach :g/group2/+1,/group3/-1p


2

If you want to have the table spacing inferred using the whole file, you could delete the headlines, run column on the resulting file and reinsert the headlines using something like this: function! Column() let b:headlines={} g/^##.*$/let b:headlines[line(".")+len(b:headlines)]=getline(".")|d %!column -ts, call map(b:headlines, 'append(v:key-1, v:...


2

Assuming the lines that start with a minus will be contiguous, I would use visual mode (assuming vim). Highlight the minus lines, then :sort will get you there. The whole sequence, assuming a file with that format, starting at the first character of the file: jVGk:sort


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