* vim-a-like vi mode status bar @ 2002-02-16 17:20 Ian Lynagh 2002-02-16 17:48 ` Thomas Köhler 2002-02-20 22:12 ` Steve Talley 0 siblings, 2 replies; 5+ messages in thread From: Ian Lynagh @ 2002-02-16 17:20 UTC (permalink / raw) To: zsh-users [-- Attachment #1: Type: text/plain, Size: 1272 bytes --] Hi all I have thought it would be nice to have a vim-a-like indicator of whether or not you are insert or command mode when using the vi line editting mode for a long time now. In a burst of enthusiasm I have put something together over the last couple of days (attached). However it's not quite as nice as it might have been and I have run into a few annoyances along the way. Initially I was planning to have the indicator in the prompt. However AFAICT once the prompt has been displayed it is cached, so even if you for zsh to redraw it (I tried various things like "zle redisplay", "zle push-input; zle get-line", "zle -R") it just redraws the old one. Did I miss a way to do this? Is there a reason why it shouldn't be possible to pipe something into source? Or another way to do it without a temporary file? With the script attached, if I paste a command in then only the first character is visible until I press ^R. If I type something else first then it works fine (even if I first delete what I typed!). Perhaps this is a bug? I also couldn't find a way to set the statusbar after accepting a command. zsh -M complains it's not being called from a widget if I call it from precmd. Finally I would welcome any comments/criticisms on the code! Thanks Ian [-- Attachment #2: zsh-vi-mode-status-bar --] [-- Type: text/plain, Size: 2772 bytes --] # Provides you with a vim-a-like vi-mode status bar showing what mode # you are in. # To be called from .zshrc # Author: Ian Lynagh <igloo@earth.li> # Licence: GPL 2 # Copyright: Ian Lynagh <igloo@earth.li> 2002 # Should we show "<insert>" or "" for insert mode? alias statusbar-show-insert="zstyle :vi-mode-statusbar: show-insert yes" alias statusbar-no-show-insert="zstyle :vi-mode-statusbar: show-insert no" alias statusbar-test-show-insert="zstyle -t :vi-mode-statusbar: show-insert" statusbar-no-show-insert # What mode are we now in? alias statusbar-now-insert="zstyle :vi-mode-statusbar: now-insert yes" alias statusbar-now-command="zstyle :vi-mode-statusbar: now-insert no" alias statusbar-test-now-insert="zstyle -t :vi-mode-statusbar: now-insert" # What mode were we in last time? alias statusbar-last-insert="zstyle :vi-mode-statusbar: last-insert yes" alias statusbar-last-command="zstyle :vi-mode-statusbar: last-insert no" alias statusbar-test-last-insert="zstyle -t :vi-mode-statusbar: last-insert" # Helper function function stat-statusbar-update { if statusbar-test-now-insert then if statusbar-test-show-insert then zle -M "<insert>" else if ! statusbar-test-last-insert then zle -M "" fi fi statusbar-last-insert else zle -M "<command>" statusbar-last-command fi } # Before each prompt reset function precmd { statusbar-now-insert statusbar-last-command } # Wrap each widget # This makes a new ~/.zshrc.stat.functions function gen-stat-functions { local EXTRA CHANGE rm ~/.zshrc.stat.functions zle -l -a | grep "^[a-zA-Z]" | while read WIDGET do UPDATE="stat-statusbar-update" CHANGE="" case "$WIDGET" in vi-(add-(eol|next)|insert(|-bol)|change-(eol|whole-line) \ |open-line-(above|below)|replace) \ |accept-(and-(hold|infer-next-history)|line(|-and-down-history)) \ |get-line|pound-insert|push-(input|line(|-or-edit)) \ |send-break|run-help|which-command) CHANGE="statusbar-now-insert" ;; vi-cmd-mode) echo foo CHANGE="statusbar-now-command" ;; vi-change) CHANGE="statusbar-now-insert" UPDATE="" ;; esac echo " function stat-$WIDGET { zle .$WIDGET $CHANGE $UPDATE } zle -N stat-$WIDGET stat-$WIDGET zle -A stat-$WIDGET $WIDGET" >> ~/.zshrc.stat.functions done } # Don't bother updating it automagically - that's just asking for it! # Just . whatever was last created . ~/.zshrc.stat.functions # Use vi mode bindkey -v ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: vim-a-like vi mode status bar 2002-02-16 17:20 vim-a-like vi mode status bar Ian Lynagh @ 2002-02-16 17:48 ` Thomas Köhler 2002-02-16 20:05 ` Ian Lynagh 2002-02-20 22:12 ` Steve Talley 1 sibling, 1 reply; 5+ messages in thread From: Thomas Köhler @ 2002-02-16 17:48 UTC (permalink / raw) To: zsh-users [-- Attachment #1.1: Type: text/plain, Size: 988 bytes --] Hi, Ian Lynagh wrote [020216 18:28]: > Hi all > > I have thought it would be nice to have a vim-a-like indicator of > whether or not you are insert or command mode when using the vi line > editting mode for a long time now. In a burst of enthusiasm I have put > something together over the last couple of days (attached). However it's > not quite as nice as it might have been and I have run into a few > annoyances along the way. Well, I use something similar. Of course, I have a multiline prompt, so what I have here might work for you, but it might need some adjustment - the escape sequences for moving the cursor might not work for your type of terminal... Ciao, Thomas -- Thomas Köhler Email: jean-luc@picard.franken.de | LCARS - Linux <>< WWW: http://jeanluc-picard.de | for Computers IRC: jeanluc | on All Real PGP public key available from Homepage! | Starships [-- Attachment #1.2: zshrc.showmode --] [-- Type: text/plain, Size: 4947 bytes --] # vi keybindings bindkey -v bindkey -M vicmd "^R" redo bindkey -M vicmd "u" undo bindkey -M vicmd "ga" what-cursor-position unsetopt promptcr redisplay() { builtin zle .redisplay ( true ; show_mode "INSERT") &! } redisplay2() { builtin zle .redisplay (true ; show_mode "NORMAL") &! } zle -N redisplay zle -N redisplay2 bindkey -M viins "^X^R" redisplay bindkey -M vicmd "^X^R" redisplay2 screenclear () { echo -n "\033[2J\033[400H" builtin zle .redisplay (true ; show_mode "INSERT") &! } zle -N screenclear bindkey "\f" screenclear screenclearx () { repeat 2 print local MYLINE="$LBUFFER$RBUFFER" highlight $MYLINE repeat 4 print builtin zle redisplay } zle -N screenclearx bindkey "^Xl" screenclearx show_mode() { local COL local x COL=$[COLUMNS-3] COL=$[COL-$#1] x=$(echo $PREBUFFER | wc -l ) x=$[x+1] echo -n "^[7^[[$x;A^[[0;G" echo -n "" echo -n "^[[0;37;44m--$1--^[[0m" echo -n "^[8" } zmodload zsh/parameter ### vi-add-eol (unbound) (A) (unbound) ### Move to the end of the line and enter insert mode. vi-add-eol() { show_mode "INSERT" builtin zle .vi-add-eol } zle -N vi-add-eol bindkey -M vicmd "A" vi-add-eol ### vi-add-next (unbound) (a) (unbound) ### Enter insert mode after the current cursor posi ### tion, without changing lines. vi-add-next() { show_mode "INSERT" builtin zle .vi-add-next # OLDLBUFFER=$LBUFFER # OLDRBUFFER=$RBUFFER # NNUMERIC=$NUMERIC # bindkey -M viins "^[" vi-cmd-mode-a } zle -N vi-add-next bindkey -M vicmd "a" vi-add-next ### vi-change (unbound) (c) (unbound) ### Read a movement command from the keyboard, and kill ### from the cursor position to the endpoint of the ### movement. Then enter insert mode. If the command ### is vi-change, change the current line. vi-change() { show_mode "INSERT" builtin zle .vi-change } zle -N vi-change bindkey -M vicmd "c" vi-change ### vi-change-eol (unbound) (C) (unbound) ### Kill to the end of the line and enter insert mode. vi-change-eol() { show_mode "INSERT" builtin zle .vi-change-eol } zle -N vi-change-eol bindkey -M vicmd "C" vi-change-eol ### vi-change-whole-line (unbound) (S) (unbound) ### Kill the current line and enter insert mode. vi-change-whole-line() { show_mode "INSERT" builtin zle .vi-change-whole-line } zle -N vi-change-whole-line bindkey -M vicmd "S" vi-change-whole-line ### vi-insert (unbound) (i) (unbound) ### Enter insert mode. vi-insert() { show_mode "INSERT" builtin zle .vi-insert } zle -N vi-insert bindkey -M vicmd "i" vi-insert ### vi-insert-bol (unbound) (I) (unbound) ### Move to the first non-blank character on the line ### and enter insert mode. vi-insert-bol() { show_mode "INSERT" builtin zle .vi-insert-bol } zle -N vi-insert-bol bindkey -M vicmd "I" vi-insert-bol ### vi-open-line-above (unbound) (O) (unbound) ### Open a line above the cursor and enter insert mode. vi-open-line-above() { show_mode "INSERT" builtin zle .vi-open-line-above } zle -N vi-open-line-above bindkey -M vicmd "O" vi-open-line-above ### vi-open-line-below (unbound) (o) (unbound) ### Open a line below the cursor and enter insert mode. vi-open-line-below() { show_mode "INSERT" builtin zle .vi-open-line-below } zle -N vi-open-line-below bindkey -M vicmd "o" vi-open-line-below ### vi-substitute (unbound) (s) (unbound) ### Substitute the next character(s). vi-substitute() { show_mode "INSERT" builtin zle .vi-substitute } zle -N vi-substitute bindkey -M vicmd "s" vi-substitute ### vi-replace (unbound) (R) (unbound) ### Enter overwrite mode. ### vi-replace() { show_mode "REPLACE" builtin zle .vi-replace } zle -N vi-replace bindkey -M vicmd "R" vi-replace ### vi-cmd-mode (^X^V) (unbound) (^[) ### Enter command mode; that is, select the `vicmd' ### keymap. Yes, this is bound by default in emacs ### mode. vi-cmd-mode() { show_mode "NORMAL" builtin zle .vi-cmd-mode } zle -N vi-cmd-mode bindkey -M viins "^[" vi-cmd-mode ### vi-oper-swap-case ### Read a movement command from the keyboard, and swap ### the case of all characters from the cursor position ### to the endpoint of the movement. If the movement ### command is vi-oper-swap-case, swap the case of all ### characters on the current line. ### bindkey -M vicmd "g~" vi-oper-swap-case [-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: vim-a-like vi mode status bar 2002-02-16 17:48 ` Thomas Köhler @ 2002-02-16 20:05 ` Ian Lynagh 2002-02-17 18:57 ` Thomas Köhler 0 siblings, 1 reply; 5+ messages in thread From: Ian Lynagh @ 2002-02-16 20:05 UTC (permalink / raw) To: zsh-users Hi, On Sat, Feb 16, 2002 at 06:48:05PM +0100, Thomas Köhler wrote: > > Ian Lynagh wrote [020216 18:28]: > > I have thought it would be nice to have a vim-a-like indicator of > > whether or not you are insert or command mode when using the vi line > > editting mode for a long time now. In a burst of enthusiasm I have put > > something together over the last couple of days (attached). However it's > > not quite as nice as it might have been and I have run into a few > > annoyances along the way. > > Well, I use something similar. Of course, I have a multiline Thanks, very interesting to see another implementation. > prompt, so what I have here might work for you, but it might need > some adjustment - the escape sequences for moving the cursor > might not work for your type of terminal... That's an approach I thought of but decided against, partly because of the potential terminal issues and partly because of the cases like multi-line input and screen clearing. However, you seem to have these mostly[0] sussed so I might switch to this with a simple command to switch to a simpler prompt if I do happen to be using a less fancy terminal. [0] It still looks like it has problems when the prompt has scrolled off the top of the screen, at least in an rxvt. This should also solve a few of my current problems (flicker, characters not being echoed when pasted and having the default state shown). I do have a couple of further questions for you though... > redisplay() { > builtin zle .redisplay > ( true ; show_mode "INSERT") &! > } I am not sure why you have the &! here - if it is worth doing then that implies you might do something else before it has finished in which case your cursor might not be where you think it is? It also seems to me you might be better off with a variable (or zstyle lookup or whatever) for the current state and a single redisplay. This would have the advantage that you wouldn't have to worry about things being rebound incorrectly later on. > zle -N redisplay Just overwriting the built-in widgets rather than aliasing seems so *obvious* now how did I ever not think of it? Too caught up in the excitement of being able to alias them I think! > show_mode() { > local COL > local x > COL=$[COLUMNS-3] > COL=$[COL-$#1] > x=$(echo $PREBUFFER | wc -l ) > x=$[x+1] > echo -n "^[7^[[$x;A^[[0;G" > echo -n "" > echo -n "^[[0;37;44m--$1--^[[0m" > echo -n "^[8" > } Am I missing something or is COL never actually used? And doesn't echo -n "" do nothing? Thanks Ian ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: vim-a-like vi mode status bar 2002-02-16 20:05 ` Ian Lynagh @ 2002-02-17 18:57 ` Thomas Köhler 0 siblings, 0 replies; 5+ messages in thread From: Thomas Köhler @ 2002-02-17 18:57 UTC (permalink / raw) To: zsh-users [-- Attachment #1: Type: text/plain, Size: 5214 bytes --] Hi, Ian Lynagh wrote [020217 19:03]: > On Sat, Feb 16, 2002 at 06:48:05PM +0100, Thomas Köhler wrote: [...] > > prompt, so what I have here might work for you, but it might need > > some adjustment - the escape sequences for moving the cursor > > might not work for your type of terminal... > > That's an approach I thought of but decided against, partly > because of the potential terminal issues and partly because of > the cases like multi-line input and screen clearing. However, > you seem to have these mostly[0] sussed so I might switch to > this with a simple command to switch to a simpler prompt if I > do happen to be using a less fancy terminal. That idea is not so bad, though I usually have very usuable terminal definitions :-) > [0] It still looks like it has problems when the prompt has > scrolled off the top of the screen, at least in an rxvt. In some cases, it doesn't work correctly, yes. This includes the case when you type a very long line, a wrap happens and you switch modes then - bad luck, --NORMAL-- appears in the wrong place (one line below). But that doesn't happen enough to bother me for now... > This should also solve a few of my current problems (flicker, > characters not being echoed when pasted and having the default > state shown). Yes, there's quite a few issues to resolve when you want to write something to some special position in the terminal... > I do have a couple of further questions for you though... No problem :-) > > redisplay() { > > builtin zle .redisplay > > ( true ; show_mode "INSERT") &! > > } > > I am not sure why you have the &! here - if it is worth doing > then that implies you might do something else before it has > finished in which case your cursor might not be where you think > it is? I've inserted those &! in all places because for some situations, the cursor was not back to its original position yet before the function has been called, so by this little trick, the function returns, the cursor is back, and _then_ the "INSERT" is being drawed. Funny issue indeed. I don't remember offhand which of those &! I really needed, and I just dodn't mind because it works OK for now... > It also seems to me you might be better off with a variable (or > zstyle lookup or whatever) for the current state and a single > redisplay. This would have the advantage that you wouldn't have > to worry about things being rebound incorrectly later on. Maybe, didn't evaluate that much further. Perhaps worth thinking about it... > > zle -N redisplay > > Just overwriting the built-in widgets rather than aliasing seems so > *obvious* now how did I ever not think of it? Too caught up in the > excitement of being able to alias them I think! That idea came to my mind after reading zsh-users some day, and once you find the trick, all seems so obvious and you think "why have I been so silly?". It's always the same :-) > > show_mode() { > > local COL > > local x > > COL=$[COLUMNS-3] > > COL=$[COL-$#1] > > x=$(echo $PREBUFFER | wc -l ) > > x=$[x+1] > > echo -n "^[7^[[$x;A^[[0;G" > > echo -n "" > > echo -n "^[[0;37;44m--$1--^[[0m" > > echo -n "^[8" > > } > > Am I missing something or is COL never actually used? Well... no, you're not missing anything, I just forgot to remove it, it was in there in my first version (and has been used then because I used to have the mode on the right hand side instead of the left hand side). > And doesn't > echo -n "" > do nothing? Actually, it prints an empty string :-) One thing I'm thinking of at the moment: Some more issues (where to put the "showmode") could be resolved better by always using the same position on the screen - for example, always on the last line, at the left hand side. That way, some fidling around with $LINES might be needed (as I used to use $COLUMNS in my original version, but then I decided to put the showmode feature to the left hand side, and, well, put a clock[1] on the right hand side), and one would have to create a long prompt (part of which would be overwritten when you're down at the bottom), but it might be a better idea? Perhaps worth a try... [1] Don't try this at home: Sometimes there's a race condition when zsh tries to complete things and that little cron comes in the way, and so sometimes (not very often, but still sometimes) zsh crashes. It used to be worse back in 3.1.9-dev-xx-days, though :) Here it is anyways, for those who still want it... ### a clock in the prompt. Yes, this _is_ cool. trap CRON ALRM TMOUT=1 CRON() { local STRING local COL local x STRING=$(date) COL=$[COLUMNS-5] COL=$[COL-$#STRING] x=$(echo $PREBUFFER | wc -l ) x=$[x+1] echo -n "^[7^[[$x;A^[[$COL;G^[[0;37;44m-- $STRING --^[[0m^[8" } > Thanks > Ian Ciao, Thomas -- Thomas Köhler Email: jean-luc@picard.franken.de | LCARS - Linux <>< WWW: http://jeanluc-picard.de | for Computers IRC: jeanluc | on All Real PGP public key available from Homepage! | Starships [-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: vim-a-like vi mode status bar 2002-02-16 17:20 vim-a-like vi mode status bar Ian Lynagh 2002-02-16 17:48 ` Thomas Köhler @ 2002-02-20 22:12 ` Steve Talley 1 sibling, 0 replies; 5+ messages in thread From: Steve Talley @ 2002-02-20 22:12 UTC (permalink / raw) To: Ian Lynagh; +Cc: zsh-users [-- Attachment #1: Type: text/plain, Size: 1485 bytes --] I have a mode line that appears below the command line (attached). It has a bug here and there, but is fairly solid and pretty simple. Steve Ian Lynagh wrote: > Hi all > > I have thought it would be nice to have a vim-a-like indicator of > whether or not you are insert or command mode when using the vi line > editting mode for a long time now. In a burst of enthusiasm I have > put something together over the last couple of days (attached). > However it's not quite as nice as it might have been and I have run > into a few annoyances along the way. > > Initially I was planning to have the indicator in the prompt. > However AFAICT once the prompt has been displayed it is cached, so > even if you for zsh to redraw it (I tried various things like "zle > redisplay", "zle push-input; zle get-line", "zle -R") it just > redraws the old one. Did I miss a way to do this? > > Is there a reason why it shouldn't be possible to pipe something > into source? Or another way to do it without a temporary file? > > With the script attached, if I paste a command in then only the > first character is visible until I press ^R. If I type something > else first then it works fine (even if I first delete what I > typed!). Perhaps this is a bug? > > I also couldn't find a way to set the statusbar after accepting a > command. zsh -M complains it's not being called from a widget if I > call it from precmd. > > Finally I would welcome any comments/criticisms on the code! > > Thanks Ian [-- Attachment #2: zshmode --] [-- Type: text/plain, Size: 2387 bytes --] # # Set vi mode status bar # # # Reads until the given character has been entered. # readuntil () { typeset a while [ "$a" != "$1" ] do read -E -k 1 a done } # # If the $SHOWMODE variable is set, displays the vi mode, specified by # the $VIMODE variable, under the current command line. # # Arguments: # # 1 (optional): Beyond normal calculations, the number of additional # lines to move down before printing the mode. Defaults to zero. # showmode() { typeset movedown typeset row # Get number of lines down to print mode movedown=$(($(echo "$RBUFFER" | wc -l) + ${1:-0})) # Get current row position echo -n "\e[6n" row="${${$(readuntil R)#*\[}%;*}" # Are we at the bottom of the terminal? if [ $((row+movedown)) -gt "$LINES" ] then # Scroll terminal up one line echo -n "\e[1S" # Move cursor up one line echo -n "\e[1A" fi # Save cursor position echo -n "\e[s" # Move cursor to start of line $movedown lines down echo -n "\e[$movedown;E" # Change font attributes echo -n "\e[1m" # Has a mode been set? if [ -n "$VIMODE" ] then # Print mode line echo -n "-- $VIMODE -- " else # Clear mode line echo -n "\e[0K" fi # Restore font echo -n "\e[0m" # Restore cursor position echo -n "\e[u" } clearmode() { VIMODE= showmode } # # Temporary function to extend built-in widgets to display mode. # # 1: The name of the widget. # # 2: The mode string. # # 3 (optional): Beyond normal calculations, the number of additional # lines to move down before printing the mode. Defaults to zero. # makemodal () { # Create new function eval "$1() { zle .'$1'; ${2:+VIMODE='$2'}; showmode $3 }" # Create new widget zle -N "$1" } # Extend widgets makemodal vi-add-eol INSERT makemodal vi-add-next INSERT makemodal vi-change INSERT makemodal vi-change-eol INSERT makemodal vi-change-whole-line INSERT makemodal vi-insert INSERT makemodal vi-insert-bol INSERT makemodal vi-open-line-above INSERT makemodal vi-substitute INSERT makemodal vi-open-line-below INSERT 1 makemodal vi-replace REPLACE makemodal vi-cmd-mode NORMAL unfunction makemodal ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-02-20 22:13 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-02-16 17:20 vim-a-like vi mode status bar Ian Lynagh 2002-02-16 17:48 ` Thomas Köhler 2002-02-16 20:05 ` Ian Lynagh 2002-02-17 18:57 ` Thomas Köhler 2002-02-20 22:12 ` Steve Talley
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).