vim function argument

46 views
Skip to first unread message

Yang Luo

unread,
Jul 14, 2016, 2:41:27 AM7/14/16
to vim_use

I write a function like this:
function InsertNumber(start, end, step)

let i = a:start

let curr_line = 0

while i <= a:end
if a:step <= 0
echo "Error: step cannot <=0."
break
endif

call append(curr_line, i)

let i += a:step

let curr_line += 1

endwhile
endfunction


when I call this function, I type this:
:echo InsertNumber(8,10,1)
8
9
10


1) How can I give arguement "step" a default value(eg: 1) when define the function?
like a C function:
void C_func(int a, int b_have_default_val = 1)
{

;
}
2)
I want to print number like this, how to do it?
08
09
10

Jürgen Krämer

unread,
Jul 14, 2016, 3:09:42 AM7/14/16
to vim...@googlegroups.com

Hi,

Yang Luo schrieb am 14.07.2016 um 08:41:
>
> I write a function like this:
> function InsertNumber(start, end, step)
>
> let i = a:start
>
> let curr_line = 0
>
> while i <= a:end
> if a:step <= 0
> echo "Error: step cannot <=0."
> break
> endif
>
> call append(curr_line, i)
>
> let i += a:step
>
> let curr_line += 1
>
> endwhile
> endfunction
>
>
> when I call this function, I type this:
> :echo InsertNumber(8,10,1)
> 8
> 9
> 10
>
>
> 1) How can I give arguement "step" a default value(eg: 1) when define the function?
> like a C function:
> void C_func(int a, int b_have_default_val = 1)
> {
>
> ;
> }

you can use optional arguments like this

function InsertNumber(start, end, ...)
if a:0 == 0
let l:step = 1
else
let l:step = a:1
endif
...
endfunction

> 2)
> I want to print number like this, how to do it?
> 08
> 09
> 10

Use the printf() function:

call appendline(curr_line, printf('%02d', i))

Or if your numbers can have more than two digits:

let width = trunc(log10(a:end)) + 1
let format = '%0' . width . 'd'
call appendline(curr_line, printf(format, i))


Regards,
Jürgen

--
Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us. (Calvin)

Yang Luo

unread,
Jul 14, 2016, 5:01:19 AM7/14/16
to vim_use
thanks alot

Yang Luo

unread,
Jul 14, 2016, 6:06:27 AM7/14/16
to vim_use

I complete the function as follow, now I want to add radix option, but I don't know how to get width. Can you help me complement it

function InsertNumber(start, end,...) " step,is_column_first_0_padding,radix(b,d,o,x)
let l:i = a:start
let l:curr_line = 0
if a:0 == 0 " a:0 extra argument numbers


let l:step = 1
else

let l:step = a:1 " the first extra argument
endif
if a:0 == 2
let l:is_padding = 0
else
let l:is_padding = 1 "default padding
endif
if a:0 == 3
let l:radix = a:3
else
let l:radix = ""
endif
if l:radix == "b"
elseif l:radix == "o"
elseif l:radix == "x"
else
let l:width = float2nr(trunc(log10(a:end))) + 1
let l:format = '%0'.l:width.'d'
endif
while l:i <= a:end
if l:step <= 0


echo "Error: step cannot <= 0."
break
endif

if l:is_padding == 1
call append(curr_line, printf(l:format, l:i))
else
call append(curr_line, l:i)
endif
let l:i += l:step
let l:curr_line += 1
endwhile
endfunction

Jürgen Krämer

unread,
Jul 14, 2016, 8:52:54 AM7/14/16
to vim...@googlegroups.com

Hi,
there is an simpler way to calculate the necessary width -- just count
the number of characters used for the a:end parameter when printed:

let width = strlen(printf('%d', a:end))

This can also be used to calculate the width for other radices than 10:

if l:radix == "b"
let width = strlen(printf('%x', a:end)) * 4
elseif l:radix == "o"
let width = strlen(printf('%o', a:end))
elseif l:radix == "x"
let width = strlen(printf('%x', a:end))
else
let width = strlen(printf('%d', a:end))
endif

Note that there is no specification for output as a binary number in
printf().

Nikolay Aleksandrovich Pavlov

unread,
Jul 14, 2016, 12:00:53 PM7/14/16
to vim...@googlegroups.com
2016-07-14 13:06 GMT+03:00 Yang Luo <youngl...@gmail.com>:
>
> I complete the function as follow, now I want to add radix option, but I don't know how to get width. Can you help me complement it
>
> function InsertNumber(start, end,...) " step,is_column_first_0_padding,radix(b,d,o,x)
> let l:i = a:start
> let l:curr_line = 0
> if a:0 == 0 " a:0 extra argument numbers
> let l:step = 1
> else
> let l:step = a:1 " the first extra argument
> endif

let l:step = get(a:000, 0, 1)

Other arguments are to be handled in a similar fashion.

> if a:0 == 2
> let l:is_padding = 0
> else
> let l:is_padding = 1 "default padding
> endif
> if a:0 == 3
> let l:radix = a:3
> else
> let l:radix = ""
> endif

let l:radix = get(a:000, 2, 'd')

(needed for the below suggestion).

> if l:radix == "b"
> elseif l:radix == "o"
> elseif l:radix == "x"
> else
> let l:width = float2nr(trunc(log10(a:end))) + 1

let l:width = len(a:end)

For other radix variants you will have to use printf indeed.

I could even suggest

let l:format = '%0*' . l:radix
let l:width = len(printf('%' . l:radix, a:end))

(note: no if’s at all).

> let l:format = '%0'.l:width.'d'

let l:format = '%0*d'

> endif
> while l:i <= a:end
> if l:step <= 0
> echo "Error: step cannot <= 0."
> break
> endif

This is wrong place to check, l:step does not change, but you check it
constantly. Move all arguments checks just below the place where you
define arguments.

> if l:is_padding == 1
> call append(curr_line, printf(l:format, l:i))

call append(curr_line, printf(l:format, l:width, l:i))

> else
> call append(curr_line, l:i)
> endif
> let l:i += l:step
> let l:curr_line += 1
> endwhile
> endfunction
>
> --
> --
> You received this message from the "vim_use" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>
> ---
> You received this message because you are subscribed to the Google Groups "vim_use" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Yang Luo

unread,
Jul 17, 2016, 5:14:26 AM7/17/16
to vim_use
thanks a lot, I get the final version.

function InsertNumber(start, end,...) " step, radix(d,o,x), is_padding
let l:i = a:start
let l:curr_line = 0

let l:step = get(a:000,0,1)

"echo l:step
if l:step <= 0


echo "Error: step cannot <= 0."

return -1
endif

let l:radix = get(a:000,1,'d')
"echo l:radix

if a:0 == 3
let l:is_padding = 0
else
let l:is_padding = 1 "default padding
endif

if l:radix == "o"
"let l:width = strlen(printf('%o',a:end))


let l:width = len(a:end)

let l:format = '%0'.l:width.'o'


elseif l:radix == "x"

"let l:width = strlen(printf('%x',a:end))


let l:width = len(a:end)

let l:format = '%0'.l:width.'x'


else
"let l:width = float2nr(trunc(log10(a:end))) + 1

"let l:width = strlen(printf('%d',a:end))


let l:width = len(a:end)

let l:format = '%0'.l:width.'d'

endif

while l:i <= a:end


if l:is_padding == 1

call append(l:curr_line, printf(l:format, l:i))
else
call append(l:curr_line, l:i)


endif
let l:i += l:step

let l:curr_line += 1
endwhile
endfunction

Reply all
Reply to author
Forward
0 new messages