From 4df8f279eaf271607737ad3a84d403a9a4a04361 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Mon, 6 Jul 2026 18:54:38 -0700 Subject: [PATCH] =?UTF-8?q?shellhtml:=20close=20the=20two=20focus=20seams?= =?UTF-8?q?=20=E2=80=94=20bios=20skips=20soft-keyboard=20open=20at=20the?= =?UTF-8?q?=20prompt=20(host=20bar=20owns=20typing);=20shell=20reclaims=20?= =?UTF-8?q?focus=20when=20the=20iframe=20steals=20it=20on=20the=20prompt?= =?UTF-8?q?=20canvas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- papers/ac-paper-layout.sty | 41 +++++++++++++++++++ papers/arxiv-sampling/sampling.tex | 35 +++++++++++++++- .../url-tradition-cards.tex | 35 +++++++++++++++- papers/arxiv-url-tradition/url-tradition.tex | 35 +++++++++++++++- papers/cli.mjs | 16 ++++++++ system/public/aesthetic.computer/bios.mjs | 6 +++ system/public/prompt.ac/index.html | 9 ++++ 7 files changed, 174 insertions(+), 3 deletions(-) diff --git a/papers/ac-paper-layout.sty b/papers/ac-paper-layout.sty index 9f302a4ddb..108a2704c1 100644 --- a/papers/ac-paper-layout.sty +++ b/papers/ac-paper-layout.sty @@ -117,4 +117,45 @@ \newcommand{\ac}{\textsc{Aesthetic Computer}} \newcommand{\acdot}{{\color{acpink}.}} +% === BREAKABLE CODE (\code) === +% \code{...} sets its argument in \ttfamily and lets long identifiers, paths, +% env-var names, op:// refs, and tokens WRAP instead of overflowing the measure +% (in body text and inside tabularx/p{} cells alike) — so nothing breaks the +% columnar arrangement. It breaks after the separators _ / . : - @ (preferred, +% zero cost) and, only when a separator break would still overflow, between any +% two characters (last resort, high penalty) so even a separator-less blob +% wraps. The argument is re-tokenized wholesale (\scantokens) under active +% separators rather than scanned token-by-token, so \char-based content +% survives, e.g. \code{\char`\~/.hermes/config.yaml} keeps its ~, and \#, \$ +% escapes render as usual. Gate any paper with tools/check-columns.mjs. +\newcommand{\codebreak}{\discretionary{}{}{}} % zero-cost break at separators +\newcommand{\codesoftbreak}{\penalty9999\relax} % last-resort break in long runs +\begingroup + \catcode`\_=12 \catcode`\/=12 \catcode`\.=12 + \catcode`\:=12 \catcode`\-=12 \catcode`\@=12 + \gdef\codeUS{_}\gdef\codeSL{/}\gdef\codeDT{.}% + \gdef\codeCL{:}\gdef\codeDS{-}\gdef\codeAT{@}% +\endgroup +\begingroup + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \gdef\codeActivate{% + \def_{\codeUS\codebreak}\def/{\codeSL\codebreak}\def.{\codeDT\codebreak}% + \def:{\codeCL\codebreak}\def-{\codeDS\codebreak}\def@{\codeAT\codebreak}% + \def\_{\codeUS\codebreak}}% underscores usually arrive as the \_ macro +\endgroup +\newcommand{\code}[1]{% + \begingroup + \ttfamily + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \codeActivate + \ifdefined\XeTeXinterchartokenstate + \XeTeXinterchartokenstate=1 + \XeTeXinterchartoks 0 0 = {\codesoftbreak}% + \fi + \endlinechar=-1 \everyeof{}% + \scantokens{#1}% + \endgroup} + \endinput diff --git a/papers/arxiv-sampling/sampling.tex b/papers/arxiv-sampling/sampling.tex index 59e4a23b0b..973c325133 100644 --- a/papers/arxiv-sampling/sampling.tex +++ b/papers/arxiv-sampling/sampling.tex @@ -130,7 +130,40 @@ % === CUSTOM COMMANDS === \newcommand{\ac}{Aesthetic Computer} \newcommand{\acos}{AC~Native~OS} -\newcommand{\code}[1]{\texttt{#1}} +% \code sets its argument in \ttfamily and lets long identifiers/paths/refs +% wrap instead of overflowing the column: it breaks after _ / . : - @ (zero +% cost) and, only when forced, between any two chars (last resort), so nothing +% breaks the columnar arrangement. \char / \# / \$ escapes survive because the +% argument is re-tokenized (\scantokens) under active separators. +\newcommand{\codebreak}{\discretionary{}{}{}} +\newcommand{\codesoftbreak}{\penalty9999\relax} +\begingroup + \catcode`\_=12 \catcode`\/=12 \catcode`\.=12 + \catcode`\:=12 \catcode`\-=12 \catcode`\@=12 + \gdef\codeUS{_}\gdef\codeSL{/}\gdef\codeDT{.}% + \gdef\codeCL{:}\gdef\codeDS{-}\gdef\codeAT{@}% +\endgroup +\begingroup + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \gdef\codeActivate{% + \def_{\codeUS\codebreak}\def/{\codeSL\codebreak}\def.{\codeDT\codebreak}% + \def:{\codeCL\codebreak}\def-{\codeDS\codebreak}\def@{\codeAT\codebreak}% + \def\_{\codeUS\codebreak}}% +\endgroup +\newcommand{\code}[1]{% + \begingroup + \ttfamily + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \codeActivate + \ifdefined\XeTeXinterchartokenstate + \XeTeXinterchartokenstate=1 + \XeTeXinterchartoks 0 0 = {\codesoftbreak}% + \fi + \endlinechar=-1 \everyeof{}% + \scantokens{#1}% + \endgroup} \begin{document} diff --git a/papers/arxiv-url-tradition/url-tradition-cards.tex b/papers/arxiv-url-tradition/url-tradition-cards.tex index e89a5ccef7..c4d48ffc63 100644 --- a/papers/arxiv-url-tradition/url-tradition-cards.tex +++ b/papers/arxiv-url-tradition/url-tradition-cards.tex @@ -69,7 +69,40 @@ \usepackage{ac-paper-cards} % Extra commands from base paper -\newcommand{\code}[1]{\texttt{#1}} +% \code sets its argument in \ttfamily and lets long identifiers/paths/refs +% wrap instead of overflowing the column: it breaks after _ / . : - @ (zero +% cost) and, only when forced, between any two chars (last resort), so nothing +% breaks the columnar arrangement. \char / \# / \$ escapes survive because the +% argument is re-tokenized (\scantokens) under active separators. +\newcommand{\codebreak}{\discretionary{}{}{}} +\newcommand{\codesoftbreak}{\penalty9999\relax} +\begingroup + \catcode`\_=12 \catcode`\/=12 \catcode`\.=12 + \catcode`\:=12 \catcode`\-=12 \catcode`\@=12 + \gdef\codeUS{_}\gdef\codeSL{/}\gdef\codeDT{.}% + \gdef\codeCL{:}\gdef\codeDS{-}\gdef\codeAT{@}% +\endgroup +\begingroup + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \gdef\codeActivate{% + \def_{\codeUS\codebreak}\def/{\codeSL\codebreak}\def.{\codeDT\codebreak}% + \def:{\codeCL\codebreak}\def-{\codeDS\codebreak}\def@{\codeAT\codebreak}% + \def\_{\codeUS\codebreak}}% +\endgroup +\newcommand{\code}[1]{% + \begingroup + \ttfamily + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \codeActivate + \ifdefined\XeTeXinterchartokenstate + \XeTeXinterchartokenstate=1 + \XeTeXinterchartoks 0 0 = {\codesoftbreak}% + \fi + \endlinechar=-1 \everyeof{}% + \scantokens{#1}% + \endgroup} \definecolor{jskw}{RGB}{119,51,170} \definecolor{jsfn}{RGB}{0,136,170} \definecolor{jsstr}{RGB}{170,120,0} diff --git a/papers/arxiv-url-tradition/url-tradition.tex b/papers/arxiv-url-tradition/url-tradition.tex index aa232e81e1..9e1082ca2f 100644 --- a/papers/arxiv-url-tradition/url-tradition.tex +++ b/papers/arxiv-url-tradition/url-tradition.tex @@ -115,7 +115,40 @@ % === CUSTOM COMMANDS === \newcommand{\acdot}{{\color{acpink}.}} \newcommand{\ac}{\textsc{Aesthetic.Computer}} -\newcommand{\code}[1]{\texttt{#1}} +% \code sets its argument in \ttfamily and lets long identifiers/paths/refs +% wrap instead of overflowing the column: it breaks after _ / . : - @ (zero +% cost) and, only when forced, between any two chars (last resort), so nothing +% breaks the columnar arrangement. \char / \# / \$ escapes survive because the +% argument is re-tokenized (\scantokens) under active separators. +\newcommand{\codebreak}{\discretionary{}{}{}} +\newcommand{\codesoftbreak}{\penalty9999\relax} +\begingroup + \catcode`\_=12 \catcode`\/=12 \catcode`\.=12 + \catcode`\:=12 \catcode`\-=12 \catcode`\@=12 + \gdef\codeUS{_}\gdef\codeSL{/}\gdef\codeDT{.}% + \gdef\codeCL{:}\gdef\codeDS{-}\gdef\codeAT{@}% +\endgroup +\begingroup + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \gdef\codeActivate{% + \def_{\codeUS\codebreak}\def/{\codeSL\codebreak}\def.{\codeDT\codebreak}% + \def:{\codeCL\codebreak}\def-{\codeDS\codebreak}\def@{\codeAT\codebreak}% + \def\_{\codeUS\codebreak}}% +\endgroup +\newcommand{\code}[1]{% + \begingroup + \ttfamily + \catcode`\_=\active \catcode`\/=\active \catcode`\.=\active + \catcode`\:=\active \catcode`\-=\active \catcode`\@=\active + \codeActivate + \ifdefined\XeTeXinterchartokenstate + \XeTeXinterchartokenstate=1 + \XeTeXinterchartoks 0 0 = {\codesoftbreak}% + \fi + \endlinechar=-1 \everyeof{}% + \scantokens{#1}% + \endgroup} % Random caps for Aesthetic.Computer branding \newcount\acrandtmp diff --git a/papers/cli.mjs b/papers/cli.mjs index ade87a4ab6..63f330c17e 100755 --- a/papers/cli.mjs +++ b/papers/cli.mjs @@ -1708,6 +1708,20 @@ if (cmd === "status" || !cmd) { } updateIndex(indexEntries); console.log("\nDone.\n"); +} else if (cmd === "check") { + // Column-overflow gate: fail loudly if any paper spills past its measure + // (long code identifiers/paths/tokens breaking the columnar arrangement). + // Reads each paper's xelatex .log; pass --build to regenerate first. + const checker = join(PAPERS_DIR, "tools", "check-columns.mjs"); + const passthru = args.filter((a) => a !== "check"); + try { + execSync( + `node "${checker}" ${passthru.map((a) => `"${a}"`).join(" ")}`.trim(), + { stdio: "inherit" }, + ); + } catch { + process.exit(1); + } } else if (cmd === "verify") { console.log("\n=== VERIFY: checking all linked PDFs ===\n"); const allOk = verify(); @@ -1730,6 +1744,8 @@ Usage: node papers/cli.mjs publish --force Full rebuild + deploy + update index + verify node papers/cli.mjs status Show build status for all papers node papers/cli.mjs verify Check all linked PDFs exist + node papers/cli.mjs check [dirs] Column-overflow gate (Overfull \\hbox); fails loudly + node papers/cli.mjs check --build Rebuild first, then gate on column overflow node papers/cli.mjs log Show build log Builds are incremental by default — only papers with source files newer than diff --git a/system/public/aesthetic.computer/bios.mjs b/system/public/aesthetic.computer/bios.mjs index 7a7d3a4d6c..fb66b33f89 100644 --- a/system/public/aesthetic.computer/bios.mjs +++ b/system/public/aesthetic.computer/bios.mjs @@ -13547,6 +13547,12 @@ async function boot(parsed, bpm = 60, resolution, debug) { } if (type === "keyboard:open") { + // 🐚 shellhtml: at the prompt the host page's DOM bar is the text + // surface — never summon the soft keyboard over the buffer there. + if (preservedParams?.shellhtml && currentPiece?.endsWith("/prompt")) { + console.log("⌨️🐚 [bios keyboard:open handler] shellhtml prompt — host bar owns typing, skipping"); + return; + } console.log("⌨️🟢 [bios keyboard:open handler] calling keyboard.input.focus()"); if (keyboardFocusLock) return; keyboardFocusLock = false; diff --git a/system/public/prompt.ac/index.html b/system/public/prompt.ac/index.html index 03739f6958..e78710bfa8 100644 --- a/system/public/prompt.ac/index.html +++ b/system/public/prompt.ac/index.html @@ -163,6 +163,15 @@ function recall(dir) { $cmd.setSelectionRange($cmd.value.length, $cmd.value.length); } +// While on the prompt, the bar owns typing — if the iframe steals focus +// (a canvas click), hand it straight back so keystrokes never vanish into +// the runtime. Pieces keep iframe focus; this only guards the prompt. +window.addEventListener("blur", () => { + if ($here.textContent === "prompt" && document.activeElement === document.getElementById("ac")) { + setTimeout(() => $cmd.focus(), 0); + } +}); + // A press of "/" or just typing anywhere refocuses the command bar. window.addEventListener("keydown", (e) => { if (document.activeElement === $cmd) return; -- 2.51.2