atuinsh / atuin

✨ Magical shell history
https://atuin.sh
MIT License
20.37k stars 554 forks source link

Replace native up arrow more seamlessly #798

Open endigma opened 1 year ago

endigma commented 1 year ago

Is it possible to replace the native up arrow in the shell not with the full screen TUI but with normal up arrow behavior, albeit with the atuin db?

RafaelKr commented 1 year ago

Do you mean disabling the up arrow behavior? You can do this as described here: https://atuin.sh/docs/config/key-binding

endigma commented 1 year ago

No, disabling disables the usage of the atuin history, I just want traditional up arrow behavior but using the atuin history db. The TUI is pretty disruptive to fast usage of the terminal history, and is more suited to replace ctrl-r, up arrow traditionally operates in-place.

conradludgate commented 1 year ago

We have a WIP to add an 'inline view' #648 but it's currently blocked on a few things.

This UI is not final, but it would work a little like this

inline

Might flip the list vertically and have the search at the top, closer to the prompt

endigma commented 1 year ago

So drop-in replacing the normal up arrow behavior with the atuin db is not planned, or not possible? I don't want to see my history or search my history I just want up arrow and down arrow to scrub the history in-place in my prompt. Exactly the same UI/UX as how it works in bash/fish/zsh/etc by default. The notable improvement would be using the atuin db.

conradludgate commented 1 year ago

Ah I see what you mean now. I'll see if that can easily be achieved already

RafaelKr commented 1 year ago

Interesting, I'm using zsh (with oh-my-zsh) with this config:

# Bind ctrl-r but not up arrow
eval "$(atuin init zsh --disable-up-arrow)"

My .zsh_history file is still used synchronously (history.db and .zsh_history are both filled) and the up arrow behaviour is working the same as before installing Atuin.

@endigma Which shell are you using?

Edit: Or do you mean that the history should work across multiple terminals? So if you have open two terminals and run echo 1 in the first and echo 2 in the second both commands should come up when using "Up" in either of them?

endigma commented 1 year ago

Up arrow does still work normally, it uses fish_history, not the atuin db.

arcuru commented 1 year ago

I am fairly sure that you can now add this to the scripts using the --offset flag added in #825.

endigma commented 1 year ago

Yep, that looks like about all that would be required to get this done, I'd still like to see it built in. I think the most challenging bit will be tracking what index the user is currently on, for example fish uses commandline -L which is a builtin that works with internal state.

arcuru commented 1 year ago

I whipped up a version of this for fish, since I've wanted this myself and that's the shell I use: https://github.com/atuinsh/atuin/compare/main...arcuru:atuin:replace-bind-up. Here's a link to the full file, that you can use in place of atuin init fish (note I added the bindings to the script, even though those are normally appended by atuin) https://github.com/patricksjackson/atuin/blob/d4c1c2b4137f39dcbfe57c9cf4c71d7614ea564b/src/shell/atuin.fish

It's not totally trivial but it does seem to work. Though there may be some rough edges compared to using the inbuilt up-or-search though. Pretty much the only benefit of doing it with atuin is that a user could set the filter-mode (EDIT: set correct link) if they wanted something other than session for the up key binding.

I haven't opened a PR since it's unclear if @ellie and @conradludgate would want this integrated as this is a decent sized change to the UX, and it looks like the inline view above might be a better fit for atuin. It may just be best to put this in the documentation somewhere as an example of "How to Customize".

I'd be happy to help integrate but I am not up for writing the scripts for all the other shells.

endigma commented 1 year ago

Perhaps under a switch like bind-r and bind-up, but off by default if this is not the intended pattern. Does your replacement take into account what's currently in the buffer as a search?

arcuru commented 1 year ago

Does your replacement take into account what's currently in the buffer as a search?

No, but that is a short change (add $ATUIN_CURRENT_CMD as the query to atuin search on lines 37 and 52).

The issue, as you've just pointed out, is that there are a lot of different options here, and atuin has for a while bound up to the full interactive search. I don't really get that, but it makes sense for a lot of people, and adding too many options here can be a problem by itself.

What would make the most sense to me, and for how I am used to using the terminal, is to use something like my change above, but pass in the $ATUIN_CURRENT_CMD to atuin, and add a config flag to atuin to also set whether or not you want to use the current cmd as input to the search.

So, a user would choose if they wanted to bind the up-arrow key or not, and in the config file customize the filter-mode, search-mode, and whether to use the current cmd string as the initial query. We could then customize atuin search to do the right thing based on those requirements.

