Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Press UP key will get last command from other tabs #2513

Closed
1 task done
firstrose opened this issue Apr 1, 2021 · 20 comments
Closed
1 task done

Press UP key will get last command from other tabs #2513

firstrose opened this issue Apr 1, 2021 · 20 comments

Comments

@firstrose
Copy link

firstrose commented Apr 1, 2021

Purpose of the issue

  • Bug report (encountered problems/errors)

Version Information

210304

Win10 10.0.19042.867

Description of the issue

Open one console window in Cmder and execute some commands.
Then open one new window in Cmder, just press UP key.
You will get you last command in previous window, not this windown(new window has no history, so nothing loaded is expected).
Looks like all windows in Cmder share the same history.

This "last command" feature should not be "cross window".

I tested it on ConEmu, different window has their own history, that is right.

@chrisant996
Copy link
Contributor

What kind of console window is being opened? I'll assume the default "Cmder" task, which uses Clink.

What does clink set history.shared report?
It sounds like shared history is enabled.
If so, it sounds like disabling it would be the solution.

The Clink documentation has information about Clink and how to configure it.
Shared history is off by default, but maybe it was turned on either by Cmder or by some other manual steps.

@firstrose
Copy link
Author

What kind of console window is being opened? I'll assume the default "Cmder" task, which uses Clink.

What does clink set history.shared report?
It sounds like shared history is enabled.
If so, it sounds like disabling it would be the solution.

The Clink documentation has information about Clink and how to configure it.
Shared history is off by default, but maybe it was turned on either by Cmder or by some other manual steps.

Thank you very much. That is the reason.

The switch is on in Cmder's initial config.

@firstrose
Copy link
Author

What kind of console window is being opened? I'll assume the default "Cmder" task, which uses Clink.

What does clink set history.shared report?
It sounds like shared history is enabled.
If so, it sounds like disabling it would be the solution.

The Clink documentation has information about Clink and how to configure it.
Shared history is off by default, but maybe it was turned on either by Cmder or by some other manual steps.

Looks like set "shared history" doesn't fully fix the problem.
Different clink instance seems has the same position for histories. So the first clink instance exits, it saves its history. Then the second write to the same file.......
As result, restart Cmder will cause all console load the same saved history.

Any suggestion? If I still want to persist history?

@chrisant996
Copy link
Contributor

Looks like set "shared history" doesn't fully fix the problem.

What is it set to?
What is the full output from clink set?

Different clink instance seems has the same position for histories. So the first clink instance exits, it saves its history. Then the second write to the same file.......
As result, restart Cmder will cause all console load the same saved history.

Any suggestion? If I still want to persist history?

I don't understand what behavior is desired. Please explain.

It almost sounds like you want each console window to save history and reload it in the future. But each new future console should only load its own history, not the history from other console windows.

But how could that work? There is no way to associate a new console with a specific old console.

Please explain in detail what is desired.
Please explain in detail what isn't working as desired, and please show the output from clink set.

@firstrose
Copy link
Author

Sorry for my delay.

Thank you for your kind help.

My previous comment only said one thing: After restart Cmder, every console window can obtain all the console's history of last run.

I really mean "each console window to save history and reload it in the future"

Yes, this is NO method can EXACTLY associate a new console with a specific old console.

An obvious solution is don't save history.

But IMHO, there is a middle ground.

Cmder will save current directory for every console when exit, and restore it when restart. I think it can be a association.

So maybe there is another solution:

  1. When clink save history for current console, also save current directory. Change current directory should overwrite old value.
  2. When restart, look for current directory and load corresponding history.

I don't think it is a perfect solution. But I really think it is good enough.

What is your option?

@daxgames
Copy link
Member

daxgames commented Apr 5, 2021

Cmder does not save current directory on exit, nor does it restore anything on relaunch. Conemu a completely separate part of the Cmder package provides this functionality and it is also completely separate from Clink.

Cmder is the config and init scripts that ties all this together.

This is not a bug it is how it works.

Nothing to fix.

@chrisant996
Copy link
Contributor

My previous comment only said one thing: After restart Cmder, every console window can obtain all the console's history of last run.

I really mean "each console window to save history and reload it in the future"

Yes, this is NO method can EXACTLY associate a new console with a specific old console.

