mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-11-06 00:15:06 +00:00
Merge branch 'feat/editor-ide' into ide/nav
This commit is contained in:
+17
-4
@@ -3252,15 +3252,28 @@ impl Tty7App {
|
||||
}
|
||||
});
|
||||
let cursor: Option<SharedString> = active.map(|f| {
|
||||
let pos = f.input.read(cx).cursor_position();
|
||||
t_fmt(
|
||||
let input = f.input.read(cx);
|
||||
let pos = input.cursor_position();
|
||||
let ln_col = t_fmt(
|
||||
L10nKey::EditorLnCol,
|
||||
&[
|
||||
("line", &(pos.line + 1).to_string()),
|
||||
("column", &(pos.character + 1).to_string()),
|
||||
],
|
||||
)
|
||||
.into()
|
||||
);
|
||||
// Multi-cursor: the position is the primary caret's, the count
|
||||
// says there are more.
|
||||
match input.selection_count() {
|
||||
1 => ln_col.into(),
|
||||
n => {
|
||||
let n = n.to_string();
|
||||
format!(
|
||||
"{ln_col} {}",
|
||||
t_fmt(L10nKey::EditorSelections, &[("n", &n)])
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
});
|
||||
let wrap: Option<bool> = active.map(|f| f.wrap);
|
||||
let is_markdown = active.is_some_and(|f| f.language() == "markdown");
|
||||
|
||||
@@ -1185,6 +1185,7 @@ pub fn translate_en(key: L10nKey) -> &'static str {
|
||||
L10nKey::EditorNoFileOpen => "No file open",
|
||||
L10nKey::EditorBackToTerminal => "Back to Terminal (Esc)",
|
||||
L10nKey::EditorLnCol => "Ln {line}, Col {column}",
|
||||
L10nKey::EditorSelections => "({n} selections)",
|
||||
L10nKey::EditorEdit => "Edit",
|
||||
L10nKey::EditorPreview => "Preview",
|
||||
L10nKey::EditorWrapOn => "Wrap: on",
|
||||
|
||||
@@ -1233,6 +1233,7 @@ pub fn translate_ja(key: L10nKey) -> Option<&'static str> {
|
||||
L10nKey::EditorNoFileOpen => "開かれているファイルはありません",
|
||||
L10nKey::EditorBackToTerminal => "ターミナルに戻る (Esc)",
|
||||
L10nKey::EditorLnCol => "行 {line}, 列 {column}",
|
||||
L10nKey::EditorSelections => "({n} 個の選択範囲)",
|
||||
L10nKey::EditorEdit => "編集",
|
||||
L10nKey::EditorPreview => "プレビュー",
|
||||
L10nKey::EditorWrapOn => "折り返し: オン",
|
||||
|
||||
@@ -921,6 +921,7 @@ l10n_keys! {
|
||||
EditorNoFileOpen,
|
||||
EditorBackToTerminal,
|
||||
EditorLnCol,
|
||||
EditorSelections,
|
||||
EditorEdit,
|
||||
EditorPreview,
|
||||
EditorWrapOn,
|
||||
|
||||
@@ -1105,6 +1105,7 @@ pub fn translate_zh(key: L10nKey) -> Option<&'static str> {
|
||||
L10nKey::EditorNoFileOpen => "没有打开的文件",
|
||||
L10nKey::EditorBackToTerminal => "返回终端 (Esc)",
|
||||
L10nKey::EditorLnCol => "行 {line},列 {column}",
|
||||
L10nKey::EditorSelections => "({n} 个选区)",
|
||||
L10nKey::EditorEdit => "编辑",
|
||||
L10nKey::EditorPreview => "预览",
|
||||
L10nKey::EditorWrapOn => "自动换行:开",
|
||||
|
||||
@@ -70,6 +70,28 @@ fn fixed_bindings() -> Vec<KeyBinding> {
|
||||
let search = Some(crate::ui::search::KEY_CONTEXT);
|
||||
bindings.push(KeyBinding::new("tab", SearchNextTab, search));
|
||||
bindings.push(KeyBinding::new("shift-tab", SearchPrevTab, search));
|
||||
// The code editor's multi-cursor chords, laid down again after tty7's
|
||||
// own table. gpui ranks a context-free binding as deep as the focused
|
||||
// context, and breaks the tie by whichever was added last — so the copies
|
||||
// gpui-component installs lose ⌘D to `SplitRight` and ⌘⌥↑/↓ to
|
||||
// `FocusPaneUp`/`Down`, whose handlers sit on the workspace root and take
|
||||
// the key before the editor is asked. Re-added here they win inside an
|
||||
// `Input`; only the code editor handles them, so in any other text field
|
||||
// gpui falls through to the pane binding next in line.
|
||||
{
|
||||
use gpui_component::input::{
|
||||
AddCursorAbove, AddCursorBelow, SelectAllOccurrences, SelectNextOccurrence,
|
||||
};
|
||||
let input = Some("Input");
|
||||
bindings.push(KeyBinding::new("secondary-d", SelectNextOccurrence, input));
|
||||
bindings.push(KeyBinding::new(
|
||||
"secondary-shift-l",
|
||||
SelectAllOccurrences,
|
||||
input,
|
||||
));
|
||||
bindings.push(KeyBinding::new("secondary-alt-up", AddCursorAbove, input));
|
||||
bindings.push(KeyBinding::new("secondary-alt-down", AddCursorBelow, input));
|
||||
}
|
||||
bindings
|
||||
}
|
||||
|
||||
@@ -2878,4 +2900,52 @@ mod gpui_tests {
|
||||
assert_eq!(backspace(cx), inherited, "nor may a rebind");
|
||||
});
|
||||
}
|
||||
|
||||
/// The code editor's multi-cursor chords sit on keys tty7 ships for panes
|
||||
/// (⌘D split, ⌘⌥↑/↓ focus). `fixed_bindings` re-adds them after the
|
||||
/// pane table so they rank first inside an `Input`; any other text field
|
||||
/// has no handler for them, and gpui falls through to the pane binding
|
||||
/// listed after. A terminal never sees them.
|
||||
#[gpui::test]
|
||||
fn editor_multi_cursor_chords_outrank_the_pane_bindings(cx: &mut TestAppContext) {
|
||||
use gpui::Action as _;
|
||||
use gpui_component::input::{
|
||||
AddCursorAbove, AddCursorBelow, SelectAllOccurrences, SelectNextOccurrence,
|
||||
};
|
||||
cx.update(|cx| {
|
||||
running_on_json(cx, "{}");
|
||||
let in_input = |keys: &str| -> Vec<&'static str> {
|
||||
let input = [Keystroke::parse(keys).expect("the keystroke parses")];
|
||||
let context = [
|
||||
gpui::KeyContext::parse("Workspace").expect("the context parses"),
|
||||
gpui::KeyContext::parse("Input").expect("the context parses"),
|
||||
];
|
||||
cx.key_bindings()
|
||||
.borrow()
|
||||
.bindings_for_input(&input, &context)
|
||||
.0
|
||||
.iter()
|
||||
.map(|b| b.action().name())
|
||||
.collect()
|
||||
};
|
||||
let cases = [
|
||||
("secondary-d", SelectNextOccurrence::name_for_type()),
|
||||
("secondary-shift-l", SelectAllOccurrences::name_for_type()),
|
||||
("secondary-alt-up", AddCursorAbove::name_for_type()),
|
||||
("secondary-alt-down", AddCursorBelow::name_for_type()),
|
||||
];
|
||||
for (keys, editor_action) in cases {
|
||||
let hits = in_input(keys);
|
||||
assert_eq!(hits.first(), Some(&editor_action), "{keys} in the editor");
|
||||
}
|
||||
if cfg!(target_os = "macos") {
|
||||
assert!(in_input("secondary-d").contains(&SplitRight::name_for_type()));
|
||||
assert_eq!(
|
||||
fired(cx, "secondary-d").first(),
|
||||
Some(&SplitRight::name_for_type()),
|
||||
"a terminal still splits on ⌘D"
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user