Basically, the up-arrow would be used for cycling through the most recent results in the history, starting with a given search string (or not) and using its own custom filter-/search-modes.

That's how I think it should work, but if you want to use it like that today you already can by customizing the script I shared above.

ellie commented 1 year ago

I haven't opened a PR since it's unclear if @ellie and @conradludgate would want this integrated as this is a decent sized change to the UX, and it looks like the inline view above might be a better fit for atuin. It may just be best to put this in the documentation somewhere as an example of "How to Customize".

This would be really good! I think @takac had something like this for zsh going in #826

I think a "custom shell integrations" page or something similar in the docs would go really well. It might be nice to integrate fully in the future, but we can start there

mentalisttraceur commented 1 year ago

I think the most challenging bit will be tracking what index the user is currently on

If negative offsets are already supported (-1 for last history entry, -2 for second-to-last entry, and so on), then "up" can just do a -1 on a counter, "down" can do a +1, with the counter floored at 0. Just need to reset counter to zero if the user is in the middle of some previous command line and hits Ctrl-C, or runs a new command.

If negative offsets aren't already supported, this is probably good evidence that it's worth doing - seems more elegant and simple to just support negative indexes inside the Atuin CLI than to have every shell integration reimplement the same boilerplate of getting the last offset outside of it.

Nezteb commented 1 year ago

In case anyone is curious, I hacked together my own implementation of the original up/down arrow functionality that still makes use of atuin's database. 😄

https://gist.github.com/Nezteb/81e8f6b78036894a28a4a40772bdda54

takac commented 1 year ago

If negative offsets are already supported (-1 for last history entry, -2 for second-to-last entry, and so on), then "up" can just do a -1 on a counter, "down" can do a +1, with the counter floored at 0. I didn't consider negative offsets when adding the --offset flag, but I did add --reverse which would allow finding the last result.

# last
atuin search --offset 0 --limit 1 --reverse "search-term" # `--offset 0` is unnecessary
# second-to-last
atuin search --offset 1 --limit 1 --reverse "search-term"

# first
atuin search --offset 0 --limit 1 "search-term" # `--offset 0` is unnecessary
ekristen commented 1 year ago

I actually really like this idea. I have often found the up/down more disruptive, especially since I can't immediately start editing the command if I need to. @Nezteb nice hack, but would be nice to get this native into atuin and have a config switch perhaps to control the behavior.

alextremblay commented 1 year ago

I've hacked together a custom bash implementation inspired by @Nezteb's zsh implementation

https://gist.github.com/alextremblay/316d2beede9acd1a29d45d9d32dd310f

notable features: if the current command line is empty, it cycles up and down through atuin's history db just like @Nexteb's implementation, but if you type out a partial command and then hit the up arrow, it launches atuins regular interactive up-arrow behaviou, filtering on that existing prefix

tyalie commented 11 months ago

@Nezteb Hey. I've looked at your script and compared it with e.g. zsh-history-substring-seach and found a few improvements. I've uploaded the updated script here. It essentially resolves your issue around not being able to catch CTRL-C by storing the previous result buffer in global scope. If it changes we know that we need to start a new query.

https://gist.github.com/tyalie/7e13cfe2ec62d99fa341a07ed12ef7c0

ellie commented 11 months ago

I've been thinking and it would be cool to get this included, gated behind config. Or perhaps a new default? It's unlikely to make it into v17, but maybe a v18 thing. Personally I prefer the interactive search, but I understand that it can be too much to get used to and muscle memory is hard to change.

Reading through the issue, looks like we have implementations for:

  1. @tyalie + @Nezteb, zsh: https://gist.github.com/tyalie/7e13cfe2ec62d99fa341a07ed12ef7c0
  2. @arcuru, fish, as described: https://github.com/atuinsh/atuin/issues/798#issuecomment-1493172263
  3. @alextremblay + @Nezteb, bash: https://gist.github.com/alextremblay/316d2beede9acd1a29d45d9d32dd310f

That leaves Nu. I'm not familiar with it so am unlikely to write the integration, but I don't think missing Nu should be a blocker to getting this out.

We could then add a config option to the client like (name pending)

classic_inline = true

or even just catch if inline_height = 1

I'm happy with writing the Rust if you'd all like to contribute your individual scripts/integrations?

It would probably make sense to either modify the current shell integrations to have additional functions (and then we can switch on which is bound, eg by adding _atuin_up_search_inline to zsh), or to add a new file with the inline config (such as atuin.inline.zsh).

Please do feel free to ping me if you'd like input

arcuru commented 11 months ago

