feat: 编辑器快捷键

This commit is contained in:
chaoszhu
2026-06-13 13:08:53 +08:00
parent e07e5851f0
commit dd585fe012
3 changed files with 109 additions and 0 deletions
@@ -240,6 +240,7 @@ class _ShortcutKeyPanel extends StatelessWidget {
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
final ctrlNotifier = controller?.ctrlPending;
final l = AppLocalizations.of(context);
return Container(
color: colors.surfaceContainerHighest,
padding: const EdgeInsets.fromLTRB(4, 6, 4, 6),
@@ -271,6 +272,35 @@ class _ShortcutKeyPanel extends StatelessWidget {
_KeyBtn('PgDn', () => onInput('\x1b[6~')),
]),
const SizedBox(height: _kSectionGap),
// Common Ctrl combinations
_buildRow([
_HintKeyBtn('^C', () => onInput('\x03'), l.tr('terminal.hint.ctrlC')),
_HintKeyBtn('^Z', () => onInput('\x1a'), l.tr('terminal.hint.ctrlZ')),
_HintKeyBtn('^D', () => onInput('\x04'), l.tr('terminal.hint.ctrlD')),
_HintKeyBtn('^L', () => onInput('\x0c'), l.tr('terminal.hint.ctrlL')),
_HintKeyBtn('^U', () => onInput('\x15'), l.tr('terminal.hint.ctrlU')),
_HintKeyBtn('^K', () => onInput('\x0b'), l.tr('terminal.hint.ctrlK')),
]),
const SizedBox(height: _kRowGap),
_buildRow([
_HintKeyBtn('^A', () => onInput('\x01'), l.tr('terminal.hint.ctrlA')),
_HintKeyBtn('^E', () => onInput('\x05'), l.tr('terminal.hint.ctrlE')),
_HintKeyBtn('^W', () => onInput('\x17'), l.tr('terminal.hint.ctrlW')),
_HintKeyBtn('^Y', () => onInput('\x19'), l.tr('terminal.hint.ctrlY')),
_HintKeyBtn('^X', () => onInput('\x18'), l.tr('terminal.hint.ctrlX')),
_HintKeyBtn('^R', () => onInput('\x12'), l.tr('terminal.hint.ctrlR')),
]),
const SizedBox(height: _kRowGap),
// Vim shortcuts
_buildRow([
_HintKeyBtn(':w', () => onInput(':w\n'), l.tr('terminal.hint.vimW')),
_HintKeyBtn(':q', () => onInput(':q\n'), l.tr('terminal.hint.vimQ')),
_HintKeyBtn(':wq', () => onInput(':wq\n'), l.tr('terminal.hint.vimWQ')),
_HintKeyBtn(':q!', () => onInput(':q!\n'), l.tr('terminal.hint.vimQF')),
_HintKeyBtn('dd', () => onInput('dd'), l.tr('terminal.hint.vimDD')),
_HintKeyBtn('yy', () => onInput('yy'), l.tr('terminal.hint.vimYY')),
]),
const SizedBox(height: _kSectionGap),
// F1–F6
_buildRow([
_KeyBtn('F1', () => onInput('\x1bOP')),
@@ -356,6 +386,47 @@ class _KeyBtn extends StatelessWidget {
}
}
class _HintKeyBtn extends StatelessWidget {
const _HintKeyBtn(this.label, this.onTap, this.hint);
final String label;
final VoidCallback onTap;
final String hint;
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
return Material(
color: colors.surfaceContainer,
borderRadius: BorderRadius.circular(6),
child: InkWell(
borderRadius: BorderRadius.circular(6),
onTap: onTap,
onLongPress: () {
ScaffoldMessenger.of(context)
..clearSnackBars()
..showSnackBar(
SnackBar(
content: Text('$label $hint'),
duration: const Duration(seconds: 2),
behavior: SnackBarBehavior.floating,
),
);
},
child: SizedBox(
height: _kKeyHeight,
child: Center(
child: Text(
label,
style: _kKeyStyle.copyWith(color: colors.onSurface),
),
),
),
),
);
}
}
class _ToggleKeyBtn extends StatelessWidget {
const _ToggleKeyBtn(this.label, this.notifier, this.onTap);
+19
View File
@@ -489,6 +489,25 @@ const Map<String, String> stringsEn = {
'terminal.findNoResults': 'No results for: {0}',
'terminal.findResults': 'Find "{0}" ({1}/{2})',
'terminal.hint.ctrlC': 'Interrupt',
'terminal.hint.ctrlZ': 'Suspend',
'terminal.hint.ctrlD': 'Exit / EOF',
'terminal.hint.ctrlA': 'Line start',
'terminal.hint.ctrlE': 'Line end',
'terminal.hint.ctrlW': 'Del word / Save(nano)',
'terminal.hint.ctrlX': 'Exit(nano)',
'terminal.hint.ctrlL': 'Clear screen',
'terminal.hint.ctrlU': 'Del to line start',
'terminal.hint.ctrlK': 'Del to line end',
'terminal.hint.ctrlY': 'Paste deleted text',
'terminal.hint.ctrlR': 'Search / Read(nano)',
'terminal.hint.vimW': 'Save(vim)',
'terminal.hint.vimQ': 'Quit(vim)',
'terminal.hint.vimWQ': 'Save & quit(vim)',
'terminal.hint.vimQF': 'Force quit(vim)',
'terminal.hint.vimDD': 'Delete line(vim)',
'terminal.hint.vimYY': 'Copy line(vim)',
'terminal.status.connecting': 'Connecting',
'terminal.status.connected': 'Connected',
'terminal.status.disconnected': 'Disconnected',
+19
View File
@@ -462,6 +462,25 @@ const Map<String, String> stringsZh = {
'terminal.findNoResults': '未找到:{0}',
'terminal.findResults': '查找 “{0}” ({1}/{2})',
'terminal.hint.ctrlC': '中断进程',
'terminal.hint.ctrlZ': '挂起进程',
'terminal.hint.ctrlD': '退出 / EOF',
'terminal.hint.ctrlA': '跳转行首',
'terminal.hint.ctrlE': '跳转行尾',
'terminal.hint.ctrlW': '删词 / 保存(nano)',
'terminal.hint.ctrlX': '退出(nano)',
'terminal.hint.ctrlL': '清屏',
'terminal.hint.ctrlU': '删除到行首',
'terminal.hint.ctrlK': '删除到行尾',
'terminal.hint.ctrlY': '粘贴已删除文本',
'terminal.hint.ctrlR': '搜索 / 读取(nano)',
'terminal.hint.vimW': '保存(vim)',
'terminal.hint.vimQ': '退出(vim)',
'terminal.hint.vimWQ': '保存并退出(vim)',
'terminal.hint.vimQF': '强制退出(vim)',
'terminal.hint.vimDD': '删除行(vim)',
'terminal.hint.vimYY': '复制行(vim)',
'terminal.status.connecting': '正在连接',
'terminal.status.connected': '已连接',
'terminal.status.disconnected': '已断开',