Skip to content

Commit 49a4c4c

Browse files
committed
History recall should ignore other sesions
When using UpArrow, people prefer not recalling commands from other currently running sessions. It's still useful to avoid entering commands that have might have been entered in another currently running session, so those commands can still be found when *searching* history, either interactively, or if the search string is not empty when using HistorySearch[Backward|Forward]. Also fixed in this change - an obscure bug where HistoryNoDuplicates did not work well with a DigitArgument when recalling history. Fixes #179
1 parent e2311b0 commit 49a4c4c

File tree

3 files changed

+70
-34
lines changed

3 files changed

+70
-34
lines changed

PSReadLine/Changes.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Bug fixes:
1717
* Fix exception on error input during rendering after certain keywords like process, begin, or end.
1818
* Fix exception after undo from menu completion
1919
* Support CancelLine (Ctrl+C) and Abort (Ctrl+G in emacs) to cancel DigitArgument
20+
* History recall now ignores command lines from other currently running sessions, but you can
21+
still find command lines from those sessions when searching history.
2022

2123
New functions:
2224
* ValidateAndAcceptLine

PSReadLine/History.cs

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class HistoryItem
1717
public List<EditItem> _edits;
1818
public int _undoEditIndex;
1919
public bool _saved;
20+
public bool _fromDifferentLiveSession;
2021
}
2122

2223
// History state
@@ -39,7 +40,7 @@ class HistoryItem
3940
private const string _failedForwardISearchPrompt = "failed-fwd-i-search: ";
4041
private const string _failedBackwardISearchPrompt = "failed-bck-i-search: ";
4142

42-
private string MaybeAddToHistory(string result, List<EditItem> edits, int undoEditIndex, bool readingHistoryFile)
43+
private string MaybeAddToHistory(string result, List<EditItem> edits, int undoEditIndex, bool readingHistoryFile, bool fromDifferentSession)
4344
{
4445
bool addToHistory = !string.IsNullOrWhiteSpace(result) && ((Options.AddToHistoryHandler == null) || Options.AddToHistoryHandler(result));
4546
if (addToHistory)
@@ -50,6 +51,7 @@ private string MaybeAddToHistory(string result, List<EditItem> edits, int undoEd
5051
_edits = edits,
5152
_undoEditIndex = undoEditIndex,
5253
_saved = readingHistoryFile,
54+
_fromDifferentLiveSession = fromDifferentSession,
5355
});
5456
_currentHistoryIndex = _history.Count;
5557

@@ -168,7 +170,7 @@ private void MaybeReadHistoryFile()
168170
historyLines.Add(sr.ReadLine());
169171
}
170172
}
171-
UpdateHistoryFromFile(historyLines);
173+
UpdateHistoryFromFile(historyLines, fromDifferentSession: true);
172174

173175
_historyFileLastSavedSize = fileInfo.Length;
174176
}
@@ -197,7 +199,7 @@ private void ReadHistoryFile()
197199
}
198200

199201
var historyLines = File.ReadAllLines(Options.HistorySavePath);
200-
UpdateHistoryFromFile(historyLines);
202+
UpdateHistoryFromFile(historyLines, fromDifferentSession: false);
201203
var fileInfo = new FileInfo(Options.HistorySavePath);
202204
_historyFileLastSavedSize = fileInfo.Length;
203205
}
@@ -208,7 +210,7 @@ private void ReadHistoryFile()
208210
}
209211
}
210212

211-
void UpdateHistoryFromFile(IEnumerable<string> historyLines)
213+
void UpdateHistoryFromFile(IEnumerable<string> historyLines, bool fromDifferentSession)
212214
{
213215
var sb = new StringBuilder();
214216
foreach (var line in historyLines)
@@ -223,13 +225,13 @@ void UpdateHistoryFromFile(IEnumerable<string> historyLines)
223225
sb.Append(line);
224226
var l = sb.ToString();
225227
var editItems = new List<EditItem> {EditItemInsertString.Create(l, 0)};
226-
MaybeAddToHistory(l, editItems, 1, readingHistoryFile: true);
228+
MaybeAddToHistory(l, editItems, 1, /*readingHistoryFile*/ true, fromDifferentSession);
227229
sb.Clear();
228230
}
229231
else
230232
{
231233
var editItems = new List<EditItem> {EditItemInsertString.Create(line, 0)};
232-
MaybeAddToHistory(line, editItems, 1, readingHistoryFile: true);
234+
MaybeAddToHistory(line, editItems, 1, /*readingHistoryFile*/ true, fromDifferentSession);
233235
}
234236
}
235237
}
@@ -242,7 +244,7 @@ public static void AddToHistory(string command)
242244
{
243245
command = command.Replace("\r\n", "\n");
244246
var editItems = new List<EditItem> {EditItemInsertString.Create(command, 0)};
245-
_singleton.MaybeAddToHistory(command, editItems, 1, readingHistoryFile: false);
247+
_singleton.MaybeAddToHistory(command, editItems, 1, readingHistoryFile: false, fromDifferentSession: false);
246248
}
247249

