zsh-users
 help / color / mirror / code / Atom feed
* Re: Would like an alias to read the part of the current command line that precedes the alias
@ 2011-10-10 23:21 dg1727
  0 siblings, 0 replies; 6+ messages in thread
From: dg1727 @ 2011-10-10 23:21 UTC (permalink / raw)
  To: zsh-users



On Mon, 10 Oct 2011 19:15:18 -0400 dg1727@hushmail.com wrote:
>Hello, 
>
>I am using zsh 4.3.12 on Xubuntu and am trying to find a 
>substitute 
>for the following which is in the default .bashrc:  
>
># Add an "alert" alias for long running commands.  Use like so:
>#   sleep 10; alert
>#alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo 
>terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-
>9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
>
>This pops up a notification that says, for example, "sleep 10" to 
>let the user know which long-running command has just finished.  
>The part of the alias that seems hard to duplicate in zsh is:  
>
>history|tail -n1
>
>The closest I have come to a working zsh version of "alert" is to 
>define the following function in .zshrc:  
>
>function alert_function() {
>  local icontype="$([ $? = 0 ] && echo terminal || echo error)"
>
>  local last_hist="$argv[*]"
>  # This is dependent on this function being called correctly.  
>  # Calling the function correctly can be done manually as 
>follows: 
> 
>  # sleep 2; alert_function !#:0-
>  # ... but it is not yet known how to do this in such a way that 
>the only 
>  # punctuation mark that the user needs to type is the ";".  
>
>  notify-send --urgency=low -i $icontype $last_hist
>}
>
>The comment block tells the story.  :-) 
>
>The zshexpn manpage says that history expansion (!#:0- in this 
>case) is done before alias expansion (or any other expansion).  
>That seems to make it difficult for any keyword that consists only 
>
>of letters (no punctuation marks), such as 'alert', to refer to 
>what precedes it on the command line.  
>
>Thanks in advance for suggestions.

My apologies that the lines of code are word-wrapped in my e-mails. 
 The 3 lines of BASH code starting with #alias were not supposed to 
