pi-better-paste-markers 0.1.0 → 0.2.0
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/README.md +2 -0
- package/index.ts +41 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@ Pastes over 10 lines or 1000 chars render as a three-line block:
|
|
|
21
21
|
- Everywhere else (drafts, autocomplete, undo) the block collapses back to the standard single-line `[paste #N ...]` marker.
|
|
22
22
|
- The block deletes as one unit: a single Backspace/Delete (or Ctrl+W/U/K) that touches it removes the whole block, like the built-in `[paste #N ...]` marker. Text before and after the block on the same line is kept.
|
|
23
23
|
- Undo restores the whole block and it keeps expanding/submitting correctly.
|
|
24
|
+
- The input is prefixed with a gray `❯` prompt (the one pi-powerline-footer draws on the default editor is lost when a custom editor component replaces it).
|
|
24
25
|
|
|
25
26
|
## Install
|
|
26
27
|
|
|
@@ -37,5 +38,6 @@ The extension replaces the main editor on `session_start` via `ctx.ui.setEditorC
|
|
|
37
38
|
- `getText()` — collapses blocks back to canonical `[paste #N ...]` markers (drafts, autocomplete snapshots, undo).
|
|
38
39
|
- `expandPasteMarkers()` — plain Enter submits through the base editor's private `submitValue()`, which expands paste markers with this method; shadowing it makes Enter submit the original pasted content instead of the three-line preview.
|
|
39
40
|
- `getExpandedText()` — used by the follow-up (Alt+Enter), external-editor and extension-API (`getEditorText`) paths.
|
|
41
|
+
- `render()` — prefixes the input with a gray `❯` and keeps the other content lines indented, matching the chrome pi-powerline-footer adds to the default editor.
|
|
40
42
|
|
|
41
43
|
Paste records are kept after a block is deleted so that undoing the deletion restores a block that still collapses and expands correctly.
|
package/index.ts
CHANGED
|
@@ -32,6 +32,8 @@ import { matchesKey, type EditorTheme, type TUI } from "@earendil-works/pi-tui";
|
|
|
32
32
|
const MIDDLE_RE = /^paste #(\d+) (\d+) chars \/ (\d+) lines$/;
|
|
33
33
|
/** Max characters shown for the first/last preview line before truncation. */
|
|
34
34
|
const PREVIEW_MAX_CHARS = 80;
|
|
35
|
+
/** Gray `❯` prompt drawn before the input line (matches pi-powerline-footer chrome). */
|
|
36
|
+
const INPUT_PROMPT = "\x1b[38;2;200;200;200m❯\x1b[0m";
|
|
35
37
|
|
|
36
38
|
interface PasteRecord {
|
|
37
39
|
content: string;
|
|
@@ -307,6 +309,45 @@ export class BetterPasteEditor extends CustomEditor {
|
|
|
307
309
|
override expandPasteMarkers(text: string): string {
|
|
308
310
|
return this.expand(this.collapse(super.expandPasteMarkers(text)));
|
|
309
311
|
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Draw a `❯` prompt before the input, mirroring the chrome that
|
|
315
|
+
* pi-powerline-footer applies to the default editor. Replacing the editor
|
|
316
|
+
* component drops that wrapper, so we render the prompt ourselves.
|
|
317
|
+
*/
|
|
318
|
+
override render(width: number): string[] {
|
|
319
|
+
if (width < 10) return super.render(width);
|
|
320
|
+
|
|
321
|
+
const contentWidth = Math.max(1, width - 3);
|
|
322
|
+
const lines = super.render(contentWidth);
|
|
323
|
+
if (lines.length === 0) return lines;
|
|
324
|
+
|
|
325
|
+
// The bottom border is the last `───…` row before any autocomplete rows.
|
|
326
|
+
let bottomBorderIndex = lines.length - 1;
|
|
327
|
+
for (let i = lines.length - 1; i >= 1; i--) {
|
|
328
|
+
const stripped = (lines[i] ?? "").replace(/\x1b\[[0-9;]*m/g, "");
|
|
329
|
+
if (stripped.length > 0 && /^─{3,}/.test(stripped)) {
|
|
330
|
+
bottomBorderIndex = i;
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const promptPrefix = ` ${INPUT_PROMPT} `;
|
|
336
|
+
const contPrefix = " ";
|
|
337
|
+
const border = " " + this.borderColor("─".repeat(Math.max(0, width - 2)));
|
|
338
|
+
const result: string[] = [border];
|
|
339
|
+
for (let i = 1; i < bottomBorderIndex; i++) {
|
|
340
|
+
result.push(`${i === 1 ? promptPrefix : contPrefix}${lines[i] ?? ""}`);
|
|
341
|
+
}
|
|
342
|
+
if (bottomBorderIndex === 1) {
|
|
343
|
+
result.push(`${promptPrefix}${" ".repeat(contentWidth)}`);
|
|
344
|
+
}
|
|
345
|
+
result.push(border);
|
|
346
|
+
for (let i = bottomBorderIndex + 1; i < lines.length; i++) {
|
|
347
|
+
result.push(lines[i] ?? "");
|
|
348
|
+
}
|
|
349
|
+
return result;
|
|
350
|
+
}
|
|
310
351
|
}
|
|
311
352
|
|
|
312
353
|
/** First-line preview: keep the head, add `...` only when something was cut. */
|
package/package.json
CHANGED