Merge pull request #522 from opticon454/fix/newline-sequence-capability

feat(terminal): newline chord as registry data, plus a Key tester in Settings

# Conflicts:
#	config/test-suites.ts
This commit is contained in:
Codeman maintainer
2026-10-04 23:24:00 +02:00
13 changed files with 288 additions and 12 deletions
+6
View File
@@ -1242,6 +1242,12 @@ class CodemanApp {
// Use capture to handle before terminal
document.addEventListener('keydown', (e) => {
// A field that exists to show what a key does (Settings → Key tester, `data-raw-keys`) must
// receive every chord untouched. Without this, probing Ctrl+W killed the active session,
// Ctrl+L cleared the terminal and Escape closed Settings: this listener runs in the capture
// phase, before the field's own handler. Must stay the first statement.
if (e.target?.closest?.('[data-raw-keys]')) return;
// Don't intercept keys during CJK IME composition
if (e.isComposing || e.keyCode === 229) return;
+16
View File
@@ -1822,6 +1822,22 @@
</div>
</div>
</div>
<div class="set-group">
<div class="set-group-head"><h4>Key tester</h4><span class="set-scope">device</span></div>
<div class="set-group-body">
<div class="set-row has-field" data-search="key tester keyboard shift enter newline diagnose keydown keypress">
<div class="set-row-text">
<span class="set-row-label">Key tester</span>
<span class="set-row-desc">Click the box and press keys to see what this browser reports (key, code, modifiers) for keydown, keypress and keyup. Useful when a shortcut such as Shift+Enter behaves differently on one device. Nothing is sent to a session.</span>
</div>
<input type="text" id="keyTesterInput" class="set-input" data-raw-keys readonly autocomplete="off" spellcheck="false"
placeholder="Click here, then press keys"
onkeydown="app.keyTesterEvent(event)" onkeypress="app.keyTesterEvent(event)" onkeyup="app.keyTesterEvent(event)">
</div>
<pre id="keyTesterLog" class="set-note mono" style="display:none;white-space:pre-wrap" data-i18n-skip></pre>
</div>
</div>
</section>
<!-- ══ Header &amp; Panels ═══════════════════════════════════════ -->
+21
View File
@@ -1114,6 +1114,27 @@ Object.assign(CodemanApp.prototype, {
this._updateCheck = null;
},
/**
* Settings → Terminal & Input → Key tester: prints what the browser reports for each key event.
* Read-only and local; it never reaches a session. keypress is shown on purpose: that event is
* why a Shift-only Enter used to submit (xterm drops Ctrl/Alt keypresses, not Shift ones).
*/
keyTesterEvent(ev) {
const log = document.getElementById('keyTesterLog');
if (!log) return;
// Never preventDefault on keydown: that suppresses the keypress this panel exists to show.
// The field is readonly, so nothing is typed into it either way.
const mods = ['ctrlKey', 'shiftKey', 'altKey', 'metaKey'].filter((m) => ev[m]).map((m) => m.replace('Key', ''));
const line =
`${ev.type.padEnd(8)} key=${JSON.stringify(ev.key)} code=${ev.code || '-'} ` +
`mods=${mods.join('+') || 'none'}` +
(ev.type === 'keypress' ? ` charCode=${ev.charCode}` : '') +
(ev.repeat ? ' (repeat)' : '');
const lines = (log.textContent ? log.textContent.split('\n') : []).concat(line);
log.textContent = lines.slice(-14).join('\n');
log.style.display = 'block';
},
_setUpdateResult(html) {
const el = this.$('updateResult');
if (el) { el.style.display = 'block'; el.innerHTML = html; }