pi-edit-session-in-place 0.1.15 → 0.1.16
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 +9 -0
- package/README.md +1 -1
- package/extensions/edit-session-in-place.ts +4 -174
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## [0.1.16] - 2026-06-04
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- fixed `Ctrl+Shift+E` after the Pi 0.78.1 update by removing the registered shortcut handler that consumed the key and only showed the placeholder notification
|
|
11
|
+
- added regression coverage that verifies the extension no longer registers a conflicting shortcut handler and still installs the custom editor hotkey path
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- removed the custom main-editor wrapper path and returned to the focused custom-editor hotkey path used by the working releases
|
|
15
|
+
|
|
7
16
|
## [0.1.15] - 2026-06-04
|
|
8
17
|
|
|
9
18
|
### Changed
|
package/README.md
CHANGED
|
@@ -81,7 +81,7 @@ If you clear the message and submit an empty value, the selected message is effe
|
|
|
81
81
|
- If the selected message contains images, the extension warns that re-editing or deleting it will drop the images and keep only text behavior
|
|
82
82
|
- The extension only offers text-bearing user messages for editing; image-only or whitespace-only user messages are skipped
|
|
83
83
|
- Queued messages must be cleared before using the command
|
|
84
|
-
-
|
|
84
|
+
- The `Ctrl+Shift+E` hotkey is handled by this extension's main-editor component so Pi's registered shortcut dispatcher does not consume it first
|
|
85
85
|
|
|
86
86
|
## Development
|
|
87
87
|
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
DynamicBorder,
|
|
16
16
|
keyHint,
|
|
17
17
|
rawKeyHint,
|
|
18
|
-
type AppKeybinding,
|
|
19
18
|
type ExtensionAPI,
|
|
20
19
|
type ExtensionCommandContext,
|
|
21
20
|
type KeybindingsManager,
|
|
@@ -30,8 +29,6 @@ import {
|
|
|
30
29
|
Spacer,
|
|
31
30
|
Text,
|
|
32
31
|
matchesKey,
|
|
33
|
-
type AutocompleteProvider,
|
|
34
|
-
type EditorComponent,
|
|
35
32
|
type EditorTheme,
|
|
36
33
|
type Focusable,
|
|
37
34
|
type TUI,
|
|
@@ -572,16 +569,12 @@ const handleEditTurn = async (ctx: ExtensionCommandContext) => {
|
|
|
572
569
|
);
|
|
573
570
|
};
|
|
574
571
|
|
|
575
|
-
const triggerEditTurnCommand = (editor: Pick<EditorComponent, "getText" | "setText" | "handleInput">) => {
|
|
576
|
-
draftBeforeHotkey = editor.getText();
|
|
577
|
-
editor.setText(COMMAND_TEXT);
|
|
578
|
-
editor.handleInput("\r");
|
|
579
|
-
};
|
|
580
|
-
|
|
581
572
|
class EditSessionInPlaceEditor extends CustomEditor {
|
|
582
573
|
handleInput(data: string): void {
|
|
583
574
|
if (matchesKey(data, HOTKEY)) {
|
|
584
|
-
|
|
575
|
+
draftBeforeHotkey = this.getText();
|
|
576
|
+
this.setText(COMMAND_TEXT);
|
|
577
|
+
super.handleInput("\r");
|
|
585
578
|
return;
|
|
586
579
|
}
|
|
587
580
|
|
|
@@ -589,152 +582,6 @@ class EditSessionInPlaceEditor extends CustomEditor {
|
|
|
589
582
|
}
|
|
590
583
|
}
|
|
591
584
|
|
|
592
|
-
type AutocompleteAwareEditor = EditorComponent & {
|
|
593
|
-
isShowingAutocomplete?: () => boolean;
|
|
594
|
-
};
|
|
595
|
-
|
|
596
|
-
class EditSessionInPlaceEditorWrapper implements EditorComponent, Focusable {
|
|
597
|
-
public actionHandlers: Map<AppKeybinding, () => void> = new Map();
|
|
598
|
-
public onEscape?: () => void;
|
|
599
|
-
public onCtrlD?: () => void;
|
|
600
|
-
public onPasteImage?: () => void;
|
|
601
|
-
public onExtensionShortcut?: (data: string) => boolean | undefined;
|
|
602
|
-
|
|
603
|
-
constructor(
|
|
604
|
-
private readonly base: EditorComponent,
|
|
605
|
-
private readonly keybindings: KeybindingsManager,
|
|
606
|
-
) {}
|
|
607
|
-
|
|
608
|
-
get focused(): boolean {
|
|
609
|
-
return "focused" in this.base && typeof this.base.focused === "boolean" ? this.base.focused : false;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
set focused(value: boolean) {
|
|
613
|
-
if ("focused" in this.base) {
|
|
614
|
-
(this.base as EditorComponent & Focusable).focused = value;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
get wantsKeyRelease(): boolean | undefined {
|
|
619
|
-
return this.base.wantsKeyRelease;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
set wantsKeyRelease(value: boolean | undefined) {
|
|
623
|
-
this.base.wantsKeyRelease = value;
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
get onSubmit(): ((text: string) => void) | undefined {
|
|
627
|
-
return this.base.onSubmit;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
set onSubmit(value: ((text: string) => void) | undefined) {
|
|
631
|
-
this.base.onSubmit = value;
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
get onChange(): ((text: string) => void) | undefined {
|
|
635
|
-
return this.base.onChange;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
set onChange(value: ((text: string) => void) | undefined) {
|
|
639
|
-
this.base.onChange = value;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
get borderColor(): ((str: string) => string) | undefined {
|
|
643
|
-
return this.base.borderColor;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
set borderColor(value: ((str: string) => string) | undefined) {
|
|
647
|
-
this.base.borderColor = value;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
render(width: number): string[] {
|
|
651
|
-
return this.base.render(width);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
invalidate(): void {
|
|
655
|
-
this.base.invalidate();
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
getText(): string {
|
|
659
|
-
return this.base.getText();
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
setText(text: string): void {
|
|
663
|
-
this.base.setText(text);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
handleInput(data: string): void {
|
|
667
|
-
if (matchesKey(data, HOTKEY)) {
|
|
668
|
-
triggerEditTurnCommand(this.base);
|
|
669
|
-
return;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
if (this.onExtensionShortcut?.(data)) {
|
|
673
|
-
return;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
if (this.keybindings.matches(data, "app.clipboard.pasteImage")) {
|
|
677
|
-
this.onPasteImage?.();
|
|
678
|
-
return;
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
if (this.keybindings.matches(data, "app.interrupt")) {
|
|
682
|
-
const isShowingAutocomplete = (this.base as AutocompleteAwareEditor).isShowingAutocomplete?.() ?? false;
|
|
683
|
-
if (!isShowingAutocomplete) {
|
|
684
|
-
const handler = this.onEscape ?? this.actionHandlers.get("app.interrupt");
|
|
685
|
-
if (handler) {
|
|
686
|
-
handler();
|
|
687
|
-
return;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
this.base.handleInput(data);
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
if (this.keybindings.matches(data, "app.exit") && this.base.getText().length === 0) {
|
|
696
|
-
const handler = this.onCtrlD ?? this.actionHandlers.get("app.exit");
|
|
697
|
-
if (handler) {
|
|
698
|
-
handler();
|
|
699
|
-
}
|
|
700
|
-
return;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
for (const [action, handler] of this.actionHandlers) {
|
|
704
|
-
if (action !== "app.interrupt" && action !== "app.exit" && this.keybindings.matches(data, action)) {
|
|
705
|
-
handler();
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
this.base.handleInput(data);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
addToHistory(text: string): void {
|
|
714
|
-
this.base.addToHistory?.(text);
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
insertTextAtCursor(text: string): void {
|
|
718
|
-
this.base.insertTextAtCursor?.(text);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
getExpandedText(): string {
|
|
722
|
-
return this.base.getExpandedText?.() ?? this.base.getText();
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
setAutocompleteProvider(provider: AutocompleteProvider): void {
|
|
726
|
-
this.base.setAutocompleteProvider?.(provider);
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
setPaddingX(padding: number): void {
|
|
730
|
-
this.base.setPaddingX?.(padding);
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
setAutocompleteMaxVisible(maxVisible: number): void {
|
|
734
|
-
this.base.setAutocompleteMaxVisible?.(maxVisible);
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
|
|
738
585
|
export default function editSessionInPlace(pi: ExtensionAPI) {
|
|
739
586
|
pi.registerCommand(COMMAND_NAME, {
|
|
740
587
|
description: `Select and re-edit a previous user message on the current branch (${HOTKEY_LABEL})`,
|
|
@@ -743,27 +590,10 @@ export default function editSessionInPlace(pi: ExtensionAPI) {
|
|
|
743
590
|
},
|
|
744
591
|
});
|
|
745
592
|
|
|
746
|
-
// Shortcut handlers receive ExtensionContext, so the custom editor hotkey path performs
|
|
747
|
-
// the command execution while this registration keeps the hotkey discoverable.
|
|
748
|
-
pi.registerShortcut(HOTKEY, {
|
|
749
|
-
description: `Edit a previous user message (${HOTKEY_LABEL})`,
|
|
750
|
-
handler: (ctx) => {
|
|
751
|
-
if (!ctx.hasUI) {
|
|
752
|
-
return;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
ctx.ui.notify(`Press ${HOTKEY_LABEL} in the main editor to edit a previous message.`, "info");
|
|
756
|
-
},
|
|
757
|
-
});
|
|
758
|
-
|
|
759
593
|
pi.on("session_start", (_event, ctx) => {
|
|
760
594
|
clearSavedDraft();
|
|
761
595
|
if (ctx.mode === "tui") {
|
|
762
|
-
|
|
763
|
-
ctx.ui.setEditorComponent((tui, theme, keybindings) => {
|
|
764
|
-
const baseEditor = previousEditor?.(tui, theme, keybindings);
|
|
765
|
-
return baseEditor ? new EditSessionInPlaceEditorWrapper(baseEditor, keybindings) : new EditSessionInPlaceEditor(tui, theme, keybindings);
|
|
766
|
-
});
|
|
596
|
+
ctx.ui.setEditorComponent((tui, theme, keybindings) => new EditSessionInPlaceEditor(tui, theme, keybindings));
|
|
767
597
|
}
|
|
768
598
|
});
|
|
769
599
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-edit-session-in-place",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "pi extension that lets you re-edit or delete an earlier user message in the current session branch",
|
|
5
5
|
"author": "Mitch Fultz (https://github.com/fitchmultz)",
|
|
6
6
|
"license": "MIT",
|