* Word-forward/word-backward as in bash / emacs @ 2012-06-03 20:28 Konstantine Rybnikov 2012-06-03 21:36 ` Peter Stephenson 0 siblings, 1 reply; 4+ messages in thread From: Konstantine Rybnikov @ 2012-06-03 20:28 UTC (permalink / raw) To: zsh-users Hi! I've tried to use zsh several times, but there was always one thing that bugged me every time -- it's word-forward/word-backward inconsistency with bash, emacs or other several programs. Here, I asked my question at stackoverflow.com http://stackoverflow.com/questions/10847255/how-to-make-zsh-forward-word-behaviour-same-as-in-bash-emacs Only answer I got is to do "select-word-style bash", which is absolutely not the same as bash (I also provided an example there that explains "why"). Hope to get an answer here. Thanks! ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Word-forward/word-backward as in bash / emacs 2012-06-03 20:28 Word-forward/word-backward as in bash / emacs Konstantine Rybnikov @ 2012-06-03 21:36 ` Peter Stephenson 2012-06-03 22:43 ` Konstantine Rybnikov 0 siblings, 1 reply; 4+ messages in thread From: Peter Stephenson @ 2012-06-03 21:36 UTC (permalink / raw) To: zsh-users On Sun, 03 Jun 2012 23:28:03 +0300 Konstantine Rybnikov <k-bx@k-bx.com> wrote: > Only answer I got is to do "select-word-style bash", which is absolutely > not the same as bash (I also provided an example there that explains "why"). So, with "select-word-style bash" that forward-word thing is the only difference, right? It seemed to be when I tried your example. I actually noted forward-word was a bit funny when I wrote the function forward-word-match that implements it when you uses select-word-style. See if this does the trick --- it patches the function forward-word-match which will be installed in your $fpath. I've made the old behaviour a separate (non-default) option for the sake of this, but if this is what's needed we probably need to think a bit more about when it should apply. The original behaviour works better with zsh's normal set up because then more characters are considered part of a word, so skipping non-word-characters at the start is less likely to have side effects. One possibility would be to reverse the sense of the option (to skip-whitespace-first), but to set it to "true" from select word-style if it's not explicitly set and the new style is "bash". That keeps compatibility in both cases. However, there are other ways of doing it. (I also standardised the indentation while I was there, so there's more changed than is really necessary.) Index: Functions/Zle/forward-word-match =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Zle/forward-word-match,v retrieving revision 1.3 diff -p -u -r1.3 forward-word-match --- Functions/Zle/forward-word-match 28 Jul 2010 13:33:59 -0000 1.3 +++ Functions/Zle/forward-word-match 3 Jun 2012 21:22:36 -0000 @@ -8,32 +8,35 @@ local -a matched_words integer count=${NUMERIC:-1} if (( count < 0 )); then - (( NUMERIC = -count )) - zle ${WIDGET/forward/backward} - return + (( NUMERIC = -count )) + zle ${WIDGET/forward/backward} + return fi while (( count-- )); do - - match-words-by-style - + match-words-by-style + + if zstyle -t $curcontext skip-whitespace-last; then # For some reason forward-word doesn't work like the other word # commands; it skips whitespace only after any matched word # characters. - if [[ -n $matched_words[4] ]]; then - # just skip the whitespace - word=$matched_words[4] - else - # skip the word and trailing whitespace - word=$matched_words[5]$matched_words[6] - fi - - if [[ -n $word ]]; then - (( CURSOR += ${#word} )) + # just skip the whitespace + word=$matched_words[4] else - return 1 + # skip the word and trailing whitespace + word=$matched_words[5]$matched_words[6] fi + else + # more standard behaviour: skip leading whitespace and the word. + word=$matched_words[4]$matched_words[5] + fi + + if [[ -n $word ]]; then + (( CURSOR += ${#word} )) + else + return 1 + fi done return 0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Word-forward/word-backward as in bash / emacs 2012-06-03 21:36 ` Peter Stephenson @ 2012-06-03 22:43 ` Konstantine Rybnikov 2012-06-03 23:45 ` Peter Stephenson 0 siblings, 1 reply; 4+ messages in thread From: Konstantine Rybnikov @ 2012-06-03 22:43 UTC (permalink / raw) To: Peter Stephenson; +Cc: zsh-users 06/04/2012 12:36 AM, Peter Stephenson написал: > On Sun, 03 Jun 2012 23:28:03 +0300 > Konstantine Rybnikov<k-bx@k-bx.com> wrote: >> Only answer I got is to do "select-word-style bash", which is absolutely >> not the same as bash (I also provided an example there that explains "why"). > So, with "select-word-style bash" that forward-word thing is the only > difference, right? It seemed to be when I tried your example. > > I actually noted forward-word was a bit funny when I wrote the function > forward-word-match that implements it when you uses select-word-style. > See if this does the trick --- it patches the function forward-word-match > which will be installed in your $fpath. > > I've made the old behaviour a separate (non-default) option for the sake > of this, but if this is what's needed we probably need to think a bit > more about when it should apply. The original behaviour works better > with zsh's normal set up because then more characters are considered > part of a word, so skipping non-word-characters at the start is less > likely to have side effects. > > One possibility would be to reverse the sense of the option (to > skip-whitespace-first), but to set it to "true" from select word-style > if it's not explicitly set and the new style is "bash". That keeps > compatibility in both cases. However, there are other ways of doing it. > > (I also standardised the indentation while I was there, so there's more > changed than is really necessary.) > > Index: Functions/Zle/forward-word-match > =================================================================== > RCS file: /cvsroot/zsh/zsh/Functions/Zle/forward-word-match,v > retrieving revision 1.3 > diff -p -u -r1.3 forward-word-match > --- Functions/Zle/forward-word-match 28 Jul 2010 13:33:59 -0000 1.3 > +++ Functions/Zle/forward-word-match 3 Jun 2012 21:22:36 -0000 > @@ -8,32 +8,35 @@ local -a matched_words > integer count=${NUMERIC:-1} > > if (( count< 0 )); then > - (( NUMERIC = -count )) > - zle ${WIDGET/forward/backward} > - return > + (( NUMERIC = -count )) > + zle ${WIDGET/forward/backward} > + return > fi > > while (( count-- )); do > - > - match-words-by-style > - > + match-words-by-style > + > + if zstyle -t $curcontext skip-whitespace-last; then > # For some reason forward-word doesn't work like the other word > # commands; it skips whitespace only after any matched word > # characters. > - > if [[ -n $matched_words[4] ]]; then > - # just skip the whitespace > - word=$matched_words[4] > - else > - # skip the word and trailing whitespace > - word=$matched_words[5]$matched_words[6] > - fi > - > - if [[ -n $word ]]; then > - (( CURSOR += ${#word} )) > + # just skip the whitespace > + word=$matched_words[4] > else > - return 1 > + # skip the word and trailing whitespace > + word=$matched_words[5]$matched_words[6] > fi > + else > + # more standard behaviour: skip leading whitespace and the word. > + word=$matched_words[4]$matched_words[5] > + fi > + > + if [[ -n $word ]]; then > + (( CURSOR += ${#word} )) > + else > + return 1 > + fi > done > > return 0 Ok, it looks like Moritz Bunkus updated he's answer with working implementation of forward-word-match. You're right, the only difference if forward-word things. Just tried your patch -- yes, looks like it works as expected. Thanks! ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Word-forward/word-backward as in bash / emacs 2012-06-03 22:43 ` Konstantine Rybnikov @ 2012-06-03 23:45 ` Peter Stephenson 0 siblings, 0 replies; 4+ messages in thread From: Peter Stephenson @ 2012-06-03 23:45 UTC (permalink / raw) To: zsh-users On Mon, 04 Jun 2012 01:43:47 +0300 Konstantine Rybnikov <k-bx@k-bx.com> wrote: > Just tried your patch -- yes, looks like it works as expected. Thanks! Good, here's a more complete patch. Rather than second-guess what the user wants with the style, which isn't really how select-word-style works (it's designed to be explicit about setting things up), this just sets the style differently for bash compatibility, and the documentation notes you can override this by setting it in a more specific context (for a style, a longer pattern is considered more specific). Index: Doc/Zsh/contrib.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v retrieving revision 1.142 diff -p -u -r1.142 contrib.yo --- Doc/Zsh/contrib.yo 8 May 2012 16:50:26 -0000 1.142 +++ Doc/Zsh/contrib.yo 3 Jun 2012 23:39:22 -0000 @@ -1734,6 +1734,16 @@ context is examined and if it contains t the cursor is considered, else the word after cursor is considered. Some examples are given below. +The style tt(skip-whitespace-first) is only used with the +tt(forward-word) widget. If it is set to true, then tt(forward-word) +skips any non-word-characters, followed by any non-word-characters: +this is similar to the behaviour of other word-orientated widgets, +and also that used by other editors, however it differs from the +standard zsh behaviour. When using tt(select-word-style) the widget +is set in the context tt(:zle:*) to tt(true) if the word style is +tt(bash) and tt(false) otherwise. It may be overridden by setting it in +the more specific context tt(:zle:forward-word*). + Here are some examples of use of the styles, actually taken from the simplified interface in tt(select-word-style): Index: Functions/Zle/forward-word-match =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Zle/forward-word-match,v retrieving revision 1.3 diff -p -u -r1.3 forward-word-match --- Functions/Zle/forward-word-match 28 Jul 2010 13:33:59 -0000 1.3 +++ Functions/Zle/forward-word-match 3 Jun 2012 23:39:22 -0000 @@ -8,32 +8,36 @@ local -a matched_words integer count=${NUMERIC:-1} if (( count < 0 )); then - (( NUMERIC = -count )) - zle ${WIDGET/forward/backward} - return + (( NUMERIC = -count )) + zle ${WIDGET/forward/backward} + return fi while (( count-- )); do - - match-words-by-style - + match-words-by-style + + if zstyle -t $curcontext skip-whitespace-first; then + # Standard non-zsh behaviour: skip leading whitespace and the word. + word=$matched_words[4]$matched_words[5] + else + # Traditional zsh behaviour. # For some reason forward-word doesn't work like the other word # commands; it skips whitespace only after any matched word # characters. - if [[ -n $matched_words[4] ]]; then - # just skip the whitespace - word=$matched_words[4] + # just skip the whitespace + word=$matched_words[4] else - # skip the word and trailing whitespace - word=$matched_words[5]$matched_words[6] + # skip the word and trailing whitespace + word=$matched_words[5]$matched_words[6] fi + fi - if [[ -n $word ]]; then - (( CURSOR += ${#word} )) - else - return 1 - fi + if [[ -n $word ]]; then + (( CURSOR += ${#word} )) + else + return 1 + fi done return 0 Index: Functions/Zle/select-word-style =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Zle/select-word-style,v retrieving revision 1.4 diff -p -u -r1.4 select-word-style --- Functions/Zle/select-word-style 28 Jul 2010 13:33:59 -0000 1.4 +++ Functions/Zle/select-word-style 3 Jun 2012 23:39:22 -0000 @@ -4,71 +4,75 @@ setopt extendedglob local -a word_functions word_functions=(backward-kill-word backward-word - capitalize-word down-case-word - forward-word kill-word - transpose-words up-case-word) + capitalize-word down-case-word + forward-word kill-word + transpose-words up-case-word) [[ -z $1 ]] && autoload -Uz read-from-minibuffer -local REPLY detail f wordstyle +local REPLY detail f wordstyle teststyle if ! zle -l $word_functions[1]; then - for f in $word_functions; do - autoload -Uz $f-match - zle -N $f $f-match - done + for f in $word_functions; do + autoload -Uz $f-match + zle -N $f $f-match + done fi while true; do - - if [[ -n $WIDGET && -z $1 ]]; then - read-from-minibuffer -k1 "Word styles (hit return for more detail): + if [[ -n $WIDGET && -z $1 ]]; then + read-from-minibuffer -k1 "Word styles (hit return for more detail): (b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit (B), (N), (S), (W) as above with subword matching ${detail}? " || return 1 - else - REPLY=$1 - fi - - detail= + else + REPLY=$1 + fi + + detail= + + case $REPLY in + ([bB]*) + # bash style + wordstyle=standard + zstyle ':zle:*' word-chars '' + zstyle ':zle:*' skip-whitespace-first true + ;; + + ([nN]*) + # normal zsh style + wordstyle=standard + zstyle ':zle:*' word-chars "$WORDCHARS" + zstyle ':zle:*' skip-whitespace-first false + ;; + + ([sS]*) + # shell command arguments or special tokens + wordstyle=shell + zstyle ':zle:*' skip-whitespace-first false + ;; + + ([wW]*) + # whitespace-delimited + wordstyle=space + zstyle ':zle:*' skip-whitespace-first false + ;; + + (d*) + # default: could also return widgets to builtins here + wordstyle= + zstyle -d ':zle:*' word-chars + zstyle -d ':zle:*' skip-whitespace-first + ;; + + (q*) + # quit without setting + return 1 + ;; - case $REPLY in - ([bB]*) - # bash style - wordstyle=standard - zstyle ':zle:*' word-chars '' - ;; - - ([nN]*) - # normal zsh style - wordstyle=standard - zstyle ':zle:*' word-chars "$WORDCHARS" - ;; - - ([sS]*) - # shell command arguments or special tokens - wordstyle=shell - ;; - - ([wW]*) - # whitespace-delimited - wordstyle=space - ;; - - (d*) - # default: could also return widgets to builtins here - wordstyle= - zstyle -d ':zle:*' word-chars - ;; - - (q*) - # quit without setting - return 1 - ;; - - (*) - detail="\ + (*) + detail="\ (b)ash: Word characters are alphanumerics only (n)ormal: Word characters are alphanumerics plus \$WORDCHARS (s)hell: Words are command arguments using shell syntax @@ -76,21 +80,21 @@ ${detail}? " || return 1 (d)efault: Use default, no special handling (usually same as \`n') (q)uit: Quit without setting a new style " - if [[ -z $WIDGET || -n $1 ]]; then - print "Usage: $0 word-style + if [[ -z $WIDGET || -n $1 ]]; then + print "Usage: $0 word-style where word-style is one of the characters in parentheses: $detail" >&2 - return 1 - fi - continue - ;; - esac - - if [[ -n $wordstyle ]]; then - if [[ $REPLY = [[:upper:]]* ]]; then - wordstyle+=-subword - fi - zstyle ':zle:*' word-style $wordstyle + return 1 + fi + continue + ;; + esac + + if [[ -n $wordstyle ]]; then + if [[ $REPLY = [[:upper:]]* ]]; then + wordstyle+=-subword fi - return + zstyle ':zle:*' word-style $wordstyle + fi + return done -- Peter Stephenson <p.w.stephenson@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-06-03 23:51 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-06-03 20:28 Word-forward/word-backward as in bash / emacs Konstantine Rybnikov 2012-06-03 21:36 ` Peter Stephenson 2012-06-03 22:43 ` Konstantine Rybnikov 2012-06-03 23:45 ` Peter Stephenson
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).