How to temporarily change Cursor color and change back

101 views
Skip to first unread message

pansz

unread,
Mar 4, 2010, 1:34:15 AM3/4/10
to vim...@googlegroups.com

In gui we can define color with :highlight command.

Script can use highlight command to change color, however, if a script
meant to change one color temporarily, it has no knowledge about the
previous setting.

1. the :hi Cursor is defined by my color scheme.
2. now in some case a script change the cursor color to indicate a
special mode.
3. when the mode ends, the script want to change the Cursor back but it
has no knowledge about what is the highlight of Cursor defined by user's
color scheme.


This rises from our script vimim, this implements an IME inside vim and
we may need to change the Cursor color to indicate IM mode and change
the Cursor color back. CursorIM is the best color group for this but we
have no command to let vim show Curor with CursorIM, the only way is to
redefine the :highlight of Cursor and the old settings are lot.

Any work around? Thanks for all.

Christian Brabandt

unread,
Mar 4, 2010, 2:10:29 AM3/4/10
to vim...@googlegroups.com
Hi pansz!

On Do, 04 Mär 2010, pansz wrote:

> Script can use highlight command to change color, however, if a script
> meant to change one color temporarily, it has no knowledge about the
> previous setting.
>
> 1. the :hi Cursor is defined by my color scheme.
> 2. now in some case a script change the cursor color to indicate a
> special mode.
> 3. when the mode ends, the script want to change the Cursor back but it
> has no knowledge about what is the highlight of Cursor defined by user's
> color scheme.

[…]


>
> Any work around? Thanks for all.
>

Try the attached script. I was written quick and dirty fr a similar
issue on this list. It already queries the font attribute, though this
only works with a patched vim, currently.

To return the Cursor highlight, you can then issue:
:let a=Hi("Cursor")
and have all attributes of Cursor in the variable a. To restore the
attributes simply exe the variable a.

The other functions are there to return all available hi groups
(HiLIst()) and SortLines is a debuging function for me to be able to
compare the output from HiList() with a manual list I created using
redir|hi|redir end
You probably won't need it, but I leave it there anyway.

regards,
Christian
--
:wq

hi3.vim

pansz

unread,
Mar 4, 2010, 7:28:24 PM3/4/10
to vim...@googlegroups.com
Christian Brabandt 写道:

> Hi pansz!
>
> On Do, 04 Mär 2010, pansz wrote:
>
>> Script can use highlight command to change color, however, if a script
>> meant to change one color temporarily, it has no knowledge about the
>> previous setting.
>>
>> 1. the :hi Cursor is defined by my color scheme.
>> 2. now in some case a script change the cursor color to indicate a
>> special mode.
>> 3. when the mode ends, the script want to change the Cursor back but it
>> has no knowledge about what is the highlight of Cursor defined by user's
>> color scheme.
> […]
>> Any work around? Thanks for all.
>>
>
> Try the attached script. I was written quick and dirty fr a similar
> issue on this list. It already queries the font attribute, though this
> only works with a patched vim, currently.
>
Thanks, it seems that the redir do the trick.

Paul

unread,
Jan 23, 2015, 2:35:41 PM1/23/15
to vim...@googlegroups.com
Christian Brabandt:
>On Do, 04 Mär 2010, pansz wrote:
>> Script can use highlight command to change color, however, if a
>> script meant to change one color temporarily, it has no knowledge
>> about the previous setting.
>>
>> 1. the :hi Cursor is defined by my color scheme. 2. now in some
>> case a script change the cursor color to indicate a special mode.
>> 3. when the mode ends, the script want to change the Cursor back
>> but it has no knowledge about what is the highlight of Cursor
>> defined by user's color scheme.
> […]
>> Any work around? Thanks for all.
>>
>
> Try the attached script. I was written quick and dirty fr a similar
> issue on this list. It already queries the font attribute, though
> this only works with a patched vim, currently.

Christian Brabandt kindly donated a function "Hi" to save the
highlighting for a group (included at the very bottom).

:hi CursorLine
CursorLine xxx term=underline cterm=underline guifg=white guibg=#002000

I have groups for which not all keys are defined. They are saved with
a value of -1, which seems to be interpretted as an error:

:echo Hi("CursorLine")
hi CursorLine term=underline ctermbg=-1 ctermfg=-1 guibg=#002000 cterm=underline guifg=white

:exe Hi("CursorLine")
E421: Color name or number not recognized: ctermbg=-1 ctermfg=-1 guibg=#002000 cterm=underline guifg=white

