From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20026 invoked by alias); 11 Oct 2011 02:05:42 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 16474 Received: (qmail 7361 invoked from network); 11 Oct 2011 02:05:39 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received-SPF: none (ns1.primenet.com.au: domain at closedmail.com does not designate permitted sender hosts) From: Bart Schaefer Message-id: <111010190517.ZM5763@torch.brasslantern.com> Date: Mon, 10 Oct 2011 19:05:17 -0700 In-reply-to: <20111010231518.BFD1A10E2AA@smtp.hushmail.com> Comments: In reply to dg1727@hushmail.com "Would like an alias to read the part of the current command line that precedes the alias" (Oct 10, 7:15pm) References: <20111010231518.BFD1A10E2AA@smtp.hushmail.com> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-users@zsh.org Subject: Re: Would like an alias to read the part of the current command line that precedes the alias MIME-version: 1.0 Content-type: text/plain; charset=us-ascii 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.