Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: How to (properly) remove the last entry from history with command_not_found_handler
- X-seq: zsh-users 18984
- From: ZyX <kp-pav@xxxxxxxxx>
- To: Jochen Keil <jrk@xxxxxxxxxxxxx>, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>, "zsh-users@xxxxxxx" <zsh-users@xxxxxxx>
- Subject: Re: How to (properly) remove the last entry from history with command_not_found_handler
- Date: Mon, 21 Jul 2014 21:46:44 +0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1405964805; bh=KPrM/zJh5eP/ncAnm41XC88sLBcS6Hq9YJy1GwJOcMo=; h=From:To:In-Reply-To:References:Subject:Date; b=Vlhv/koe9uqKJbwxyhNmBEezQEMTfAIAO9OB61k+fmmnbGslqqUP9l1jZor9rWe+2 E3UB1Y9O7r5kEIjltISLwqiav9RiOqtP9fhUptgjChQSqAL1Lz1NmiQgzB9FvRS53l 4yJogWlBtgQBC84Vg5XfdpMbs/vUg/eSoVilH1N0=
- In-reply-to: <53CC2B29.2030809@sternenrei.ch>
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
- References: <53CB860C.8080509@sternenrei.ch> <140720111354.ZM20358@torch.brasslantern.com> <53CC2B29.2030809@sternenrei.ch>
21.07.2014, 00:52, "Jochen Keil" <jrk@xxxxxxxxxxxxx>:
> Hello Bart,
>
> On 20.07.2014 20:13, Bart Schaefer wrote:
>> On Jul 20, 11:04am, Jochen Keil wrote:
>> }
>> } function command_not_found_handler()
>> } {
>> } sed -i '$d' $HISTFILE
>> } return 127
>> } }
>> }
>> } However, I'm not sure if it's ok to manipulate the history file directly
>> } with sed, or if I'm risking corruption.
>>
>> This is likely to be a problem if the failing command spans more than
>> one line (e.g., a "for" loop with command-not-found in the middle of
>> it) or if you are using SHARE_HISTORY where there's a race condition
>> among shells reading the history and shells (re)writing it.
>>
>> There really isn't any way to "properly" remove an entry once it has been
>> written to the history file. You might try some variation of this:
>>
>> zshaddhistory() { whence ${${(z)1}[1]} >/dev/null || return 2 }
>>
>> There are still problems with that for multi-line commands but the right
>> way to achieve your desired behavior is to avoid writing out the commands
>> you don't want, not to write them and then delete them again.
>
> It was my first thought too, to avoid adding the command at all.
> However, I misunderstood/misinterpreted the explanation of the
> zshaddhistory hook in the manual. Anyhow, your version works very well,
> thank you!
>
> Nevertheless, I start to see why this is probably a not so good idea (or
> at least pretty hard to implement). For example:
>
> $ echo "test"; echox "test"
>
> This is similar to the multi-line example. One basically needs to split
> up the command at semicolons and newlines. Then one needs to decide
> which of the subcommands is correct and which one not. Finally one needs
> to decide if an altered version of the command should go to the history
> file or none at all.
>
> I think the possible gains are not worth the effort. I'll stick to your
> solution as it covers most of the cases which I care most about: When
> I've accidentally mistyped a command or entered other garbage.
>
> Thank you very much again and best wishes,
>
> Jochen
Are you sure you need to *remove* that entry? I can suggest another approach: defer adding history item until you are sure you can add it:
_record_history_item() {
typeset -g _LASTHISTITEM="${1%%$'\n'}"
return 2 # Never record history at this point
}
zshaddhistory_functions+=(_record_history_item)
_add_history_precmd() {
if test -n "$_LASTHISTITEM" ; then
print -sr -- "$_LASTHISTITEM"
endif
}
precmd_functions+=(_add_history_precmd)
Then all your handler need is to use
_LASTHISTITEM=
to drop history item. I did not test my code though.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author