mirror of
https://github.com/chaos-zhu/easynode.git
synced 2026-10-07 13:18:34 +08:00
feat: 编辑器快捷键
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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': '已断开',
|
||||
|
||||
Reference in New Issue
Block a user