@optique/core 1.0.15-dev.2789 → 1.0.15-dev.2809

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.
@@ -601,6 +601,29 @@ function ${functionName}
601
601
  set -l tokens (commandline -poc)
602
602
  set -l current (commandline -ct)
603
603
 
604
+ # commandline -poc decodes previous tokens, but commandline -ct returns
605
+ # the current token as typed. Decode its quotes and escapes as well.
606
+ # Keep the token as typed if decoding fails or yields a newline or tab,
607
+ # which completion output cannot carry.
608
+ set -l __raw_current "$current"
609
+ set -l __decoded (string unescape -- "$current")
610
+ or begin
611
+ # string unescape rejects an unfinished trailing backslash. fish
612
+ # keeps it literally inside single quotes, which also keep a " as
613
+ # is, and otherwise waits for the character it escapes.
614
+ set -l __prefix (string replace -r '\\\\\\\\$' '' -- "$current")
615
+ set -l __probe (string unescape -- "$__prefix\\"")
616
+ set -l __plain (string unescape -- "$__prefix")
617
+ if test "$__probe" = "$__plain\\""
618
+ set __decoded (string unescape -- "$current\\\\")
619
+ else
620
+ set __decoded (string unescape -- "$__prefix")
621
+ end
622
+ end
623
+ and test (count $__decoded) -eq 1
624
+ and not string match -qr '\\t' -- "$__decoded"
625
+ and set current "$__decoded"
626
+
604
627
  # Extract previous arguments (skip the command name)
605
628
  set -l prev
606
629
  set -l count (count $tokens)
@@ -621,6 +644,13 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
621
644
  set -l pattern (string replace -a '%25' '%' -- (string replace -a '%3A' ':' -- $parts[4]))
622
645
  set -l hidden $parts[5]
623
646
 
647
+ # path() echoes the current word as its pattern. When that word
648
+ # was quoted or escaped, treat the echo as the typed word rather
649
+ # than as a pattern from the program.
650
+ if test "$current" != "$__raw_current"; and test "$pattern" = "$current"
651
+ set pattern ""
652
+ end
653
+
624
654
  # When a pattern is specified, use it as the glob base instead
625
655
  # of the current word. If the user has already typed beyond the
626
656
  # pattern (e.g., pattern="src/" and current="src/ma"), keep the
@@ -656,13 +686,16 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
656
686
  end
657
687
 
658
688
  # Expand tilde prefix for globbing — fish does not expand ~
659
- # inside variable substitutions, so replace it with $HOME
660
- if string match -q '~/*' -- "$glob_base"
661
- set __tilde_prefix "~"
662
- set glob_base (string replace -r '^~' "$HOME" -- "$glob_base")
663
- else if string match -q '~' -- "$glob_base"
664
- set __tilde_prefix "~"
665
- set glob_base "$HOME/"
689
+ # inside variable substitutions, so replace it with $HOME. Like
690
+ # fish itself, keep a quoted or escaped tilde in the word literal.
691
+ if test $__from_pattern -eq 1; or string match -q '~*' -- "$__raw_current"
692
+ if string match -q '~/*' -- "$glob_base"
693
+ set __tilde_prefix "~"
694
+ set glob_base (string replace -r '^~' "$HOME" -- "$glob_base")
695
+ else if string match -q '~' -- "$glob_base"
696
+ set __tilde_prefix "~"
697
+ set glob_base "$HOME/"
698
+ end
666
699
  end
667
700
 
668
701
  # If the glob base is a directory without a trailing slash,
@@ -880,6 +913,16 @@ complete -c ${programName} -f -a '(${functionName})'
880
913
  }
881
914
  };
882
915
  /**
916
+ * Quotes a string as a Nushell string literal. Nushell single-quoted strings
917
+ * have no escape sequences, so a value containing an apostrophe is written as
918
+ * a double-quoted string, in which only backslashes and double quotes need
919
+ * escaping.
920
+ */
921
+ function quoteNuString(value) {
922
+ if (!value.includes("'")) return `'${value}'`;
923
+ return `"${value.replace(/["\\]/g, "\\$&")}"`;
924
+ }
925
+ /**
883
926
  * The Nushell completion generator.
884
927
  * @since 0.6.0
885
928
  */