I've delved into vim code in years past, and I have an idea of how
long it will take. Unfortunately, I won't be doing that any time
soon. Is there a quick way to get around the problem? My vim version
info is:

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Feb 19 2014 10:14:40)
Included patches: 1-182
Compiled by <cygwin-xfree_AT_cygwin.com>
Huge version with GTK2 GUI. Features included (+) or not (-):
+acl +dialog_con_gui +insert_expand +mouse_sgr +ruby/dyn +vertsplit
+arabic +diff +jumplist -mouse_sysmouse +scrollbind +virtualedit
+autocmd +digraphs +keymap +mouse_urxvt +signs +visual
+balloon_eval +dnd +langmap +mouse_xterm +smartindent +visualextra
+browse -ebcdic +libcall +multi_byte -sniff +viminfo
++builtin_terms +emacs_tags +linebreak +multi_lang +startuptime +vreplace
+byte_offset +eval +lispindent -mzscheme +statusline +wildignore
+cindent +ex_extra +listcmds +netbeans_intg -sun_workshop +wildmenu
+clientserver +extra_search +localmap +path_extra +syntax +windows
+clipboard +farsi +lua/dyn +perl/dyn +tag_binary +writebackup
+cmdline_compl +file_in_path +menu +persistent_undo +tag_old_static +X11
+cmdline_hist +find_in_path +mksession +postscript -tag_any_white -xfontset
+cmdline_info +float +modify_fname +printer -tcl +xim
+comments +folding +mouse +profile +terminfo +xsmp_interact
+conceal -footer +mouseshape +python/dyn +termresponse +xterm_clipboard
+cryptv +fork() +mouse_dec +python3/dyn +textobjects -xterm_save
+cscope +gettext -mouse_gpm +quickfix +title +xpm
+cursorbind -hangul_input -mouse_jsbterm +reltime +toolbar
+cursorshape +iconv +mouse_netterm +rightleft +user_commands
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
system gvimrc file: "$VIM/gvimrc"
user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
system menu file: "$VIMRUNTIME/menu.vim"
fall-back for $VIM: "/etc"
f-b for $VIMRUNTIME: "/usr/share/vim/vim74"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK -D_REENTRANT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng15 -I/usr/include/harfbuzz -I/usr/include/ncursesw -ggdb -O2 -pipe -Wimplicit-function-declaration -fdebug-prefix-map=/usr/src/ports/vim/vim-7.4.182-1.x86_64/build=/usr/src/debug/vim-7.4.182-1 -fdebug-prefix-map=/usr/src/ports/vim/vim-7.4.182-1.x86_64/src/vim74=/usr/src/debug/vim-7.4.182-1 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: gcc -L. -L/usr/local/lib -Wl,--as-needed -o vim.exe -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lpangocairo-1.0 -lXinerama -lXi -lXrandr -lXcursor -lXcomposite -lXdamage -lgdk_pixbuf-2.0 -lpangoft2-1.0 -lgio-2.0 -lXfixes -lcairo -lpixman-1 -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpng15 -lharfbuzz -lpango-1.0 -lm -lfontconfig -lexpat -lfreetype -lz -lbz2 -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -liconv -lpcre -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE -lm -lelf -lncursesw -liconv -lintl -Wl,--enable-auto-import -Wl,--export-all-symbols -Wl,--enable-auto-image-base -fstack-protector -L/usr/lib/perl5/5.14/x86_64-cygwin-threads/CORE -lperl -ldl -lcrypt
--------------------------------------------------
fun! Hi(...)
let s:attr = {}
let s:attr1 = {'bold' : 0, 'italic': 0, 'reverse': 0, 'inverse': 0, 'underline': 0, 'undercurl': 0 , 'standout':0}
let s:query = ['fg', 'bg', 'sp', 'bold', 'italic', 'reverse', 'underline', 'undercurl', 'standout', 'font']

for key in s:query
for mode in ['term', 'cterm', 'gui']
if !empty(synIDattr(synIDtrans(hlID(a:1)), key, mode))
if key =~ 'fg\|bg' || (key=='sp' && mode=='gui')
let s:attr[mode . key]=synIDattr(synIDtrans(hlID(a:1)), key, mode)
elseif key=='font' && mode=='gui'
let s:attr[key]=synIDattr(synIDtrans(hlID(a:1)), key, mode)
else
let s:attr1[mode . key] = synIDattr(synIDtrans(hlID(a:1)), key, mode)
endif
endif
endfor
endfor

if has("gui_running")
let cmode='gui'
else
let cmode='cterm'
endif

for mode in ['term', 'cterm', 'gui']
if get(s:attr1, mode . 'italic') ||
\ get(s:attr1, mode . 'bold') ||
\ get(s:attr1, mode . 'reverse') ||
\ get(s:attr1, mode . 'underline') ||
\ get(s:attr1, mode . 'standout') ||
\ get(s:attr1, mode . 'undercurl')

let s:attr[mode] = get(s:attr1, mode . 'italic', '') ? 'italic,' : ''
let s:attr[mode] .= get(s:attr1, mode . 'bold', '') ? 'bold,' : ''
let s:attr[mode] .= get(s:attr1, mode . 'reverse', '') ? 'reverse,' : ''
let s:attr[mode] .= get(s:attr1, mode . 'underline', '') ? 'underline,' : ''
let s:attr[mode] .= get(s:attr1, mode . 'standout', '') ? 'standout,' : ''
let s:attr[mode] .= get(s:attr1, mode . 'undercurl', '') ? 'undercurl' : ''
endif
endfor

