pi-studio 0.9.61 → 0.9.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/client/studio-client.js +61 -1
- package/index.ts +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to `pi-studio` are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.63] — 2026-10-08
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- The cursor fix in 0.9.62 didn't reach Studio's own editor, so in Safari and other WebKit browsers such as Muxy and cmux the cursor could still drift away from the text after an edit let a word move back up a line. The re-layout now works in Studio's layout.
|
|
11
|
+
- After a macOS autocorrect, that re-layout could switch itself off until you moved to another line. Typing, an ordinary edit or leaving the editor now turns it back on, and the editor also re-lays out once whenever you pause typing.
|
|
12
|
+
|
|
13
|
+
## [0.9.62] — 2026-10-08
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- With syntax highlighting on, the cursor could end up several characters away from the text being typed, mostly in Safari and other WebKit browsers such as Muxy and cmux. It happened when an edit let a word move back up a line. The editor now re-lays out its text after each edit, so the cursor and text stay together. A line that is exactly full can still show a brief mismatch, which corrects itself on the next key.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- `Ctrl+Shift+H` toggles syntax highlighting without leaving the editor.
|
|
20
|
+
|
|
7
21
|
## [0.9.61] — 2026-09-30
|
|
8
22
|
|
|
9
23
|
### Fixed
|
package/client/studio-client.js
CHANGED
|
@@ -2587,6 +2587,7 @@
|
|
|
2587
2587
|
let pendingResponseScrollReset = false;
|
|
2588
2588
|
let editorMetaUpdateRaf = null;
|
|
2589
2589
|
let editorHighlightEnabled = false;
|
|
2590
|
+
let editorWrapCompositionActive = false;
|
|
2590
2591
|
let editorLanguage = "markdown";
|
|
2591
2592
|
let responseHighlightEnabled = false;
|
|
2592
2593
|
let completionSuggestionState = null;
|
|
@@ -17999,6 +18000,56 @@
|
|
|
17999
18000
|
return EXT_TO_LANG[ext] || "";
|
|
18000
18001
|
}
|
|
18001
18002
|
|
|
18003
|
+
function repairEditorTextareaWrap(event) {
|
|
18004
|
+
// A composition can start without a matching end (e.g. macOS autocorrect in WebKit);
|
|
18005
|
+
// an ordinary input event proves it is over, so a stale flag cannot disable the repair.
|
|
18006
|
+
if (event?.type === "input" && event.isComposing === false) editorWrapCompositionActive = false;
|
|
18007
|
+
if (!editorHighlightEnabled || editorView !== "markdown" || editorWrapCompositionActive || event?.isComposing) return false;
|
|
18008
|
+
// WebKit can keep the previous soft-wrap layout after a native edit,
|
|
18009
|
+
// while the rebuilt overlay has already moved a word onto its prior line.
|
|
18010
|
+
// Narrow the text by 1px for one forced layout, then restore it, without
|
|
18011
|
+
// replacing text or touching native undo/IME. Nudge the padding, not the
|
|
18012
|
+
// width: the editor is a flex item that grows back to full width, so a
|
|
18013
|
+
// width nudge never reached its text layout (checked in WebKit, 8 Oct).
|
|
18014
|
+
const style = sourceTextEl.style;
|
|
18015
|
+
const padding = style.getPropertyValue("padding-right");
|
|
18016
|
+
const priority = style.getPropertyPriority("padding-right");
|
|
18017
|
+
const computed = window.getComputedStyle(sourceTextEl).paddingRight || "0px";
|
|
18018
|
+
const top = sourceTextEl.scrollTop, left = sourceTextEl.scrollLeft;
|
|
18019
|
+
try {
|
|
18020
|
+
style.setProperty("padding-right", "calc(" + computed + " + 1px)", "important");
|
|
18021
|
+
void sourceTextEl.offsetWidth;
|
|
18022
|
+
} finally {
|
|
18023
|
+
if (padding) style.setProperty("padding-right", padding, priority);
|
|
18024
|
+
else style.removeProperty("padding-right");
|
|
18025
|
+
void sourceTextEl.offsetWidth;
|
|
18026
|
+
sourceTextEl.scrollTop = top; sourceTextEl.scrollLeft = left;
|
|
18027
|
+
}
|
|
18028
|
+
syncEditorHighlightScroll();
|
|
18029
|
+
return true;
|
|
18030
|
+
}
|
|
18031
|
+
|
|
18032
|
+
// Catch-all: lay the text out again once typing pauses, covering edits made
|
|
18033
|
+
// outside the ordinary input path (autocorrect, dictation, text replacement).
|
|
18034
|
+
let editorWrapPauseTimer = null;
|
|
18035
|
+
function scheduleEditorWrapPauseRepair() {
|
|
18036
|
+
if (editorWrapPauseTimer !== null) window.clearTimeout(editorWrapPauseTimer);
|
|
18037
|
+
editorWrapPauseTimer = window.setTimeout(() => { editorWrapPauseTimer = null; repairEditorTextareaWrap(); }, 300);
|
|
18038
|
+
}
|
|
18039
|
+
|
|
18040
|
+
function handleEditorHighlightShortcut(event) {
|
|
18041
|
+
if (!event || event.defaultPrevented || event.isComposing || editorWrapCompositionActive || event.target !== sourceTextEl
|
|
18042
|
+
|| editorView !== "markdown" || sourceTextEl.disabled || sourceTextEl.readOnly || studioModalBlocksDraftAction()
|
|
18043
|
+
|| !event.ctrlKey || !event.shiftKey || event.metaKey || event.altKey
|
|
18044
|
+
|| !(event.code === "KeyH" || String(event.key || "").toLowerCase() === "h")) return false;
|
|
18045
|
+
event.preventDefault(); event.stopPropagation();
|
|
18046
|
+
if (!event.repeat) {
|
|
18047
|
+
setEditorHighlightEnabled(!editorHighlightEnabled);
|
|
18048
|
+
repairEditorTextareaWrap();
|
|
18049
|
+
}
|
|
18050
|
+
return true;
|
|
18051
|
+
}
|
|
18052
|
+
|
|
18002
18053
|
function renderEditorHighlightNow() {
|
|
18003
18054
|
if (!sourceHighlightEl) return;
|
|
18004
18055
|
if (!editorHighlightEnabled || editorView !== "markdown") {
|
|
@@ -24943,9 +24994,18 @@
|
|
|
24943
24994
|
requestLatestResponse();
|
|
24944
24995
|
});
|
|
24945
24996
|
|
|
24997
|
+
sourceTextEl.addEventListener("keydown", event => { if (!event.isComposing && event.keyCode !== 229) editorWrapCompositionActive = false; });
|
|
24998
|
+
sourceTextEl.addEventListener("blur", () => { editorWrapCompositionActive = false; });
|
|
24946
24999
|
sourceTextEl.addEventListener("keydown", handleSourceTextTabKey);
|
|
25000
|
+
sourceTextEl.addEventListener("keydown", handleEditorHighlightShortcut);
|
|
25001
|
+
sourceTextEl.addEventListener("compositionstart", () => { editorWrapCompositionActive = true; });
|
|
25002
|
+
sourceTextEl.addEventListener("compositionend", () => {
|
|
25003
|
+
editorWrapCompositionActive = false;
|
|
25004
|
+
repairEditorTextareaWrap();
|
|
25005
|
+
});
|
|
24947
25006
|
|
|
24948
|
-
sourceTextEl.addEventListener("input",
|
|
25007
|
+
sourceTextEl.addEventListener("input", event => {
|
|
25008
|
+
repairEditorTextareaWrap(event); scheduleEditorWrapPauseRepair();
|
|
24949
25009
|
if (completionSuggestionState && sourceTextEl.value !== completionSuggestionState.baseText) {
|
|
24950
25010
|
hideCompletionSuggestion();
|
|
24951
25011
|
}
|
package/index.ts
CHANGED
|
@@ -12515,7 +12515,7 @@ ${cssVarsBlock}
|
|
|
12515
12515
|
<button id="showMeResponseBtn" type="button" hidden title="Explain the response displayed in the right pane using the smallest useful visual or structural representation.">Explain displayed response</button>
|
|
12516
12516
|
<button id="askAsideBtn" type="button" title="Open a separate side-question thread without adding it to the main Pi conversation.">Side question</button>
|
|
12517
12517
|
<button id="quizBtn" type="button" title="Open an active quiz for the current editor selection or document.">Quiz me</button>
|
|
12518
|
-
<select id="highlightSelect" class="studio-flat-select" aria-label="Editor syntax highlighting">
|
|
12518
|
+
<select id="highlightSelect" class="studio-flat-select" aria-label="Editor syntax highlighting" aria-keyshortcuts="Control+Shift+H">
|
|
12519
12519
|
<option value="off">Syntax highlight: Off</option>
|
|
12520
12520
|
<option value="bash">Syntax highlight: Bash</option>
|
|
12521
12521
|
<option value="c">Syntax highlight: C</option>
|
|
@@ -12806,6 +12806,7 @@ ${cssVarsBlock}
|
|
|
12806
12806
|
<div><dt>Tab</dt><dd>Insert a visible completion suggestion; otherwise indent selected editor text</dd></div>
|
|
12807
12807
|
<div><dt>Esc</dt><dd>Dismiss a visible completion suggestion, close overlays, exit pane focus, or stop an active request</dd></div>
|
|
12808
12808
|
<div><dt>Shift+Tab</dt><dd>Unindent selected editor text</dd></div>
|
|
12809
|
+
<div><dt>Ctrl+Shift+H</dt><dd>Toggle editor syntax highlighting</dd></div>
|
|
12809
12810
|
</dl>
|
|
12810
12811
|
</section>
|
|
12811
12812
|
<section class="shortcuts-group shortcuts-full-only">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-studio",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.63",
|
|
4
4
|
"description": "Two-pane browser workspace for pi with prompt/response editing, annotations, critiques, active quiz, prompt/response history, live previews, and tmux-backed REPL/literate REPL workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|