@@ -887,7 +930,7 @@ const nu = {
887
930
  name: "nu",
888
931
  generateScript(programName, args = []) {
889
932
  validateProgramName(programName);
890
- const escapedArgs = args.map((arg) => `'${arg.replace(/'/g, "''")}'`).join(" ");
933
+ const escapedArgs = args.map(quoteNuString).join(" ");
891
934
  const safeName = programName.replace(/[^a-zA-Z0-9]+/g, "-");
892
935
  const functionName = `nu-complete-${safeName}`;
893
936
  return `
@@ -601,6 +601,29 @@ function ${functionName}
601
601
  set -l tokens (commandline -poc)
602
602
  set -l current (commandline -ct)
603
603
 
604
+ # commandline -poc decodes previous tokens, but commandline -ct returns
605
+ # the current token as typed. Decode its quotes and escapes as well.
606
+ # Keep the token as typed if decoding fails or yields a newline or tab,
607
+ # which completion output cannot carry.
608
+ set -l __raw_current "$current"
609
+ set -l __decoded (string unescape -- "$current")
610
+ or begin
611
+ # string unescape rejects an unfinished trailing backslash. fish
612
+ # keeps it literally inside single quotes, which also keep a " as
613
+ # is, and otherwise waits for the character it escapes.
614
+ set -l __prefix (string replace -r '\\\\\\\\$' '' -- "$current")
615
+ set -l __probe (string unescape -- "$__prefix\\"")
616
+ set -l __plain (string unescape -- "$__prefix")
617
+ if test "$__probe" = "$__plain\\""
618
+ set __decoded (string unescape -- "$current\\\\")
619
+ else
620
+ set __decoded (string unescape -- "$__prefix")
621
+ end
622
+ end
623
+ and test (count $__decoded) -eq 1
624
+ and not string match -qr '\\t' -- "$__decoded"
625
+ and set current "$__decoded"
626
+
604
627
  # Extract previous arguments (skip the command name)
605
628
  set -l prev
606
629
  set -l count (count $tokens)
@@ -621,6 +644,13 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
621
644
  set -l pattern (string replace -a '%25' '%' -- (string replace -a '%3A' ':' -- $parts[4]))
622
645
  set -l hidden $parts[5]
623
646
 
647
+ # path() echoes the current word as its pattern. When that word
648
+ # was quoted or escaped, treat the echo as the typed word rather
649
+ # than as a pattern from the program.
650
+ if test "$current" != "$__raw_current"; and test "$pattern" = "$current"
651
+ set pattern ""
652
+ end
653
+
624
654
  # When a pattern is specified, use it as the glob base instead
625
655
  # of the current word. If the user has already typed beyond the
626
656
  # pattern (e.g., pattern="src/" and current="src/ma"), keep the
@@ -656,13 +686,16 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
656
686
  end
657
687
 
658
688
  # Expand tilde prefix for globbing — fish does not expand ~
659
- # inside variable substitutions, so replace it with $HOME
660
- if string match -q '~/*' -- "$glob_base"
661
- set __tilde_prefix "~"
662
- set glob_base (string replace -r '^~' "$HOME" -- "$glob_base")
663
- else if string match -q '~' -- "$glob_base"
664
- set __tilde_prefix "~"
665
- set glob_base "$HOME/"
689
+ # inside variable substitutions, so replace it with $HOME. Like
690
+ # fish itself, keep a quoted or escaped tilde in the word literal.
691
+ if test $__from_pattern -eq 1; or string match -q '~*' -- "$__raw_current"
692
+ if string match -q '~/*' -- "$glob_base"
693
+ set __tilde_prefix "~"
694
+ set glob_base (string replace -r '^~' "$HOME" -- "$glob_base")
695
+ else if string match -q '~' -- "$glob_base"
696
+ set __tilde_prefix "~"
697
+ set glob_base "$HOME/"
698
+ end
666
699
  end
667
700
 
668
701
  # If the glob base is a directory without a trailing slash,
@@ -880,6 +913,16 @@ complete -c ${programName} -f -a '(${functionName})'
880
913
  }
881
914
  };
882
915
  /**
916
+ * Quotes a string as a Nushell string literal. Nushell single-quoted strings
917
+ * have no escape sequences, so a value containing an apostrophe is written as
918
+ * a double-quoted string, in which only backslashes and double quotes need
919
+ * escaping.
920
+ */
921
+ function quoteNuString(value) {
922
+ if (!value.includes("'")) return `'${value}'`;
923
+ return `"${value.replace(/["\\]/g, "\\$&")}"`;
924
+ }
925
+ /**
883
926
  * The Nushell completion generator.
884
927
  * @since 0.6.0
885
928
  */
@@ -887,7 +930,7 @@ const nu = {
887
930
  name: "nu",
888
931
  generateScript(programName, args = []) {
889
932
  validateProgramName(programName);
890
- const escapedArgs = args.map((arg) => `'${arg.replace(/'/g, "''")}'`).join(" ");
933
+ const escapedArgs = args.map(quoteNuString).join(" ");
891
934
  const safeName = programName.replace(/[^a-zA-Z0-9]+/g, "-");
892
935
  const functionName = `nu-complete-${safeName}`;
893
936
  return `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.15-dev.2789",
3
+ "version": "1.0.15-dev.2809",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",