let out='hi ' . a:1
for item in items(s:attr)
"if item[1] >=0
let out .= printf(" %s=%s", item[0], item[1])
"endif
endfor
let out=substitute(out, ',\(\s\|$\)', ' ' , 'g')
if len(split(out, '\s\+')) == 2
let out=substitute(out, '^hi', '& clear', '')
endif
" echo out

return out
endfun

Christian Brabandt

unread,
Jan 23, 2015, 3:00:49 PM1/23/15
to vim...@googlegroups.com
Hi Paul!
> let out='hi ' . a:1
> for item in items(s:attr)
> "if item[1] >=0
> let out .= printf(" %s=%s", item[0], item[1])
> "endif
> endfor

Try uncommenting the above if statement.


Best,
Christian
--
Ich glaube, alle Empfängnisse sind unbefleckt.
-- George Bernard Shaw

Paul

unread,
Jan 26, 2015, 11:00:06 AM1/26/15
to vim...@googlegroups.com
On Friday, January 23, 2015 at 3:00:49 PM UTC-5, Christian Brabandt
wrote:
Christian replied:
>>
>> let out='hi ' . a:1
>> for item in items(s:attr)
>> "if item[1] >=0
>> let out .= printf(" %s=%s", item[0], item[1])
>> "endif
>> endfor
>
> Try uncommenting the above if statement.

It works awesomely, Christian. Thanks! Code below, for posterity
(future usenet archivers in years to come). Unfortunately, I cannot
upload, so the wrap-around below will turn the code into a dog's
breakfast.
_____________________________________
fun! <sid>HiList()
redir => a | sil hi | redir end

let a=substitute(a, '\n\s\+', ' ', 'g')
let b=split(a,'\n')
call map(b, 'split(v:val, ''\s\+'')[0]')
if exists("g:items")
unlet g:items
endif
let g:items=[]
for val in b
call add(g:items, <sid>Hi(val))
endfor
endfun
let out='hi ' . a:1
for item in items(s:attr)
if item[1] >=0
let out .= printf(" %s=%s", item[0], item[1])
endif
endfor
let out=substitute(out, ',\(\s\|$\)', ' ' , 'g')
if len(split(out, '\s\+')) == 2
let out=substitute(out, '^hi', '& clear', '')
endif
" echo out

return out
endfun

fun! <sid>SortLines()
" %s/^hi //ge
" %s/\s\+xxx//ge
"sort
let lines=getline(1,'$')
let i=1
for line in lines
let word=split(line, '\s\+')
let sort=[ word[0] ] + sort(word[1:])
call setline(i, join(sort))
let i+=1
endfor
endfun

"com! -nargs=1 -complete=highlight HI :call <sid>Hi(<q-args>)
"com! HIList :call <sid>HiList()
"com! CleanUp :call <sid>SortLines()

Paul

unread,
Jan 26, 2015, 11:05:22 AM1/26/15
to vim...@googlegroups.com
On Mon, Jan 26, 2015 11:03:25 AM, Paul wrote:
>On Fr, 23 Jan 2015, Paul wrote:
>> Christian Brabandt kindly donated a function "Hi" to save the
>> highlighting for a group (included at the very bottom).
>>
>> <...snip...>
>>
>> I have groups for which not all keys are defined. They are saved
>> with a value of -1, which seems to be interpretted as an error:
>>
>> :echo Hi("CursorLine")
>> hi CursorLine term=underline ctermbg=-1 ctermfg=-1 guibg=#002000 cterm=underline guifg=white
>>
>> :exe Hi("CursorLine")
>> E421: Color name or number not recognized: ctermbg=-1 ctermfg=-1 guibg=#002000 cterm=underline guifg=white
>>
>> I've delved into vim code in years past, and I have an idea of how
>> long it will take. Unfortunately, I won't be doing that any time
>> soon. Is there a quick way to get around the problem? <...snip...>
>
>Christian replied:
>>>
>>> let out='hi ' . a:1
>>> for item in items(s:attr)
>>> "if item[1] >=0
>>> let out .= printf(" %s=%s", item[0], item[1])
>>> "endif
>>> endfor
>>
>> Try uncommenting the above if statement.
>
> It works awesomely, Christian. Thanks! Code below, for posterity
> (future usenet archivers in years to come). Unfortunately, I cannot
> upload, so the wrap-around below will turn the code into a dog's
> breakfast.

By the way, is vimfiles/plugin a good place to put this?

Christian Brabandt

unread,
Jan 26, 2015, 1:29:57 PM1/26/15
to vim...@googlegroups.com
Hi Paul!

On Mo, 26 Jan 2015, Paul wrote:

> By the way, is vimfiles/plugin a good place to put this?

Yes.


Best,
Christian
--
Hallo Bausparer!
Reply all
Reply to author
Forward
0 new messages