That leaves Nu. I'm not familiar with it so am unlikely to write the integration, but I don't think missing Nu should be a blocker to getting this out.

Nu shouldn't/can't do this yet, the up arrow can't work correctly at all without a change to Nushell - https://github.com/atuinsh/atuin/issues/1025

To be honest, the enter_accept setting was enough to tip me back over into just using the full-screen Atuin here, and I'm starting to prefer it this way too :). I'd be happy to contribute that fish script I wrote though once we decide what the path forward is.

It would probably make sense to either modify the current shell integrations to have additional functions (and then we can switch on which is bound, eg by adding _atuin_up_search_inline to zsh), or to add a new file with the inline config (such as atuin.inline.zsh).

I'd vote for adding it the same script file under a new function and switching on which one is bound. It's less surprising to people who want to customize the shell invocation if they get all the options when they dump the script with atuin init.

alextremblay commented 11 months ago

I agree with @arcuru

I will try and take some time to reimplement my bash variant to incorporate some of the improvements @tyalie made to the ZSH implementation, and contribute it here

alextremblay commented 11 months ago

I would prefer to have the "Classic history" mode triggered on a specific config like classic_inline = true, rather than implicitly when inline_height = 1, but i'm ok with either. let me know what you decide

cohml commented 7 months ago

One significant use case for this feature that hasn't been discussed yet is when filter_mode is set to "directory" (#1769).

With this configuration, there's a mismatch between what atuin shows (directory) and what the up arrow cycles through (global). This entails extra (unwelcome) cognitive load, plus people who set filter_mode to "directory" do so because directory history tends to be faster/more useful.

So being able to access it quickly via the up arrow would be a major quality of life improvement.

ellie commented 7 months ago

With this configuration, there's a mismatch between what atuin shows (directory) and what the up arrow cycles through (global).

This is intentional

So being able to access it quickly via the up arrow would be a major quality of life improvement.

We have a separate setting for the up arrow, to enable the user to quickly use a different sort of filtering

filter_mode_shell_up_key_binding = "session"

https://docs.atuin.sh/configuration/config/#filter_mode_shell_up_key_binding

cohml commented 7 months ago

That setting only applies when the up arrow opens the atuin TUI.

filter_mode_shell_up_key_binding

The default filter to use when searching and being invoked from a shell up-key binding.

I am referring to the alternate case, where atuin is initialized with --disable-up-arrow.

Is that not what this thread is about, retaining the up arrow's native shell history scrolling behavior except pulling commands from the atuin db?

It would be awesome if that could be implemented, but to have it respect a certain filter mode.

ellie commented 7 months ago

Sorry, I was replying to a bunch of issues and misread your message

With this configuration, there's a mismatch...

Is written in the present tense, so I took it as the present behaviour of Atuin.

remmycat commented 7 months ago

I was thinking about this issue a bit.

The arrow-up event issue in nushell seems to be solved, but I believe we would at least also need the issue in nushell to be solved that the commandline nu command always creates a new line when "replacing" the contents. I think that would be super annoying when cycling through the history (this is described in the last comment in a maybe-related issue here https://github.com/nushell/nushell/issues/11065)

I've also been wondering if this is the right approach for nushell, at least long-term. Nushell already allows custom external completers (feature description, usage example). I feel like the team might be open to the idea of having a custom external history too, that would integrate better with nushell than manually manipulating the line using keyboard events.

Note that I have not asked anyone about this and might be totally wrong about it, but I was thinking about creating an issue in nushell, if an API like this would make sense to them. The implementation in nushell and reedline might get tricky though.

atuin-bot commented 3 months ago

This issue has been mentioned on Atuin Community. There might be relevant details there:

https://forum.atuin.sh/t/dont-bring-up-ui-for-up-arrow/383/3

GDYendell commented 2 months ago

I would like this to be added too, not because I don't like the search UI, but because I really want to be able to arrow across the current command and then up arrow to repeat the history search with what is to left of the cursor as the prefix. If that was possible through the full search UI (maybe it is?) I think that would be good too. Though, it might be nice if up arrow and Ctrl+R could use different inline heights this case.

davidebenato commented 1 month ago

I would love this functionality as well. The TUI is great for some usecases, but I find the native one line search much better on a faster workflow. There is less information overload and you still have the context of the previous commands.

kboshold commented 4 weeks ago

I have also added this for the Fish Shell. Certainly not yet optimal but works for now... I will optimise it further in the coming weeks:

https://github.com/kboshold/dotfiles/blob/main/dot_config/fish/atuin_history.fish