Reply to message «optwin.vim - setlocal on global options ? ...», sent 10:13:02 30 January 2011, Sunday by Marc Weber:
> fun! <SID>BinOptionL(name)
> exe "norm! \<C-W>p"
> exe "let val = &" . a:name
> exe "norm! \<C-W>p"
> call append("$", substitute(substitute(" \tset " . val . a:name . "\t"
> . \!val . a:name, "0", "no", ""), "1", "", ""))
> endfun
>
> Why is it important to keep it fast - is :options used that often?
> why is exe used if there is wincmd p (or even getbufvar ?)
> ... some more questions appear but its not worth writing them down.
By the way, is substitute really faster then ((val)?(""):("no"))? I guess it is
not.
Other possible improvements:
--- /usr/share/vim/vim73/optwin.vim 2011-01-24 05:44:22.000000000 +0300
+++ optwin.vim 2011-01-30 12:43:32.000000000 +0300
@@ -26,15 +26,11 @@
fun! <SID>CR()
" If on a continued comment line, go back to the first comment line
- let lnum = line(".")
+ let lnum = search("^[^\t]", 'bWcn')
let line = getline(lnum)
- while line[0] == "\t"
- let lnum = lnum - 1
- let line = getline(lnum)
- endwhile
" <CR> on a "set" line executes the option line
- if match(line, "^ \tset ") >= 0
+ if line[:5] ==# " \tset "
" For a local option: go to the previous window
" If this is a help window, go to the window below it
@@ -63,7 +59,7 @@
let line = getline(lnum)
" <Space> on a "set" line refreshes the option line
- if match(line, "^ \tset ") >= 0
+ if line[:5] ==# " \tset "
" For a local option: go to the previous window
" If this is a help window, go to the window below it
@@ -79,21 +75,21 @@
" find the window in which the option applies
" returns 0 for global option, 1 for local option, -1 for error
fun! <SID>Find(lnum)
- if getline(a:lnum - 1) =~ "(local to"
+ if stridx(getline(a:lnum-1), "(local to")!=-1
let local = 1
let thiswin = winnr()
- exe "norm! \<C-W>p"
- if exists("b:current_syntax") && b:current_syntax == "help"
- exe "norm! \<C-W>j"
+ wincmd p
+ if getbufvar(winbufnr(0), '&buftype') ==# "help"
+ wincmd j
if winnr() == thiswin
- exe "norm! \<C-W>j"
+ wincmd j
endif
endif
else
let local = 0
endif
- if local && (winnr() == thiswin || (exists("b:current_syntax")
- \ && b:current_syntax == "help"))
+ if local && (winnr() == thiswin
+ \ || getbufvar(winbufnr(0), '&buftype') ==# "help")
echo "Don't know in which window"
let local = -1
endif
@@ -138,16 +134,13 @@
" If the current window is a help window, try finding a non-help window.
" Relies on syntax highlighting to be switched on.
let s:thiswin = winnr()
-while exists("b:current_syntax") && b:current_syntax == "help"
+while s:thiswin != winnr() && getbufvar(winbufnr(0), '&buftype') ==# 'help'
exe "norm! \<C-W>w"
- if s:thiswin == winnr()
- break
- endif
endwhile
" Open the window
new option-window
-setlocal ts=15 tw=0 noro
+setlocal ts=15 tw=0 noro buftype=nofile
" Insert help and a "set" command for each option.
call append(0, '" Each "set" line shows the current value of an option (on the
left).')
@@ -162,31 +155,30 @@
" Init a local binary option
fun! <SID>BinOptionL(name)
- exe "norm! \<C-W>p"
- exe "let val = &" . a:name
- exe "norm! \<C-W>p"
- call append("$", substitute(substitute(" \tset " . val . a:name . "\t" .
- \!val . a:name, "0", "no", ""), "1", "", ""))
+ wincmd p
+ let val = eval("&".a:name)
+ wincmd p
+ call append('$', " \tset " . (val?"":"no") . a:name . "\t" .
+ \ (val?"no":"") . a:name)
endfun
" Init a global binary option
fun! <SID>BinOptionG(name, val)
- call append("$", substitute(substitute(" \tset " . a:val . a:name . "\t" .
- \!a:val . a:name, "0", "no", ""), "1", "", ""))
+ call append('$', " \tset " . (a:val?"":"no") . a:name . "\t" .
+ \ (a:val?"no":"") . a:name)
endfun
" Init a local string option
fun! <SID>OptionL(name)
- exe "norm! \<C-W>p"
- exe "let val = substitute(&" . a:name . ', "[ \\t\\\\\"|]", "\\\\\\0", "g")'
- exe "norm! \<C-W>p"
+ wincmd p
+ let val = escape(eval("&".a:name), " \t\\\"|")
+ wincmd p
call append("$", " \tset " . a:name . "=" . val)
endfun
" Init a global string option
fun! <SID>OptionG(name, val)
- call append("$", " \tset " . a:name . "=" . substitute(a:val, '[ \t\\"|]',
- \ '\\\0', "g"))
+ call append("$", " \tset " . a:name . "=" . escape(a:val, " \t\\\"|"))
endfun
let s:idx = 1
Original message:
> First of all: Why is setlocal aw allowed because its a global option
> only.
>
> I'd like to tidy up optwin.vim and change its output maybe adding core
> funtions which can be used to query wether a buf local var has been set
> at all.
>
> I'd like the output to look like this:
>
> === START ==
> (g); global option
> (b): options belonging to a buffer
> (w): options belonging to a window
>
> You don't assign values to binary options. You set or unset them like
> this: set option
> set nooption
>
>
> # shiftwidth (b) number of spaces used for each step of (auto)indent
> (local to buffer) setlocal sw=2
>
> # autowrite (g) automatically write a file when leaving a modified
buffer
> set aw
>
> # ⇧shelltemp (g,b) use a temp file for shell commands instead of using
> a pipe setlocal stmp=value1
> set stmp="value2" (*)
> == END ==
>
>
>
> So what's different?
>
> - it shows clearly whether an option is a buffer local, a window local
> or a global option. The current behaviour is inconsistent. Some
> options have a second line saying (local to buffer), but not all
> (example "sts")
>
> - it shows both: global and buffer local vars if they are set.
> (How to query this?)
>
>
> Do you know about any reason why not to change the format?
>
>
> It looks like several lines in the file could be improved:
>
> " If there already is an option window, jump to that one.
> if bufwinnr("option-window") > 0
> let s:thiswin = winnr()
> while 1
> if @% == "option-window"
> finish
> endif
> exe "norm! \<C-W>w"
> if s:thiswin == winnr()
> break
> endif
> endwhile
> endif
>
> What the heck does it do? Let's rewrite it:
>
> " If there already is an option window, jump to that one.
> if bufwinnr("option-window") > 0
> " if buffer is shown finish even if the buffer whose options should
> " be shouwn has different local vars. focus it
> exec bufwinnr("option-window").' wincmd w'
> finish
> endif
>
> Now that you know what this code does you'll notice some issues:
>
> - if you hide buffer (quit with set hidden) and run options again
> you'll have the options twice
>
> - if you don't hide and jump to a different buffer which has buffer
> local values set differently those local buffers won't update !
>
> This makes me think the :options command is close to useless and should
> be fixed.
>
> While the optwin.vim code pays much attention about whether an option is
> a local or a global one the output does not reflect this.
>
> global autowrite output vs local shiftwidth output:
>
> autowrite automatically write a file when leaving a modified buffer
> set aw noaw
> shiftwidth number of spaces used for each step of (auto)indent
> (local to buffer)
> set sw=10
>
>
> Let's have look at the code BinOptionL:
>
>
> " These functions are called often below. Keep them fast!
>
> " Init a local binary option
> fun! <SID>BinOptionL(name)
> exe "norm! \<C-W>p"
> exe "let val = &" . a:name
> exe "norm! \<C-W>p"
> call append("$", substitute(substitute(" \tset " . val . a:name . "\t"
> . \!val . a:name, "0", "no", ""), "1", "", ""))
> endfun
>
> Why is it important to keep it fast - is :options used that often?
> why is exe used if there is wincmd p (or even getbufvar ?)
> ... some more questions appear but its not worth writing them down.
>
>
> Yours
> Marc Weber
signature.asc
Description: This is a digitally signed message part.
