I want to implement a function that cycles through setting the line numbers.
I'm having trouble evaluating the state of the number command. For instance I have tried:
function! CycleNumbers()
if exists(":number")
set nonumber
elseif exists(":nonumber")
set number
endif
endfunction
Is there a way to test for number being off? Something like number==off?
Thank you for your help
why not check the option value? something like :
let &number = &number? 0: 1
or simply as you said in comment, set nu!
to get the information, if line number is shown, read &number variable. if it's 1 the number is currently showing. 0, not.
something like:
if &number
"showing
else
"not showing
endif
fill your logic codes there.
You can toggle an option with the exclamation mark (on the command line):
:set number!
See also :help set-!
If you insist on having a function, then you want something like
fu! CycleNumbers()
set number!
endfu
Edit
If you want to query the current value of the option, you use the &option syntax:
if &number == 0
...
else
...
endif
Related
I tend to enable auto-wrap :
:set textwidth=80
:set formatoptions+=wt
But I don't want to wrap when I input a long string in quotes when I coding with C or javascript, because it will be error;
Can I configure my vim auto-wrap exclude quotes?
or auto typing '\' before wrapping this line?
You can start from this little script which I coded and add some improvements in order to fit your needs:
"""""the event that will trigger the wrap (leaving insert mode)
au InsertLeave * call WrapLines()
"""""highlight the column where the wrapping will be made
set colorcolumn=30
"""""WrapLines will be executed on lines
function! WrapLines()
execute ":%g/^/ call WrapFunction()"
endfunction
"""""check and wrap the line
function! WrapFunction()
let l:line=getline(".")
let l:length=strlen(l:line)
let l:occurence=0
let l:i=0
let l:nb=30
for l:i in split(l:line,'\zs')
if matchstr(l:i,'"') != ''
let l:occurence+=1
let l:occurence=l:occurence % 2
endif
let l:nb-=1
if l:nb == 0
break
endif
endfor
if l:length >= 30
if l:occurence == 0
"""""to get ^M you need to type <ctrl-v><enter> buttons
normal! 30|i^M
endif
endif
endfunction
Note: to get the ^M in the code please type ctrl+v Enter
Name and save the file ex:script.vim and call it after that by the command ":source script.vim"
Here is the example: ( 30 characters - Limit -):
Your settings are wrapping the lines by adding carriage return and which cause problem while compiling.
Instead you can use the wrap option which is a virtual wrap and doesn't affect the lines:
:set wrap
:set textwidth=0
:set wrapmargin=0
I have this loop in my .vimrc to display the tab title as "1: File1.txt" or "2: File2.tx", etc, but both tabpagenr('$') and tabpagenr() always returns 1 no matter how many tabs I open. What am I doing wrong?
for t in range(tabpagenr('$'))
if (t + 1) == tabpagenr()
let &titlestring = t + 1 . ': '
endif
endfor
let &titlestring .= expand("%:M")
if &term == "screen" || &term == "xterm"
set title
endif
It looks like there are some bits missing from your sample code: how do you expect to change your tab labels with only those few lines?
Anyway, without an argument, tabpagenr() returns the number of the current tab. Since you are always in the same tab during your loop, that function always returns the same number.
:help setting-tabline has an example, did you read it?
You didn't tell us on which events your code is executed. If you plainly put this in your ~/.vimrc, it will only be executed once during Vim startup. You need to use :autocmd to update the 'titlestring', at least on every tab page change (i.e. the TabEnter event), or better use an expression in the option to have it continuously evaluated:
:set titlestring=%{tabpagenr()}
I want to conveniently remove an accidentally placed tab while using vim. The solution that jumped out to me is making an insert-mode mapping to the following vim function:
function DeleteTab()
redir => l:numSpaces "captures output of set
set tabstop?
redir END
"Strip off non-numerical output of 'set tabstop?'
let l:numSpaces = substitute(l:numSpaces, "tabstop=", "", "")
let l:numSpaces = substitute(l:numSpaces, " ", "", "g")
"all echom lines are for debugging purposes
echom "1"
if l:numSpaces > 0
echom "2"
while 1:numSpaces > 0
execute "normal i<bs>"
let l:numSpaces = l:numSpaces - 1
endwhile
endfunction
In addition to not doing what I intended, the result of calling this function is "1" in my messages, but not "2". This means that l:numSpaces is not being interpreted as a number. How do I do the equivalent of casting in vimscript. Also, am I missing a more easy approach?
Instead of doing the redir just use &tabstop the ampersand gets the value and places it in the variable.
let l:numSpaces = &tabstop
The next problem you have is with this line
while 1:numSpaces > 0
You wrote a 1 (one) instead of l (lowercase L)
So the fixed function looks something like this.
function! DeleteTab()
let l:numSpaces = &tabstop
echom "1"
if l:numSpaces > 0
echom "2"
endif
while l:numSpaces > 0
execute "normal i<bs>"
let l:numSpaces = l:numSpaces - 1
endwhile
endfunction
Also this function is kinda pointless. I believe the behavior you want should be achieved if you set the following (or to what ever value you want)
set tabstop=4
set softtabstop=4
set shiftwidth=4
Hitting the backspace key should go back a full tab if you insert an accidental tab.
If you want to access the value of an option in vimscript, you can use the syntax &option (see :help expr-option). That simplifies the first half of your function to
let numSpaces = &tabstop
As far as undoing an accidental tab, all that should require is pressing Backspace, unless you aren't inserting tab characters.
If you mean you want to "remove a level of indentation" instead of "remove a tab", then you should use the builtin command for that, pressing Ctrl+d in insert mode. Similarly, you can use Ctrl+t to add a level of indentation to the current line. Both of these work regardless of where your cursor is in the current line, unlike trying to manage the indentation manually with Backspace, as well as doing the Right Thing based on your 'shiftwidth', 'expandtab', and 'tabstop' settings.
I know my question title is not explanatory enough so let me try to explain.
I created a vim function that displays my current battery state. My function is as follows:
function! BatteryStatus()
let l:status = system("~/battery_status.sh")
echo join(split(l:status))
endfunction
I have mapped the above function as nnoremap <F3> :call BatteryStatus()<cr>. Now, when I press F3 it displays my battery status as Discharging, 56%, 05:01:42 remaining which is my required output but my question is how do I make the above output disappear.
Currently what happens is after function call it continuously displays the output and I have to manually use :echo to clear the command window(:).
So, what necessary changes are to be made in my function so that I can achieve toggle like behaviour.
battery_status.sh
acpi | awk -F ": " '{print $2}'
PS: This is part of a learning exercise. So, please don't suggest alternative vim scripts.
Simplistic straightforward way to toggling the output:
let s:battery_status_output_flag = "show"
function! BatteryStatus()
if s:battery_status_output_flag == "show"
let l:status = system("~/battery_status.sh")
echo join(split(l:status))
let s:battery_status_output_flag = "clear"
else
echo ""
let s:battery_status_output_flag = "show"
endif
endfunction
Note s: prefix, see :help script-variable
You can define a autocmd:
:au CursorHold * redraw!
Vim redraws itself 4 sec (set by updatetime option) after it's idle.
vim
function! pseudocl#render#clear()
echon "\r\r"
echon ''
endfunction
You can just Ctrl+ L to clear the message on the status
line.
Drawing a blank on this, and google was not helpful.
Want to make a function like this:
function JakPaste()
let tmp = :set paste?
if tmp == "paste"
set nopaste
else
set paste
endif
endfunction
map <F2> :call JakPaste()<CR>
However this does not work. I have isolated the broken line:
function JakPaste()
let tmp = set paste?
endfunction
map <F2> :call JakPaste()<CR>
Pressing F2 results in this error:
Error detected while processing function JakPaste:
line 1:
E121: Undefined variable: set
E15: Invalid expression: set paste?
Hit ENTER or type command to continue
How should I call an ex command (set) from a vim function?
This seems somewhat relevant however I still don't get it.
The reason this doesn't work is that you're trying to run a command in an expression - those are different things. The ? construct you used just causes vim to echo the value of the option; this isn't the same as a function returning the value. To be clear: the problem isn't that you're calling an ex command from a function - every other line of the function is an ex command - it's that you're calling the ex command in an expression.
But that's not the right way to carry out the task you're attempting here. Here's the shortest way, thanks to rampion's comment:
set paste!
Now, if you ever need something smarter than just inverting a boolean, you can use & to turn an option name into a usable variable. Here are two ways to use that:
" still a function, good for taking extra action (here, printing notification)"
function TogglePaste()
if (&paste)
set nopaste
echo "paste off"
else
set paste
echo "paste on"
endif
endfunction
" just set the variable directly"
let &paste = !&paste