I see, you're exploring heuristics for how to approximate associating a new console with an old console.

That is presupposing that Clink would keep track of many separate persisted histories, and somehow manage the storage space and lifetimes. That seems pretty complicated and expensive, and also very unpredictable and confusing. More on that below...

An obvious solution is don't save history.

Which is clink set history.save false.

But IMHO, there is a middle ground.

Cmder will save current directory for every console when exit, and restore it when restart. I think it can be a association.

So maybe there is another solution:

  1. When clink save history for current console, also save current directory. Change current directory should overwrite old value.
  2. When restart, look for current directory and load corresponding history.

I don't think it is a perfect solution. But I really think it is good enough.

What is your option?

I think it can seem good at first look, but quickly runs into edge cases that are ambiguous and lead to complexity and confusion.

Here is a major one:

In that model, history is loaded from one source, and then saved to a different source. It inherently migrates history around, which leads to problems such as collisions and merging, predictability, "losing" all the history when the history "moves" to be associated with a different directory, and so on.

Can you please describe the problem that it's intended to solve?
I understand the proposed implementation, and I see many problems that would prevent me from implementing it.
It would be very helpful to understand the problem that it's trying to solve, so that I could look for other approaches that might be able to solve the problem.

I don't have a clear understanding yet of what is considered to be the problem.

@chrisant996
Copy link
Contributor

I don't think ConEmu does anything at all about history, so if you like how ConEmu works then maybe clink set history.save false might be what's desired. That won't save/load history, but it will keep separate histories for windows while they are open.

Or clink set history.shared false will keep history separate until a console window closes, and then its history will merge into the master history -- but windows that are already open won't see the new history yet.

Again, please describe the problem, so that we have a shared understanding of what the problems and requirements are, before trying to produce an implementation.

@firstrose
Copy link
Author

firstrose commented Apr 7, 2021

I don't think ConEmu does anything at all about history, so if you like how ConEmu works then maybe clink set history.save false might be what's desired. That won't save/load history, but it will keep separate histories for windows while they are open.

Or clink set history.shared false will keep history separate until a console window closes, and then its history will merge into the master history -- but windows that are already open won't see the new history yet.

Again, please describe the problem, so that we have a shared understanding of what the problems and requirements are, before trying to produce an implementation.

Thank you for your explaination.

Now I think history.save=false and history.shared=false will be the final solution for me.

Let me explain it.

I have many console applications to run. Every application is in its own directory. Sometimes, I need to restart one of them. It's painful to look for one special console in many CMD. But Cmder can help me.

At first, I open consoles in Cmder, execute CD in each console, run applications. Then Cmder will keep "current directory" for me after restarting my computer. Also, application's name is saved as history. So I can simply press UP to get command line after restart.

When I have to restart one application, I switch to the tab, press CTRL-C to break it, then UP, and ENTER.

Then I found all consoles share history.

I thought it is a bug.

With your help, I found history.shared is set to true in Cmder's initial config.

After that, I found the history is still "shared" after restart. So I thought, it's better to separate each console's history.

Since separating histories is hard to do, I think I can accept not to persist history. Because clink has another feature: filter exe file first when press TAB. That is also a big help.

Thank you for your patience.

@daxgames
Copy link
Member

daxgames commented Apr 7, 2021

@firstrose have you tried using the history search to find the command?

@firstrose
Copy link
Author

@firstrose have you tried using the history search to find the command?

Not yet.

In my case, every application has its own fixed location/directory. Only one console is needed for each application, and the exe file names are also fixed. So each console's histroy should has only one item normally. Search is useless and UP for "last command" is what I need.

Thank you.

@chrisant996
Copy link
Contributor

@firstrose ah! Thank you very much, that made everything clear now.

I don't think that's a work environment that I would want to make Clink try to automatically deduce and support.

But it would be pretty simple and safe to add an environment variable to override the name of the history file. Then it would be possible for a script to explicitly configure where each session stores its history, and it would even be possible to make multiple "Foo Task" consoles share history, and have multiple "Bar Task" consoles share different history.

I think that might be significantly more flexible and powerful and more exactly fit the goals, while also being very simple to implement and also to configure.

What do you think?

@daxgames
Copy link
Member

daxgames commented Apr 8, 2021

