History sharing between active sessions seems broken, or isn't instant.
The following documentation item would seem to imply that SaveIncrementally would allow the history to be used between sessions immediately.
-- SaveIncrementally: save history after each command is executed - and share across multiple instances of PowerShell
Environment data
PSReadLine 2.0.0-beta6 PowerShell 6.2.3 & 7.0.0-preview6 Windows 10 Insiders 19030.1
Steps to reproduce
Start multiple sessions simultaneously, enter commands in each, and afterwards use UpArrow to attempt to find each others commands in different sessions
The only result I get is that a new session created after all the commands in the different sessions, will see all the history, in the order they were entered.
This is by design, see https://github.com/PowerShell/PSReadLine/commit/49a4c4c1e62a00dc9fda357b0182a0d76d0d3bd9
Interesting ... any documentation that clarifies that? (thinking about others who might be trying to understand what is meant by sharing between sessions)
However, I think this particular feature might be occasionally causing a problem. Occasionally when I have multiple sessions and I am entering similar commands between them, UpArrow recall won't recall the last command I just entered in to that session ... possibly because it was a duplicate.
Start two sessions (herein refefred to as A and B) (substitute commands with fresh test commands so as not to trip duplicate detection right away, here I have used invalid commands)
- In A, type
test& ENTER - In B, type
hello& ENTER - In A type
hello& ENTER - in B type
test& ENTER
Now in B, UpArrow produces hello, probably because it thinks that the test was a duplicate, and then because the first instance is from a different session, it shouldn't be shown??
Or maybe it is in A, I repeated it with new commands (dudd and goofy), and I even know that A possessed the history item (from step 1) between step 2 and 3, but after step 4, it would not recall either command!
I don't think it's documented, but it's after some experience both ways, the current implementation is mostly what people seem to expect so it didn't seem critical to document.
I have a feeling I've observed the behavior you describe, but I was always in too much of a hurry to determine the root cause.
I'm aware of at least 1 other undesirable interaction: https://github.com/PowerShell/PSReadLine/issues/211
Now in B, UpArrow produces
hello, probably because it thinks that thetestwas a duplicate, and then because the first instance is from a different session, it shouldn't be shown??
The fix probably should be done here: https://github.com/PowerShell/PSReadLine/blob/4fe166e000d0ed1b28a9db865c900f485b5ed027/PSReadLine/History.cs#L133-L137
If the line is from the current session and the last history item has the same command line, then maybe update that history entry to make it from local session. edits needs to be updated too, but GetAddToHistoryOption should still return SkipAdding.
I doubt the current behavior is noticeable to most users, so put this issue in low priority.
I think the problem is in WriteHistoryRange:
finally
{
if (historyLines != null)
{
// Populate new history from other sessions to the history queue after we are done
// with writing the specified range to the file.
// We do it at this point to make sure the range of history items from 'start' to
// 'end' do not get changed before the writing to the file.
UpdateHistoryFromFile(historyLines, fromDifferentSession: true, fromInitialRead: false);
}
}
combined with HistoryRecall
if (_history[newHistoryIndex].FromOtherSession)
{
continue;
}
WriteHistoryRange is adding other sessions history to the current session AFTER the latest command. This means that commands in the session history are out of order relative to the file (i.e. chronological) history. Analysis of the example follows. Note that the prime (') is for identification and is ignored in comparisons.
time A cmd A hist B cmd B hist file
1 test test test
2 hello' hello' test
test hello'
3 hello test test
hello hello'
hello
4 test' hello' test
test hello'
hello
At time 2, B's history ends up with test after hello' even though it was entered into A before hello' was entered into B.
At time 3, A's history ignores the duplicate hello' after writing its own hello to the file.
At time 4, B's history ignores the duplicate test' completely (doesn't write it to the file).
So now when up-arrow is pressed in B, the first history item found is test instead of test' (wrong session) and is skipped.
The idea of modifying the "duplicate" entry in the current session's history if it is from another session would solve this very limited example but doesn't fix the problem of history entries losing chronological ordering. It would be possible for very old entries from another session to end up ahead of the most recent entry of the current session (if you had left the current session idle for a long time while using other sessions). This would not be a problem for arrow navigation (ignores other sessions) but could give unexpected results when using search functions. Also, the suggestion that GetAddToHistoryOption should still return SkipAdding means that the overall history is incorrect. In the example, the last command entered (in any session) was test' but this is not reflected in the history file. A possibly better solution could be that if the entered command is the same as the last history entry but the history entry is from another session then that history entry is deleted and the new command added as if there were no match found. This could result in duplicate entries in the history file (already happening, see above) but might be useful to indicate that a command was repeated but into a different session.
Edit: Older versions such as V2.0.0-beta2 (my Win10 1903) don't use the same code as listed above but the effect is the same, new history from other sessions is read (before this session's is written) and then added to the end of the queue.