Giter Club home page Giter Club logo

zsh-hist's Introduction

zsh-hist

Edit your Zsh history, without ever leaving the command line.

Installation

  1. git clone this repo.
  2. Add the following to your ~/.zshrc file:
    source path/to/zsh-hist.plugin.zsh

To update, cd into your clone and git pull.

Uniform code formatting

Whenever you finish your command line, zsh-hist will automatically format it for you, before it is saved to history. You can also retroactively format your history with hist n.

Notes on code formatting

  • For the formatting to be preserved completely when the command is saved history, you need to unsetopt HIST_REDUCE_BLANKS in your .zshrc file. Otherwise, most of the indentation will get lost.
  • Formatting the code can disable certain crazy uses of global aliases. For example, since the formatting turns most ;s into newlines, declaring ; as a global alias will most of the time simply not have any effect. Since this is not something a normal person would want to do, most users don't need to worry about this. However, if you are a purist and want that the formatting can never change the way Zsh works, then please enable the automatic alias expansion feature below.
  • To disable this feature, add the following to your .zshrc file:
    zstyle ':hist:*' auto-format no

Automatic alias expansion (Optional)

zsh-hist can automatically expand your aliases before each command line is saved to history. This is disabled by default, but to enable it, add the following to your .zshrc file:

zstyle ':hist:*' expand-aliases yes

Added Undo functionality

On any new command line, you can now press Undo to pop the last command from your history into the line editor, letting you correct any mistakes you made, before running it back. Afterwards, the old, faulty command will be gone from your history and only the new, corrected one remains.

Additionally, if you make a typo and end up on the secondary prompt, you can now press Undo to return to the primary prompt.

Push lines to history

When you press โŒƒQ, your line is now written to history (without being executed) instead of to the buffer stack.

This has the following benefits:

  • A pushed line does not automatically get popped back into your line editor.
  • Pushed lines persist as long as they remain in your history and can be shared between multiple sessions.
  • Pushed lines can be accessed using conventional history search mechanisms.

Pressing โŒƒQ on the secondary prompt will return you to the primary prompt.

hist command syntax

Usage
  hist [<option>...] compress <delta>
  hist [<option>...] {reload|undo}
  hist [<option>...] <command> <selection> ...

Return value
  $reply  an associative array of history index -> entry tuples

Options
  -f  force: never ask for confirmation
  -i  interactive: always ask for confirmation
  -q  quiet: do not print anything
  -s  silent: same as quiet
By default, hist asks for confirmation only when operating on multiple history
entries.

Commands (can be shortened to first letter):
  compress   delete each entry that differs <delta> chars or less from the next
  delete     remove from history
  edit       delete, then modify & append as new
  fix        delete + get
  get        load into buffer
  list       look, but do not touch
  normalize  delete, then auto-format & append as new
  reload     re-initialize local history from file
  undo       roll back to before last command in same session

Selections (for commands other than compress, reload or undo):
  negative int  offset from end of history
  positive int  index from beginning of history
  pattern       all matching entries

Examples
  hist f -1         # Fix last entry (cut from history; paste into command line)
  hist n {1..9}     # Normalize (uniformly format) a range of history items
  hist d $'*(\n|;)' # Delete all entries ending in newline or semicolon

Author

ยฉ 2020 Marlon Richert

License

This project is licensed under the MIT License. See the LICENSE file for details.

zsh-hist's People

Contributors

helmecke avatar marlonrichert avatar tangoman75 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

zsh-hist's Issues

Don't add current command to history (`ignore` flag)

What do you want?

Running a command without it being added to the history in the first place (sort of, it shall be added, but removed instantly). This would be great, as it would allow to send a single command in incognito without the necessity to send a hist d -1 afterwards.

Why do you want this?

I have so send a secret to my Android phone via USB debugging (adb shell -n input text), because the TAN2GO app of my bank won't allow me to paste in passwords from my password manager. Flawed design. I then want to prevent the secret in my history.

Who else would benefit from this?

Anybody who wants to send a single command and delete it from history in one go, i.e. when having the command on the password manager like I do. Right now, sending adb shell -n input text mysecret; hist d -1 will not remove the secret, but the history entry prior. So the user has to send two commands.

How should it work?

Given this situation:
A new flag to secretly send a command and remove it from history afterwards, let's call it ignore/i?

When I perform these steps:
hist ignore echo secret

Then I expect this to happen:
It should print secret without adding echo secret to the history.

Thanks!

