This is a small part of the file, the original file has hundreds of lines.
Line 1 below insert the new line Numbers 1, 2, 3 lines below the new line number 2, 3, and so on, are as follows.
How to use gVim command and function to achieve the change from above to below.
I'm using gVim of windows platform.
Before the modification
hsd
xlfh
1lm
2lm
3lm
4lm
5lm
6lm
7lm
8lm
9lm
slm
s1lm
......
After the modification
hsd
1
xlfh
1lm
2
3
2lm
3lm
4lm
4
5
6
5lm
6lm
7lm
8lm
7
8
9
10
9lm
slm
s1lm
......
I do not know why you would need to do this, but if you need this often, consider a function inside .vimrc:
function! Nameme()
1
let mov = 1
let start = 1
let inc = 0
while 1
call append(line('.'), range(start, start+inc))
let mov += 2
let inc += 1
let start += inc
if mov + line('.') > line('$')
break
endif
execute mov + line('.')
endwhile
endfunction
Then you could just :call Nameme().
It is possible in Vim, merging another file containing the numbers to insert (created by /bin/cat -n for example), here is the beginning.
gg go to first line
o1<esc>"ayy a (will increase) initialized to 1
"byy b (will be cumsum of a) initialized to 1
qz loop this:
:.,<c-r>a advance by a lines
"bp put a(a-1)
... but I will only continue if you format your question so that it does not end up deleted
Related
This question already has answers here:
Printf without newline in assembly
(5 answers)
Printing an entire array on a single line using printf asm nasm
(3 answers)
Closed 2 years ago.
So, i faced with a problem, that print each value of variable on a new line, but format for print is a line. I really spend a lot of time that find solution. But this solution don't work. I think that is because i am noob in assembler. So, i deleted all my fail... This is my code:
global main
extern printf
section .data
str: db "%i", 10, 0
count: dw 1
section .text
main:
start:
push dword [count]
push dword str
call printf
push dword [count]
push dword str
call printf
So, now in terminal printed this:
1
1
What do I need to do to print like this:
1 1
Please, example me code, that i understand.... Please, don't send me first link in internet with similar problem, because i tried this. I really don't understand...
How i can insert in print string with differents char, for example ':', 'space', '/' and other...?
Thanks you :)
Change
str: db "%i", 10, 0
to
str: db "%i ", 0
10 is a newline character. This replaces it with a space.
Whenever I add files to my args, the same files are also added to my list of buffers. This happens with set hidden and set nohidden. This is not the expected behaviour, right? And how do I stop it?
:ls
1 a "[No Name]" line 1
:args *
:ls
1 a "[No Name]" line 1
3 %a "globals.js" line 1
4 "package.json" line 0
5 "README.md" line 0
6 "spec" line 0
7 "tags" line 0
Spec is a directory not a file, which prompted me to experiment with disabling NERDTree but that made no difference.
It is the standard/normal behavior.
You can switch to the next file using :next.
I'm new to Vimscript but I am trying to find all the lines which contain #property.
What I am trying is:
norm! gg
wh search( "#property", "cW" ) != 0
echo getline( "." )
endw
But this code has a deadlock. What am I doing wrong?
Don’t pass the c flag, or at least not every time. c specifies that a match at the cursor should be accepted – but search() always moves the cursor to a match!
For example,
let flags = "cW"
while search("#property", flags) != 0
echo getline(".")
let flags = "W"
endwhile
I have some parameters in a text file which goes as follows
parameter1 =5
parameter2=4
----------
---------
parameter(n-1) = 6
parameter(n)=11
My requirement is that the values of the parameters should sum upto 100 and there can be number of parameters. I was wondering if I could write a function in Vim , which could calculate the sum and display it somewhere?
I have no idea how to pass arguement to such a function,I was thinking it could somehow be done by block selecting the lines with parameter values.
Add following function to your vimrc file:
function! CustomSum()
let sum = 0
for l in range( 1, line('$') )
let fields = split( getline(l), '\s*=\s*' )
if ( len( fields ) != 2 || fields[1] =~? '\D' )
continue
endif
let sum = sum + fields[1]
endfor
return sum
endfunction
And run it:
:echo CustomSum()
That with your input data yields:
26
EDIT to add a range to previous function. Now accepts a range as input parameters named a:firstline and a:lastline. I increment them with 0 to convert them to integers, otherwise the range function complains. Last line echoes the result for debugging but would be better idea to handle the result in a return call (only uncomment it).
function! CustomSum() range
let sum = 0
for l in range( a:firstline + 0, a:lastline + 0 )
let fields = split( getline(l), '\s*=\s*' )
if ( len( fields ) != 2 || fields[1] =~? '\D' )
continue
endif
let sum = sum + fields[1]
endfor
echo sum
"" return sum
endfunction
Now you can do visually selection or normal ranges, like:
:'<,'>call CustomSum()
or
:1,5call CustomSum()
Both should work.
This can also be done with a (pseudo) one-liner as well:
:let s=0
:g/parameter\d\+\s*=\s*\d\+/let s+=matchstr(getline('.'), '\d\+\s*$')
:echo s
It you want a function you fall back to Birei's solution
EDIT: BTW, we can also echo it directly with:
echo eval(join(map(filter(getline(1,'$'), 'v:val =~ "=\\s*\\d"'), 'matchstr(v:val, "=\\s*\\zs\\d\\+")'), '+'))
or if you prefer a command:
command! -nargs=0 -range=% Sum echo eval(join(map(filter(getline(<line1>,<line2>), 'v:val =~ "=\\s*\\d"'), 'matchstr(v:val, "=\\s*\\zs\\d\\+")'), '+'))
I am a vim user, and I want to be able to loop over a range of substrings when I am substituting. How can I use some vim magic to go from a set of lines like this:
Afoo
Bfoo
Cfoo
Dfoo
to
Abar
Bbar
Cbaz
Dbaz
?
I want to search my file from the start for the next occurance of foo, and replace the first two instances with bar, and the second two with baz. Is using a for loop the best option? If so, then how do I use the loop variable in the substitution command?
I would use a function that has a state, and call this function from %s. Something like:
" untested code
function! InitRotateSubst()
let s:rs_idx = 0
endfunction
function! RotateSubst(list)
let res = a:list[s:rs_idx]
let s:rs_idx += 1
if s:rs_idx == len(a:list)
let s:rs_idx = 0
endif
return res
endfunction
And use them with:
:call InitRotateSubst()
:%s/foo/\=RotateSubst(['bar', 'bar', 'baz', 'baz'])/
The call to the two commands could be encapsulated into a single command if you wish.
EDIT: Here is a version integrated as a command that:
accepts as many replacements as we wish, all the replacements needs to be separated with the separator-character ;
supports back-references ;
can replace only the N first occurrences, N == the number of replacements specified if the command call is banged (with a !)
does not support usual flags like g, i (:h :s_flags) -- for that, we would have for instance to impose the command call to always ends up with a / (or whatever separator-character), if not the last text is interpreted as flags.
Here is the command definition:
:command! -bang -nargs=1 -range RotateSubstitute <line1>,<line2>call s:RotateSubstitute("<bang>", <f-args>)
function! s:RotateSubstitute(bang, repl_arg) range
let do_loop = a:bang != "!"
" echom "do_loop=".do_loop." -> ".a:bang
" reset internal state
let s:rs_idx = 0
" obtain the separator character
let sep = a:repl_arg[0]
" obtain all fields in the initial command
let fields = split(a:repl_arg, sep)
" prepare all the backreferences
let replacements = fields[1:]
let max_back_ref = 0
for r in replacements
let s = substitute(r, '.\{-}\(\\\d\+\)', '\1', 'g')
" echo "s->".s
let ls = split(s, '\\')
for d in ls
let br = matchstr(d, '\d\+')
" echo '##'.(br+0).'##'.type(0) ." ~~ " . type(br+0)
if !empty(br) && (0+br) > max_back_ref
let max_back_ref = br
endif
endfor
endfor
" echo "max back-ref=".max_back_ref
let sm = ''
for i in range(0, max_back_ref)
let sm .= ','. 'submatch('.i.')'
" call add(sm,)
endfor
" build the action to execute
let action = '\=s:DoRotateSubst('.do_loop.',' . string(replacements) . sm .')'
" prepare the :substitute command
let args = [fields[0], action ]
let cmd = a:firstline . ',' . a:lastline . 's' . sep . join(args, sep)
" echom cmd
" and run it
exe cmd
endfunction
function! s:DoRotateSubst(do_loop, list, replaced, ...)
" echom string(a:000)
if ! a:do_loop && s:rs_idx == len(a:list)
return a:replaced
else
let res0 = a:list[s:rs_idx]
let s:rs_idx += 1
if a:do_loop && s:rs_idx == len(a:list)
let s:rs_idx = 0
endif
let res = ''
while strlen(res0)
let ml = matchlist(res0, '\(.\{-}\)\(\\\d\+\)\(.*\)')
let res .= ml[1]
let ref = eval(substitute(ml[2], '\\\(\d\+\)', 'a:\1', ''))
let res .= ref
let res0 = ml[3]
endwhile
return res
endif
endfunction
which could be used this way:
:%RotateSubstitute#foo#bar#bar#baz#baz#
or even, considering the initial text:
AfooZ
BfooE
CfooR
DfooT
the command
%RotateSubstitute/\(.\)foo\(.\)/\2bar\1/\1bar\2/
would produce:
ZbarA
BbarE
RbarC
DbarT
This is Not strictly what you want but can be useful for cycles.
I've written a plugin swapit http://www.vim.org/scripts/script.php?script_id=2294 which among other things can help with cycling through lists of strings. Eg.
:Swaplist foobar foo bar baz
then type
This line is a foo
create a simple yank/paste line, go to last word and ctrl-a swap.
qqyyp$^A
then execute the swap pattern
100#q
to get
This line is foo
This line is bar
This line is baz
This line is foo
This line is bar
This line is baz
This line is foo
This line is bar
This line is baz
This line is foo
This line is bar
This line is baz
...
It could probably be applied to your problem although its {cword} sensitive.
Why not:
:%s/\(.\{-}\)foo\(\_.\{-}\)foo\(\_.\{-}\)foo\(\_.\{-}\)foo/\1bar\2bar\3baz\4baz/
I'm not sure that it covers the breadth of the problem but does have the virtue of being a simple substitute. A more complex one may cover the solution if this one doesn't.
This is how I'd attempt that macro.
qa Records macro in buffer a
/foo<CR> Search for the next instance of 'foo'
3s Change the next three characters
bar To the word bar
<Esc> Back to command mode.
n Get the next instance of foo
. Repeat last command
n Get the next instance of foo
3s Change next three letters
baz To the word bar
<Esc> Back to command mode.
. Repeat last command
q Stop recording.
1000#a Do a many times.
Any advice on how to do it better is welcome.
thanks,
Martin.
It's probably going to be much easier to record a macro that can replace the first two, and then use :s for the rest.
The macro might look like /foo^Mcwbar^[. If you're not familiar with macro mode, just hit q, a (the register to store it in) and then the keystrokes /foo <Enter> cwbar <Escape>.
Now once you've got that macro, do 2#a to replace the first two occurrences in the current buffer and use :s normally to replace the rest.