diff --git a/src/PowerShellRun/Application/SearchBar.cs b/src/PowerShellRun/Application/SearchBar.cs index 57575ab..95d155f 100644 --- a/src/PowerShellRun/Application/SearchBar.cs +++ b/src/PowerShellRun/Application/SearchBar.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; using System.Text; +using PowerShellRun.Dependency; internal class SearchBar { @@ -20,21 +21,6 @@ internal class SearchBar public bool IsCursorUpdated { get; set; } = false; public string DebugPerfString = ""; - public int CursorXInCanvas - { - get - { - return _cursorX + _textBox.X; - } - } - public int CursorYInCanvas - { - get - { - return _textBox.Y; - } - } - public SearchBar(string promptString) { var theme = SelectorOptionHolder.GetInstance().Option.Theme; @@ -71,6 +57,25 @@ public void SetQuery(string query) _isQuerySetFromOutside = true; } + public (int X, int Y) GetCursorPositionInCanvas() + { + int x = _textBox.X; + int y = _textBox.Y; + for (int i = 0; i < _cursorX; ++i) + { + if (i >= _readKeysBuffer.Length) + break; + + int displayWidth = Unicode.GetDisplayWidth(_readKeysBuffer[i]); + if (displayWidth <= 0) + continue; + + x += displayWidth; + } + + return (x, y); + } + public void Update() { ReadKeys(); @@ -102,14 +107,6 @@ public void Update() } } - private static Key[] _skipKeys = - { - Key.Enter, - Key.Escape, - Key.UpArrow, - Key.DownArrow, - Key.Tab, - }; private void ReadKeys() { IsQueryUpdated = false; @@ -123,18 +120,6 @@ private void ReadKeys() if (key.KeyCombination.Modifier.HasFlag(KeyModifier.Alt)) continue; - bool skip = false; - foreach (var skipKey in _skipKeys) - { - if (skipKey == key.KeyCombination.Key) - { - skip = true; - break; - } - } - if (skip) - continue; - if (key.KeyCombination.Key == Key.LeftArrow) { SetCursorX(_cursorX - 1); @@ -183,7 +168,7 @@ private void ReadKeys() continue; } - if (!Char.IsAscii(key.ConsoleKeyInfo.KeyChar)) + if (Unicode.GetDisplayWidth(key.ConsoleKeyInfo.KeyChar) <= 0) continue; if (_readKeysBuffer.Length >= Constants.QueryCharacterMaxCount) diff --git a/src/PowerShellRun/Application/Selector.cs b/src/PowerShellRun/Application/Selector.cs index 113b400..77bb65b 100644 --- a/src/PowerShellRun/Application/Selector.cs +++ b/src/PowerShellRun/Application/Selector.cs @@ -86,7 +86,8 @@ public static SelectorResult Open( break; } - canvas.SetCursorOffset(searchBar.CursorXInCanvas, searchBar.CursorYInCanvas); + var cursorPosInCanvas = searchBar.GetCursorPositionInCanvas(); + canvas.SetCursorOffset(cursorPosInCanvas.X, cursorPosInCanvas.Y); if (searchBar.IsQueryUpdated || resultWindow.IsUpdated) { canvas.ClearCells(); diff --git a/tests/Public/Invoke-PSRunSelector.Tests.ps1 b/tests/Public/Invoke-PSRunSelector.Tests.ps1 index 4039856..e4f0d41 100644 --- a/tests/Public/Invoke-PSRunSelector.Tests.ps1 +++ b/tests/Public/Invoke-PSRunSelector.Tests.ps1 @@ -53,6 +53,12 @@ $match | Should -Be 'abc' } + It 'should support non-ascii character query' { + $context.Query = '恂' + $match = 'abc', 'a恂' | Invoke-PSRunSelector -Option $option -Context $context + $match | Should -Be 'a恂' + } + It 'should not throw an exception with multi selection' { $match = 'a' | Invoke-PSRunSelector -Option $option -MultiSelection $match | Should -Be 'a'