feat: improve editor interactions
- add editor history, word navigation, and undo redo - preserve overlay cursor focus when editor is open - demonstrate editor shortcuts in Example
This commit is contained in:
+31
-4
@@ -18,6 +18,7 @@ using var runtime = new TuiRuntime(terminalInput, parser, renderer);
|
||||
var done = new ManualResetEventSlim();
|
||||
var eventsText = new Text("最近事件:\n- 无");
|
||||
var statusText = new Text();
|
||||
var editorHistory = new List<string> { "history: first command", "history: second command" };
|
||||
var loader = new Loader(textMeasurer) { Message = "运行中" };
|
||||
using var loaderCancellation = new CancellationTokenSource();
|
||||
var input = new TinyTUI.Components.Input(textMeasurer) { Prompt = "请输入: " };
|
||||
@@ -62,7 +63,7 @@ input.OnSubmitted = value =>
|
||||
case "/edit":
|
||||
AddEvent(eventsText, "Overlay: editor opened");
|
||||
runtime.ShowOverlay(
|
||||
new EditorOverlay(runtime, message => AddEvent(eventsText, message), textMeasurer),
|
||||
new EditorOverlay(runtime, editorHistory, message => AddEvent(eventsText, message), textMeasurer),
|
||||
new OverlayOptions
|
||||
{
|
||||
Width = OverlaySize.Percent(70),
|
||||
@@ -247,21 +248,40 @@ file sealed class SelectOverlay : IInputComponent
|
||||
file sealed class EditorOverlay : IInputComponent
|
||||
{
|
||||
private readonly ITuiRuntime _runtime;
|
||||
private readonly List<string> _history;
|
||||
private readonly Action<string> _addEvent;
|
||||
private readonly Editor _editor;
|
||||
private readonly Box _box;
|
||||
|
||||
public EditorOverlay(ITuiRuntime runtime, Action<string> addEvent, ITextMeasurer textMeasurer)
|
||||
public EditorOverlay(ITuiRuntime runtime, List<string> history, Action<string> addEvent, ITextMeasurer textMeasurer)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_history = history;
|
||||
_addEvent = addEvent;
|
||||
_editor = new Editor(textMeasurer)
|
||||
{
|
||||
Height = 6,
|
||||
Value = "这里可以输入多行文本\nEnter 换行 Esc 提交并关闭",
|
||||
Placeholder = "在这里输入内容",
|
||||
OnCanceled = SubmitAndClose,
|
||||
};
|
||||
_box = new Box(_editor, textMeasurer) { Title = "Editor" };
|
||||
_editor.SetHistory(_history);
|
||||
_box = new Box(
|
||||
new Container
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Text(
|
||||
"Ctrl+A/E 行首行尾 Ctrl+Left/Right 按词移动\n" +
|
||||
"Ctrl+Backspace/Delete 按词删除 Ctrl+Z/Y 撤销重做\n" +
|
||||
"空内容时 Up/Down 浏览历史 Esc 提交并关闭"),
|
||||
new Text(),
|
||||
_editor,
|
||||
},
|
||||
},
|
||||
textMeasurer)
|
||||
{
|
||||
Title = "Editor",
|
||||
};
|
||||
}
|
||||
|
||||
public IReadOnlyList<string> Render(int width) => _box.Render(width);
|
||||
@@ -279,6 +299,13 @@ file sealed class EditorOverlay : IInputComponent
|
||||
|
||||
private void SubmitAndClose()
|
||||
{
|
||||
var value = _editor.Value.Trim();
|
||||
if (value.Length > 0)
|
||||
{
|
||||
_history.Remove(value);
|
||||
_history.Insert(0, value);
|
||||
}
|
||||
|
||||
_addEvent($"Edited {Math.Max(1, _editor.Value.Split('\n').Length)} line(s)");
|
||||
_runtime.HideOverlay();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user