Commands drawn from history cannot be executed.

Reproduction:

$ cd "$(mktemp -d)"
$ zsh -f
$ source /absolute/path/to/zsh-hist/zsh-hist.plugin.zsh
$ echo Test1

Press โ†‘Enter.

Expected result: echo Test1 should be retrieved from the command history, then executed.
Actual result: echo Test1 is retrieved from history, but it appears as if only a blank line was executed.

Plugin no longer working as expected after recent changes

Describe the bug

Before commit 6b0e5e6 this plugin was working as expected for me:
^q pushed a command to history and ^g retrieved it from history - perfect! ๐Ÿ˜„

After the commit from above on Feb. 07 2023, this functionality broke. Now, when I press ^q the current command is added to the buffer-stack instead and automatically poped when I press enter ๐Ÿ˜ž

Steps To Reproduce

zinit light-mode for marlonrichert/zsh-hist

The above works as expected before Feb. 07 and stops working after Feb. 07

Expected behavior

Should continue to work as described, even after the changes introduced in February

Environment:

  • OS: Arch Linux
  • Terminal: Kitty
  • Zsh version: zsh 5.9 (x86_64-pc-linux-gnu)
  • Repo version: latest

Additional context

I know you frown upon using zinit, however it worked flawlessly before, so perhaps it's not even zinit's fault?

Select multiple history entries

Very nice plugin, thanks!

I'd like to delete ranges of command lines from the history.

The use case is that it usually takes a lot of trial and error before building the perfect complex one-liner (e.g. a text processing command with regex). I want to keep the good command in history and delete the incorrect tentatives.

Python slice notation syntax could be convenient:

e.g:

hist d [-3:]    # delete last 3 lines
hist d [-10:-2]   # delete last 10 lines, except the most recent one
hist d [1500:1510]   # delete lines with index 1500 to 1510

Maybe brackets can be omitted for an even more concise syntax.

Another suggestion, with probably less potential for popularity, but which would be practical in many cases:

hist d 60m # delete all commands from the last 60 minutes

Aliases are automatically expanded before the command is executed

To reproduce:

% zsh -f
% git clone https://github.com/marlonrichert/zsh-hist.git
% source zsh-hist/zsh-hist.plugin.zsh
% alias x='echo hello'
% x

Expected: upon hitting Enter after entering the last command the following lines appear:

% x
hello

Actual: these lines appear instead:

%   echo hello
hello

Commit: bf89313.

History line autocompletion not working.

Typing hist d - + tab I would expect to see a menu with history lines available for deletion (prefixed by their number). Unfortunately, though, the tab key does nothing.

I have confirmed that my history is not empty (in fact, running hist d 3 successfully deletes its third line).

Curiously, this works as expected in conjunction with zsh-autocomplete.

Relevant .zshrc excerpt follows. Many thanks!

znap source "marlonrichert/zsh-hist"
bindkey "^[z" undo
bindkey "^[p" push-line-or-edit
bindkey "^[g" get-line
setopt histfcntllock histignorealldups histsavenodups sharehistory hist_verify hist_reduce_blanks

Widgets are not found anymore

I'm loading zsh-hist using zinit and sice the latest commit I get an error whenever I want to execute a zle widget. For example: No such shell function `.hist.undo.widget' for ^_. Probably related to the removed autoload stuff?

How to do a big-time auto format in place?

Hi, in a no brainer way, how can I reformat my ~150k lines long $HOME/.zsh_history in place with its history auto formatted?

I cannot figure out how to use your plugin in such a scale (I managed to get a few lines formatted).

Command line prepended with tab character.

Thank you for yet another excellent plugin.

Curiously, the plugin seems to cause the prepending of every command with a tab character (\t).

This tab is inserted both in the command line (upon pressing Enter) and in the history (as confirmed by hist l).

Any thoughts as to what the reason might be? Thank you once again.

Make plugin work with per-directory-history too, not just global history

What do you want?

per-directory-history is a very simple yet extremely nice zsh plugin which allows users to track not only "global" history, but also history on a per-directory basis. In other words, if I run cd ~ from ~/foo, cd ~ would be recorded in my global history, but also in a dedicated file containing only those commands execute from ~/foo. This is useful because often commands run from a given location are related, so being able to search only among them helps filter out noise and find the desired commands quickly.

Anyway, zsh-hist currently seems to only work with global history, which makes it only a partial solution for the users of per-directory-history.

