editprompt 1.0.0 → 1.1.1

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.
Files changed (2) hide show
  1. package/dist/index.js +70 -10
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { tmpdir } from "node:os";
9
9
  import { join } from "node:path";
10
10
 
11
11
  //#region package.json
12
- var version = "1.0.0";
12
+ var version = "1.1.1";
13
13
 
14
14
  //#endregion
15
15
  //#region src/modules/tmux.ts
@@ -265,6 +265,25 @@ function needsSpaceSeparator(prevLine, currentLine) {
265
265
  return isLastCharAlpha && isFirstCharAlpha;
266
266
  }
267
267
  /**
268
+ * Merge lines for Pattern A where indented lines likely indicate wrap
269
+ */
270
+ function mergeIndentedContinuations(originalLines, trimmedLines) {
271
+ const result = [];
272
+ for (let i = 0; i < trimmedLines.length; i++) {
273
+ const line = trimmedLines[i] ?? "";
274
+ const original = originalLines[i] ?? "";
275
+ const prevOriginal = originalLines[i - 1] ?? "";
276
+ if (i > 0 && original.startsWith(" ") && original.trimStart().length > 0 && !prevOriginal.startsWith(" ") && !/^[-*+]\s/.test(original.trimStart())) {
277
+ const prev = result.pop() ?? "";
278
+ const separator = needsSpaceSeparator(prev, line) ? " " : "";
279
+ result.push(prev + separator + line);
280
+ continue;
281
+ }
282
+ result.push(line);
283
+ }
284
+ return result;
285
+ }
286
+ /**
268
287
  * Determine if two lines should be merged
269
288
  */