248250
/// <summary>
@@ -307,38 +309,45 @@ private void HistoryRecall(int direction)
307309
return;
308310
}
309311

310-
int newHistoryIndex;
311-
if (Options.HistoryNoDuplicates)
312+
if (Options.HistoryNoDuplicates && _recallHistoryCommandCount == 0)
313+
{
314+
_hashedHistory = new Dictionary<string, int>();
315+
}
316+
317+
int count = Math.Abs(direction);
318+
direction = direction < 0 ? -1 : +1;
319+
int newHistoryIndex = _currentHistoryIndex;
320+
while (count > 0)
312321
{
313-
if (_recallHistoryCommandCount == 0)
322+
newHistoryIndex += direction;
323+
if (newHistoryIndex < 0 || newHistoryIndex >= _history.Count)
314324
{
315-
_hashedHistory = new Dictionary<string, int>();
325+
break;
316326
}
317327

318-
newHistoryIndex = _currentHistoryIndex;
319-
while (true)
328+
if (_history[newHistoryIndex]._fromDifferentLiveSession)
329+
{
330+
continue;
331+
}
332+
333+
if (Options.HistoryNoDuplicates)
320334
{
321-
newHistoryIndex = newHistoryIndex + direction;
322-
if (newHistoryIndex < 0 || newHistoryIndex >= _history.Count)
323-
{
324-
break;
325-
}
326335
var line = _history[newHistoryIndex]._line;
327336
int index;
328337
if (!_hashedHistory.TryGetValue(line, out index))
329338
{
330339
_hashedHistory.Add(line, newHistoryIndex);
331-
break;
340+
--count;
332341
}
333-
if (index == newHistoryIndex)
342+
else if (newHistoryIndex == index)
334343
{
335-
break;
344+
--count;
336345
}
337346
}
338-
}
339-
else
340-
{
341-
newHistoryIndex = _currentHistoryIndex + direction;
347+
else
348+
{
349+
--count;
350+
}
342351
}
343352
_recallHistoryCommandCount += 1;
344353
if (newHistoryIndex >= 0 && newHistoryIndex <= _history.Count)
@@ -378,6 +387,14 @@ public static void NextHistory(ConsoleKeyInfo? key = null, object arg = null)
378387

379388
private void HistorySearch(int direction)
380389
{
390+
if (_current == 0)
391+
{
392+
// If we aren't actually searching, use HistoryRecall
393+
// because it ignores command lines from other running sessions.
394+
HistoryRecall(direction);
395+
return;
396+
}
397+
381398
if (_searchHistoryCommandCount == 0)
382399
{
383400
if (LineIsMultiLine())
@@ -396,28 +413,45 @@ private void HistorySearch(int direction)
396413
}
397414
_searchHistoryCommandCount += 1;
398415

399-
for (int i = _currentHistoryIndex + direction; i >= 0 && i <= _history.Count; i += direction)
416+
int count = Math.Abs(direction);
417+
direction = direction < 0 ? -1 : +1;
418+
int newHistoryIndex = _currentHistoryIndex;
419+
while (count > 0)
400420
{
401-
var line = i == _history.Count ? _savedCurrentLine._line : _history[i]._line;
421+
newHistoryIndex += direction;
422+
if (newHistoryIndex < 0 || newHistoryIndex >= _history.Count)
423+
{
424+
break;
425+
}
426+
427+
var line = newHistoryIndex == _history.Count ? _savedCurrentLine._line : _history[newHistoryIndex]._line;
402428
if (line.StartsWith(_searchHistoryPrefix, Options.HistoryStringComparison))
403429
{
404430
if (Options.HistoryNoDuplicates)
405431
{
406432
int index;
407433
if (!_hashedHistory.TryGetValue(line, out index))
408434
{
409-
_hashedHistory.Add(line, i);
435+
_hashedHistory.Add(line, newHistoryIndex);
436+
--count;
410437
}
411-
else if (index != i)
438+
else if (index == newHistoryIndex)
412439
{
413-
continue;
440+
--count;
414441
}
415442
}
416-
_currentHistoryIndex = i;
417-
UpdateFromHistory(moveCursor: true);
418-
break;
443+
else
444+
{
445+
--count;
446+
}
419447
}
420448
}
449+
450+
if (newHistoryIndex >= 0 && newHistoryIndex <= _history.Count)
451+
{
452+
_currentHistoryIndex = newHistoryIndex;
453+
UpdateFromHistory(moveCursor: true);
454+
}
421455
}
422456

423457
/// <summary>

PSReadLine/ReadLine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ private string InputLoop()
325325
ProcessOneKey(key, _dispatchTable, ignoreIfNoAction: false, arg: null);
326326
if (_inputAccepted)
327327
{
328-
return MaybeAddToHistory(_buffer.ToString(), _edits, _undoEditIndex, readingHistoryFile: false);
328+
return MaybeAddToHistory(_buffer.ToString(), _edits, _undoEditIndex, readingHistoryFile: false, fromDifferentSession: false);
329329
}
330330

331331
if (killCommandCount == _killCommandCount)

0 commit comments

Comments
 (0)