be commented (no # at the beginning), and are all one line in 
.bashrc.  


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Would like an alias to read the part of the current command line that precedes the alias
  2011-10-13 19:32     ` Bart Schaefer
@ 2011-11-07  5:12       ` Aaron Davies
  0 siblings, 0 replies; 6+ messages in thread
From: Aaron Davies @ 2011-11-07  5:12 UTC (permalink / raw)
  To: zsh-users

On Thu, Oct 13, 2011 at 3:32 PM, Bart Schaefer
<schaefer@brasslantern.com> wrote:

>    typeset -g _LASTALERT=$HISTCMD
>    preexec() {
>      SECONDS=0
>    }
>    precmd() {
>      local alert="${${?/0/Terminal}//<->*/Problem Reporter}"
>      (( _LASTALERT < HISTCMD && SECONDS > 1 )) &&
>        growlnotify -p "Very Low" -a "$alert" -m "$history[$_LASTALERT]"
>      _LASTALERT=$HISTCMD
>    }

looks great, thanks!
-- 
Aaron Davies
aaron.davies@gmail.com


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Would like an alias to read the part of the current command line that precedes the alias
  2011-10-13  3:15   ` Aaron Davies
@ 2011-10-13 19:32     ` Bart Schaefer
  2011-11-07  5:12       ` Aaron Davies
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2011-10-13 19:32 UTC (permalink / raw)
  To: zsh-users

On Oct 12, 11:15pm, Aaron Davies wrote:
}
} First, and I think this is general, it triggers again off of a blank
} command line (i.e. pressing return a second time) after the specified
} time has elapsed.

You can fix this by keeping track of $HISTCMD and skipping the alert
if it hasn't incremented.

} Second, and this is probably due to my setup, I can't get the failure
} detection working. The third growlnotify call below should have a -a
} argument of "Problem Reporter".
}
} Any idea what I'm doing wrong?

My example was incomplete.  I tested without the (( SECONDS > N )) and
that resets $? before the part after the && happens.

    typeset -g _LASTALERT=$HISTCMD
    preexec() {
      SECONDS=0
    }
    precmd() {
      local alert="${${?/0/Terminal}//<->*/Problem Reporter}"
      (( _LASTALERT < HISTCMD && SECONDS > 1 )) &&
        growlnotify -p "Very Low" -a "$alert" -m "$history[$_LASTALERT]"
      _LASTALERT=$HISTCMD
    }

Note that this is also going to put up a dialog if you interrupt a
command with ctrl-c.  Fixing that would involve saving $? and checking
for what signal it indicates was received, i.e. ^C is 130.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Would like an alias to read the part of the current command line that precedes the alias
  2011-10-11  2:05 ` Bart Schaefer
@ 2011-10-13  3:15   ` Aaron Davies
  2011-10-13 19:32     ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Aaron Davies @ 2011-10-13  3:15 UTC (permalink / raw)
  To: zsh-users

On Oct 10, 2011, at 10:05 PM, Bart Schaefer wrote:

> However, I suspect most zsh users would do this with a precmd function,
> and never type out the "; alert" at all.  For example:

Here's my attempt to build a version for Mac.

I'm having two problems:

First, and I think this is general, it triggers again off of a blank command line (i.e. pressing return a second time) after the specified time has elapsed. This is the second growlnotify call below.

Second, and this is probably due to my setup, I can't get the failure detection working. The third growlnotify call below should have a -a argument of "Problem Reporter".

Any idea what I'm doing wrong?

pro% echo $ZSH_VERSION 
4.3.9
pro% setopt
extendedglob
interactive
login
monitor
shinstdin
zle
pro% typeset -f preexec precmd
preexec () {
	SECONDS=0 
}
precmd () {
	(( SECONDS > 1 )) && growlnotify -p "Very Low" -a "${${?/0/Terminal}//<->*/Problem Reporter}" -m $history[$[HISTCMD-1]]
}
pro% cat succeed 
#!/bin/zsh
sleep 2
pro% cat fail 
#!/bin/zsh
sleep 2
exit 1
pro% set -x
+precmd:1> ((  SECONDS > 1  ))
pro% ./succeed 
+preexec:1> SECONDS=0 
+-zsh:7> ./succeed
+precmd:1> ((  SECONDS > 1  ))
+precmd:3> growlnotify -p 'Very Low' -a Terminal -m ./succeed
pro% 
+precmd:1> ((  SECONDS > 1  ))
+precmd:3> growlnotify -p 'Very Low' -a Terminal -m ./succeed
pro% ./fail 
+preexec:1> SECONDS=0 
+-zsh:9> ./fail
+precmd:1> ((  SECONDS > 1  ))
+precmd:3> growlnotify -p 'Very Low' -a Terminal -m ./fail
pro% 
-- 
Aaron Davies
aaron.davies@gmail.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Would like an alias to read the part of the current command line that precedes the alias
  2011-10-10 23:15 dg1727
@ 2011-10-11  2:05 ` Bart Schaefer
  2011-10-13  3:15   ` Aaron Davies
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2011-10-11  2:05 UTC (permalink / raw)
  To: zsh-users

On Oct 10,  7:15pm, dg1727@hushmail.com wrote:
}
} I am using zsh 4.3.12 on Xubuntu and am trying to find a substitute 
} for the following which is in the default .bashrc:  
} 
} #alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo 
} terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-
} 9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
} 
} This pops up a notification that says, for example, "sleep 10" to 
} let the user know which long-running command has just finished.  
} The part of the alias that seems hard to duplicate in zsh is:  
} 
} history|tail -n1

That's pretty easy, actually.

	history $HISTCMD

will do it.  Zsh by default does not consider the current command to
be interesting, because it's almost always "history" (or "fc") plus
maybe some arguments.  So "history -1" refers to the command that is
immediately *before* the command "history -1" itself.

If you use

	zmodload zsh/parameter

(which you probably already are, if you're using completion) then you
don't need the history command, you can just refer to $history like
this:

	$history[$HISTCMD]

And then to prune everything from the last separator:

	${history[$HISTCMD]%[;&|]*}

You don't have to sed off the history number that way, either.  And
you can convert $? into a string without forking [ $? = 0  ] too:

	${${?/0/terminal}//<->*/error}

That says, first replace 0 with the string "terminal" and then if any
numbers are left, replace with "error".

So:

alias alert='notify-send --urgency=low -i \
	${${?/0/terminal}//<->*/error} ${history[$HISTCMD]%[;&|]*}'

Or in Gnome, perhaps:

alias alert='zenity --${${?/0/info}//<->*/warning} \
	--text=${history[$HISTCMD]%[;&|]*}'

However, I suspect most zsh users would do this with a precmd function,
and never type out the "; alert" at all.  For example:

    preexec() {
      SECONDS=0  # Reset the counter
    }
    precmd() {
      (( SECONDS > 120 )) &&  # Took more than 2 minutes, send alert
        notify-send --urgency=low -i \
          ${${?/0/terminal}//<->*/error} $history[$[HISTCMD-1]]
    }

Note there that you reference $[HISTCMD-1] because by the time you get
to the precmd function the history count has been incremented and you
now are interested in the previous event.  Add double quotes if you
use the shwordsplit option.

} The zshexpn manpage says that history expansion (!#:0- in this 
} case) is done before alias expansion (or any other expansion).  
} That seems to make it difficult for any keyword that consists only 
} of letters (no punctuation marks), such as 'alert', to refer to 
} what precedes it on the command line.  

Those don't really have anything to do with one another.  The purpose
of history expansion is for the command editor (i.e., you as typist)
to refer to other history events; that's distinct from the execution
of some command, long after you're done typing it, referring back to
something in the history.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Would like an alias to read the part of the current command line that precedes the alias
@ 2011-10-10 23:15 dg1727
  2011-10-11  2:05 ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: dg1727 @ 2011-10-10 23:15 UTC (permalink / raw)
  To: zsh-users

Hello, 

I am using zsh 4.3.12 on Xubuntu and am trying to find a substitute 
for the following which is in the default .bashrc:  

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
#alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo 
terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-
9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

This pops up a notification that says, for example, "sleep 10" to 
let the user know which long-running command has just finished.  
The part of the alias that seems hard to duplicate in zsh is:  

history|tail -n1

The closest I have come to a working zsh version of "alert" is to 
define the following function in .zshrc:  

function alert_function() {
  local icontype="$([ $? = 0 ] && echo terminal || echo error)"

  local last_hist="$argv[*]"
  # This is dependent on this function being called correctly.  
  # Calling the function correctly can be done manually as follows: 
 
  # sleep 2; alert_function !#:0-
  # ... but it is not yet known how to do this in such a way that 
the only 
  # punctuation mark that the user needs to type is the ";".  

  notify-send --urgency=low -i $icontype $last_hist
}

The comment block tells the story.  :-) 

The zshexpn manpage says that history expansion (!#:0- in this 
case) is done before alias expansion (or any other expansion).  
That seems to make it difficult for any keyword that consists only 
of letters (no punctuation marks), such as 'alert', to refer to 
what precedes it on the command line.  

Thanks in advance for suggestions.  


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-11-07  5:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-10 23:21 Would like an alias to read the part of the current command line that precedes the alias dg1727
  -- strict thread matches above, loose matches on Subject: below --
2011-10-10 23:15 dg1727
2011-10-11  2:05 ` Bart Schaefer
2011-10-13  3:15   ` Aaron Davies
2011-10-13 19:32     ` Bart Schaefer
2011-11-07  5:12       ` Aaron Davies

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).