270
289
  function shouldMergeLines(prevLine, currentLine) {
@@ -278,10 +297,16 @@ function shouldMergeLines(prevLine, currentLine) {
278
297
  */
279
298
  function removeWhitespaceAndMergeLines(lines) {
280
299
  const minWhitespace = getMinLeadingWhitespace(lines);
281
- const trimmedLines = lines.map((line) => {
300
+ let trimmedLines = lines.map((line) => {
282
301
  if (line.length === 0) return line;
283
302
  return line.slice(minWhitespace);
284
303
  });
304
+ trimmedLines = trimmedLines.map((line, index) => {
305
+ const original = lines[index] ?? "";
306
+ const prevOriginal = lines[index - 1] ?? "";
307
+ if (index > 0 && original.startsWith(" ") && original.trimStart().length > 0 && prevOriginal.trim().length > 0 && !/^[-*+]\s/.test(original.trimStart())) return original.trimStart().trimEnd();
308
+ return line.trimEnd();
309
+ });
285
310
  const result = [];
286
311
  let currentLine = "";
287
312
  for (let i = 0; i < trimmedLines.length; i++) {
@@ -320,12 +345,14 @@ function removeWhitespaceAndMergeLines(lines) {
320
345
  * 4. Adding quote prefix ("> ") to each line
321
346
  * 5. Adding two newlines at the end
322
347
  */
323
- function processQuoteText(text) {
348
+ function processQuoteText(text, options) {
349
+ const withQuote = options?.withQuote ?? true;
324
350
  const lines = text.replace(/^\n+|\n+$/g, "").split("\n");
325
351
  const hasNoLeadingWhitespaceInLaterLines = lines.slice(1).some((line) => line.length > 0 && !line.startsWith(" ") && !line.startsWith(" "));
326
352
  let processedLines;
327
- if (hasNoLeadingWhitespaceInLaterLines) processedLines = lines.map((line) => line.trimStart());
353
+ if (hasNoLeadingWhitespaceInLaterLines) processedLines = mergeIndentedContinuations(lines, lines.map((line) => line.trimStart().trimEnd()));
328
354
  else processedLines = removeWhitespaceAndMergeLines(lines);
355
+ if (!withQuote) return processedLines.join("\n");
329
356
  return `${processedLines.map((line) => `> ${line}`).join("\n")}\n\n`;
330
357
  }
331
358
 
@@ -431,6 +458,15 @@ const ARG_ALWAYS_COPY = {
431
458
  description: "Always copy content to clipboard",
432
459
  type: "boolean"
433
460
  };
461
+ const ARG_NO_QUOTE = {
462
+ description: "Disable quote prefix and trailing blank lines",
463
+ type: "boolean"
464
+ };
465
+ const ARG_OUTPUT = {
466
+ description: "Output destination (buffer, stdout). Can be specified multiple times",
467
+ type: "string",
468
+ multiple: true
469
+ };
434
470
  function validateMux(value) {
435
471
  const muxValue = value || "tmux";
436
472
  if (!isMuxType(muxValue)) {
@@ -454,6 +490,7 @@ function normalizeTargetPanes(value) {
454
490
 
455
491
  //#endregion
456
492
  //#region src/modes/collect.ts
493
+ const SUPPORTED_OUTPUTS = ["buffer", "stdout"];
457
494
  async function readStdin() {
458
495
  return new Promise((resolve, reject) => {
459
496
  const chunks = [];
@@ -468,14 +505,29 @@ async function readStdin() {
468
505
  });
469
506
  });
470
507
  }
471
- async function runCollectMode(mux, targetPaneId, rawContent) {
508
+ function normalizeCollectOutputs(value) {
509
+ let outputs = [];
510
+ if (Array.isArray(value)) outputs = value.map((v) => String(v));
511
+ else if (typeof value === "string") outputs = [value];
512
+ if (outputs.length === 0) return ["buffer"];
513
+ const uniqueOutputs = [...new Set(outputs)];
514
+ const invalid = uniqueOutputs.filter((v) => !SUPPORTED_OUTPUTS.includes(v));
515
+ if (invalid.length > 0) {
516
+ console.error(`Error: Invalid output(s) '${invalid.join(", ")}'. Supported values: ${SUPPORTED_OUTPUTS.join(", ")}`);
517
+ process.exit(1);
518
+ }
519
+ return uniqueOutputs;
520
+ }
521
+ async function runCollectMode(mux, targetPaneId, rawContent, outputs = ["buffer"], withQuote = true) {
472
522
  try {
473
523
  let selection;
474
524
  if (rawContent !== void 0) selection = rawContent;
475
525
  else selection = await readStdin();
476
- const processedText = processQuoteText(selection);
477
- if (mux === "tmux") await appendToQuoteVariable(targetPaneId, processedText);
478
- else if (mux === "wezterm") await appendToQuoteText(targetPaneId, processedText);
526
+ const processedText = processQuoteText(selection, { withQuote });
527
+ for (const output of outputs) if (output === "buffer") {
528
+ if (mux === "tmux") await appendToQuoteVariable(targetPaneId, processedText);
529
+ else if (mux === "wezterm") await appendToQuoteText(targetPaneId, processedText);
530
+ } else if (output === "stdout") process.stdout.write(processedText);
479
531
  } catch (error) {
480
532
  console.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
481
533
  process.exit(1);
@@ -486,11 +538,15 @@ const collectCommand = define({
486
538
  description: "Collect and accumulate quoted text to pane variable",
487
539
  args: {
488
540
  mux: ARG_MUX,
489
- "target-pane": ARG_TARGET_PANE_SINGLE
541
+ "target-pane": ARG_TARGET_PANE_SINGLE,
542
+ output: ARG_OUTPUT,
543
+ "no-quote": ARG_NO_QUOTE
490
544
  },
491
545
  async run(ctx) {
492
546
  const targetPane = validateTargetPane(ctx.values["target-pane"], "collect");
493
547
  const mux = validateMux(ctx.values.mux);
548
+ const outputs = normalizeCollectOutputs(ctx.values.output);
549
+ const withQuote = !ctx.values["no-quote"];
494
550
  let rawContent;
495
551
  if (mux === "wezterm") {
496
552
  rawContent = extractRawContent(ctx.rest, ctx.positionals);
@@ -499,7 +555,7 @@ const collectCommand = define({
499
555
  process.exit(1);
500
556
  }
501
557
  }
502
- await runCollectMode(mux, targetPane, rawContent);
558
+ await runCollectMode(mux, targetPane, rawContent, outputs, withQuote);
503
559
  }
504
560
  });
505
561
 
@@ -621,6 +677,10 @@ async function runInputMode(rawContent, autoSend, sendKey) {
621
677
  } catch (error) {
622
678
  console.error(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
623
679
  }
680
+ if (config.alwaysCopy) {
681
+ await copyToClipboard(content);
682
+ console.log("Also copied to clipboard.");
683
+ }
624
684
  if (successCount > 0) console.log("Content sent and submitted successfully!");
625
685
  else {
626
686
  console.error("Error: All target panes failed to receive content");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "editprompt",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "author": "eetann",
5
5
  "description": "A CLI tool that lets you write prompts for CLI tools using your favorite text editor",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "build": "tsdown",
41
41
  "dev": "tsdown --watch",
42
42
  "lint": "biome check",
43
- "formant": "biome format --write",
43
+ "format": "biome format --write",
44
44
  "typecheck": "tsgo --noEmit",
45
45
  "release": "bun run lint && bun run typecheck && bun run test && bun run build && bumpp",
46
46
  "test": "bun test",