Therefore modifying zsh-hist to be sensitive to history mode, such that commands are removed only from the currently-active history file (or perhaps even better, from both global and per-directory histories?) would be a major usability upgrade.

Why do you want this?

Because from what I can tell, zsh-hist doesn't do anything with per-directory histories, rendering it only half useful for per-directory-history users.

Who else would benefit from this?

Anyone who uses per-directory-history or equivalent plugins.

For the record, per-directory-history is one of the plugins that ships natively with Oh-My-Zsh, so the user base is potentially large.

How should it work?

Persumably zsh-hist would first identify the current history mode, and accordingly the associated history file. Any deletions/updates/etc. would then be applied to that file, at a minimum.

Ideally they would also be applied to the global file, so that everything in (or not in) a local file is also in (or not in) the global file, but this is just "nice to have" since I realize it may be a heavy lift.

Regex `\b` replaced with `^H` in multi-line command

Describe the bug

When I type out a multi-line command involving a regex \b character, the expansion replaces \b with ^H.

Steps To Reproduce

N.b. paste the first line first, then the remaining lines (to simulate typing out the command interactively).

for f in $(grep -l '\bfoo\b' *); do
  echo "foo found in $f"
done

after pressing enter after done the prompt displays

for f in $(grep -l '^Hfoo^H' *)
do
        echo "foo found in $f"
done

Expected behavior

\b to be unchanged

Observed behavior

\b was replaced with ^H (which breaks the grep pattern)

Environment:

  • OS: macOS Version 13.2.1
  • Terminal: iTerm2 3.4.19
  • Zsh version: 5.8.1
  • Repo version: 6b0e5e6

^Q unavailable in vi command mode

Describe the bug

The README states that this plugin binds ^Q to an action, but it doesn't do so for vi command mode.

Steps To Reproduce

Source zsh-hist and enter emacs mode.

source zsh-hist.plugin.zsh
bindkey -e

Note that the ^Q yields the desired behavior.

Now enter vi mode.

bindkey -v

After ensuring you're in insert mode (press Esc and then i to be sure), note that ^Q works.

Now press Esc to enter command mode, and note that ^Q does NOT work.

Expected behavior

push-history is not Emacs/Vi/insert/command-related, so^Q should yield the same behavior across all modes by default.

Observed behavior

^Q works only in emacs mode and vi insert mode, not vi command mode.

Click to expand

Environment:

  • OS: macOS
  • Terminal: iTerm2
  • Zsh version: 5.9
  • Repo version: * main 3efe240 Fix bugs in push-history widget

Problems with unicode characters

First: this is a great plugin which I use every day, thanks for making it available!

I noticed I can no longer work with (German, in my case) Unicode-characters after loading zsh-hist, here is what happens:

Without this plugin:

โฏ echo 'รŸ'
รŸ

Same command with zsh-hist loaded:

โฏ echo 'รƒ<bf>'
รƒ

...which then breaks programs like grep searching for Umlauts or similar.

This behavior is reproducible even in a clean zsh-environment as described here

The term "undo" is used twice

Great plugin - undo is exactly what I want to use it for (the ^_ version).

However I see from the instructions that hist u is also an "undo". I have now finally got it but I did find it confusing. Maybe change that one to be "rollback" (with letter b) or "revert" (with letter v)?

Code formatting ignores HIST_IGNORE_SPACE

I have the (arguably bad?) habit of prefixing commands I don't want to have in my history (e.g. because of temporary, specific parameters or sensitive arguments) with a space. For that I have setopt hist_ignore_space in my .zshrc.

Unfortunately the new code formatting feature (which sounds great, btw) doesn't respect that option. I tried with and without HIST_REDUCE_BLANKS but the results are the same: the leading whitespace is removed and thus the command is saved in history.

It would be great if the formatting would respect that setting (e.g. by keeping leading whitespace?) or (as a workaround) if the formatting could be disabled.

History line tab-completion not working.

Typing hist d - + tab I would expect to see a menu with history lines available for deletion (prefixed by their number). Unfortunately, though, the tab key does nothing.

I have confirmed that my history is not empty (in fact, running hist d 3 successfully deletes its third line).

Curiously, this works as expected in conjunction with zsh-autocomplete.

Relevant .zshrc excerpt follows. Many thanks!

znap source "marlonrichert/zsh-hist"
bindkey "^[z" undo
bindkey "^[p" push-line-or-edit
bindkey "^[g" get-line
setopt histfcntllock histignorealldups histsavenodups sharehistory hist_verify hist_reduce_blanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.