diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-22 01:43:35 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-22 01:43:35 +0000 |
| commit | 427acc420c6fce10fa77e603f7696f3e89d342d6 (patch) | |
| tree | df87f81f0b0ece4a64a46a6e07fae592bfb47940 /bundle | |
| parent | 899c2af576124df2918fd2ae976434df0ebbae5b (diff) | |
feat(bundle): add platform-adaptive file, find and comment shortcuts
New, Open, Save and Find are Monaco KeyMod.CtrlCmd bindings matched
with StandardKeyboardEvent, so they use Cmd on macOS and Ctrl on Windows
and Linux, exactly like the editor's own keybindings. Find also works
from Input and Output by focusing the editor first. Toggle Line Comment
comes from Monaco's comment contribution and the plugin's "//"
lineComment. This replaces the Save handler that accepted Ctrl or Cmd
with any other modifiers on every platform.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bundle')
| -rw-r--r-- | bundle/AGENTS/DEVELOPMENT.md | 2 | ||||
| -rw-r--r-- | bundle/README.md | 2 | ||||
| -rw-r--r-- | bundle/src/editor.js | 1 | ||||
| -rw-r--r-- | bundle/src/main.js | 60 |
4 files changed, 42 insertions, 23 deletions
diff --git a/bundle/AGENTS/DEVELOPMENT.md b/bundle/AGENTS/DEVELOPMENT.md index 940a0dd..f87f0c0 100644 --- a/bundle/AGENTS/DEVELOPMENT.md +++ b/bundle/AGENTS/DEVELOPMENT.md @@ -30,4 +30,6 @@ The Rust runner launches the packaged compiler directly, using the source direct After building the compiler, run `cargo test --release --manifest-path src-tauri/Cargo.toml`. The two native tests exercise real compilation, prefilled input, EOF, Unicode, diagnostics, output before process exit, stopping, single-run exclusion and restart, including source paths with spaces. CI runs them on all three native platforms. +Keyboard shortcuts are Monaco `KeyMod.CtrlCmd` keybindings: the editor registers Find and Toggle Line Comment, and the document handler matches New, Open, Save and Find with `StandardKeyboardEvent.equals`. Never test `ctrlKey`/`metaKey` directly; Monaco resolves CtrlCmd to Cmd on macOS and Ctrl elsewhere. + Use brief English UI labels and messages. Keep the first version to one document and prefilled stdin. Before feature commits, run affected plugin tests, build the frontend and check native compilation as appropriate. Do not add a separate UI test framework for routine changes. diff --git a/bundle/README.md b/bundle/README.md index 3e08ddc..6ef2bcc 100644 --- a/bundle/README.md +++ b/bundle/README.md @@ -2,6 +2,8 @@ Open a `.cps` file, enter its input in **Input**, and click **Run**. The file is saved before running. Program output and errors appear in **Output**. Click **Stop** to end a running program. +Shortcuts use Cmd on macOS and Ctrl on Windows: **N** new, **O** open, **S** save, **F** find, **/** toggle line comment. + Nightly provides a standalone Windows x64 `.exe` and a macOS Apple Silicon `.tar.xz` containing the `.app`. Windows extracts the included `cpsc.exe` into the current working directory on startup; macOS keeps it inside the `.app`. Windows uses the system WebView2 runtime. For development and build instructions, see [AGENTS/DEVELOPMENT.md](AGENTS/DEVELOPMENT.md). diff --git a/bundle/src/editor.js b/bundle/src/editor.js index adfc90c..853fa82 100644 --- a/bundle/src/editor.js +++ b/bundle/src/editor.js @@ -1,6 +1,7 @@ import * as monaco from 'monaco-editor/editor/editor.api.js'; import 'monaco-editor/editor/browser/coreCommands.js'; import 'monaco-editor/editor/contrib/clipboard/browser/clipboard.js'; +import 'monaco-editor/editor/contrib/comment/browser/comment.js'; import 'monaco-editor/editor/contrib/contextmenu/browser/contextmenu.js'; import 'monaco-editor/editor/contrib/format/browser/formatActions.js'; import 'monaco-editor/editor/contrib/bracketMatching/browser/bracketMatching.js'; diff --git a/bundle/src/main.js b/bundle/src/main.js index 56cbff6..b71ed27 100644 --- a/bundle/src/main.js +++ b/bundle/src/main.js @@ -1,6 +1,8 @@ import { invoke, Channel } from '@tauri-apps/api/core'; import { getCurrentWindow } from '@tauri-apps/api/window'; import { open, save, message } from '@tauri-apps/plugin-dialog'; +import { KeyCode, KeyMod } from 'monaco-editor/editor/editor.api.js'; +import { StandardKeyboardEvent } from 'monaco-editor/base/browser/keyboardEvent.js'; import { createEditor } from './editor.js'; import './style.css'; @@ -96,11 +98,37 @@ async function canReplace() { if (answer === 'Cancel') return false; return answer === 'Discard' || await saveFile(); } +async function newFile() { + if (!await canReplace()) return; + path = null; + savedText = ''; + editor.setValue(''); + refreshTitle(); + status.textContent = 'Ready'; +} +async function openFile() { + if (!await canReplace()) return; + const target = await open({ filters, multiple: false }); + if (!target) return; + const text = await invoke('read_file', { path: target }); + path = target; + savedText = text; + editor.setValue(text); + refreshTitle(); + status.textContent = 'Ready'; +} async function action(callback) { if (busy || running) return; busy = true; try { await callback(); } catch (error) { report(error); } finally { busy = false; } } +// CtrlCmd is Cmd on macOS and Ctrl elsewhere, matching Monaco's own keybindings. +const shortcuts = [ + [KeyMod.CtrlCmd | KeyCode.KeyN, () => action(newFile)], + [KeyMod.CtrlCmd | KeyCode.KeyO, () => action(openFile)], + [KeyMod.CtrlCmd | KeyCode.KeyS, () => action(saveFile)], + [KeyMod.CtrlCmd | KeyCode.KeyF, () => { editor.focus(); editor.getAction('actions.find').run(); }] +]; try { editor = await createEditor(document.querySelector('#editor')); @@ -113,30 +141,16 @@ try { } }; document.querySelector('#save').onclick = () => action(saveFile); - document.querySelector('#new').onclick = () => action(async () => { - if (!await canReplace()) return; - path = null; - savedText = ''; - editor.setValue(''); - refreshTitle(); - status.textContent = 'Ready'; - }); - document.querySelector('#open').onclick = () => action(async () => { - if (!await canReplace()) return; - const target = await open({ filters, multiple: false }); - if (!target) return; - const text = await invoke('read_file', { path: target }); - path = target; - savedText = text; - editor.setValue(text); - refreshTitle(); - status.textContent = 'Ready'; - }); + document.querySelector('#new').onclick = () => action(newFile); + document.querySelector('#open').onclick = () => action(openFile); document.addEventListener('keydown', event => { - if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') { - event.preventDefault(); - action(saveFile); - } + // Monaco already handled its own keybindings, such as Find inside the editor. + if (event.defaultPrevented) return; + const key = new StandardKeyboardEvent(event); + const shortcut = shortcuts.find(([binding]) => key.equals(binding)); + if (!shortcut) return; + event.preventDefault(); + shortcut[1](); }); await window.onCloseRequested(async event => { if (closing) return; |