Cmder provides a way to create task that runs a specific app/exe when it starts. Would that help?

@chrisant996
Copy link
Contributor

Cmder provides a way to create task that runs a specific app/exe when it starts. Would that help?

Yes. That could be used to set the history file name for the task (once Clink supports that).

@firstrose
Copy link
Author

But it would be pretty simple and safe to add an environment variable to override the name of the history file. Then it would be possible for a script to explicitly configure where each session stores its history, and it would even be possible to make multiple "Foo Task" consoles share history, and have multiple "Bar Task" consoles share different history.

Thank you for the reply.

Yes, it's a good idea. But IMHO it should be an command-line argument, not an environment variable.

e.g.

clink -history-file-location=.\hist.clink

That will be more flexible.

========================================

There ia one more question: How to clear history ONLY for CURRENT Session? I read manual and find no clew.

Thanks in advance.

@chrisant996
Copy link
Contributor

chrisant996 commented Apr 9, 2021

Yes, it's a good idea. But IMHO it should be an command-line argument, not an environment variable.

e.g.

clink -history-file-location=.\hist.clink

That will be more flexible.

No:

  • This is not a way to change the folder where history is stored. The --profile arg already controls that. If that's what's desired, that was already available.
  • This enables one profile to have multiple history lists. I'm not going to support storing history in arbitrary locations outside the profile directory. I think that would undermine how Clink organizes the profile.
  • This is more flexible than an arg because this can be changed on the fly without closing/reopening the window.

There ia one more question: How to clear history ONLY for CURRENT Session? I read manual and find no clew.

This is an implementation suggestion without context. Can you describe the motivation? What problem is it trying to solve?

There is not a way. Also, the question could mean several different things depending on intent and on config settings. If "session" is referring to when history.shared is off, then it's unclear to me yet why that edge case would be desirable.

Please explain.

Thanks!

@firstrose
Copy link
Author

No:

* This is not a way to change the folder where history is stored. The `--profile` arg already controls that. If that's what's desired, that was already available.

* This enables one profile to have multiple history lists. I'm not going to support storing history in arbitrary locations outside the profile directory. I think that would undermine how Clink organizes the profile.

* This is more flexible than an arg because this can be changed on the fly without closing/reopening the window.

I found you added %CLINK_HISTORY_LABEL%

But it confuses me. Because I really don't know how to enable multiple history lists by only one environment variable. Since it can be changed on fly, while all the consoles can get to know.

I looked up your document and found no usage yet. Could you please give more detail in the document?

This is an implementation suggestion without context. Can you describe the motivation? What problem is it trying to solve?

Please explain.

Please put it aside, before I get to know how %CLINK_HISTORY_LABEL% works. Maybe it isn't a question any more after that.

Thank you very much.

@chrisant996
Copy link
Contributor

chrisant996 commented Apr 10, 2021

Start a console for project Foo.
set clink_history_label=foo

Start a console for project Bar.
set clink_history_label=bar

There is already something being used to launch the different consoles in different directories. Make that set the envvar, in addition to setting the directory.

(Setting an environment variable in one console only affects that console, not other ones.)

@firstrose
Copy link
Author

Start a console for project Foo.
set clink_history_label=foo

Start a console for project Bar.
set clink_history_label=bar

There is already something being used to launch the different consoles in different directories. Make that set the envvar, in addition to setting the directory.

(Setting an environment variable in one console only affects that console, not other ones.)

Aha! I get. No problems any more.

Thank you very much.

@kzkvv
Copy link

kzkvv commented Sep 11, 2021

Just info for someone who found this issue and want to save separated histories for each console, it may help you:

  • install cmder
  • install clink (globaly)
  • reboot your PC
  • check that clink is installed successfully - you must see clink copyright in cmder console
  • select 'auto save/restore opened tabs' in cmder settings: settings -> startup
  • during start a new console in cmder (ctrl+T) paste this command before your startup command: set clink_history_label=your_label_name &&
    For example, this command will start new console with clink label your_label_name : set clink_history_label=your_label_name && cmd /k ""%ConEmuDir%\..\init.bat" "
    For each next new console this prefix will be setted automatically and you must just change label name to have separated histories.
    And after cmder restart your previous tabs will reopened automatically with self history in each.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants