@optique/core 1.0.15-dev.2822 → 1.0.15-dev.2824

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.
@@ -902,15 +902,13 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
902
902
  # Normalize leading ./ so that ./src/ma matches pattern src/
903
903
  set -l __norm_current (string replace -r '^\\./' '' -- "$current")
904
904
  set -l __norm_pattern (string replace -r '^\\./' '' -- "$pattern")
905
- # For wildcard patterns, compare only the directory prefix
905
+ # For wildcard patterns, compare only the directory prefix.
906
+ # Use a regex: fish wildcards have no character classes.
907
+ # Only the basename can hold wildcards; a ? or * in a
908
+ # directory name such as What?/ is literal.
906
909
  set -l __compare_pattern "$__norm_pattern"
907
- if string match -q '*[*?]*' -- "$__compare_pattern"
908
- set __compare_pattern (string replace -r '[*?].*' '' -- "$__compare_pattern")
909
- if string match -q '*/*' -- "$__compare_pattern"
910
- set __compare_pattern (string replace -r '/[^/]*$' '/' -- "$__compare_pattern")
911
- else
912
- set __compare_pattern ""
913
- end
910
+ if string match -qr '[*?][^/]*$' -- "$__compare_pattern"
911
+ set __compare_pattern (string replace -r '[^/]*$' '' -- "$__compare_pattern")
914
912
  end
915
913
  set -l __cp_len (string length -- "$__compare_pattern")
916
914
  set -l __nc_len (string length -- "$__norm_current")
@@ -945,54 +943,82 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
945
943
  end
946
944
 
947
945
  # Pre-expand file candidates. When the glob base came from
948
- # the program's pattern and contains * or ?, use it as the
949
- # complete glob expression. Otherwise append * as a prefix.
946
+ # the program's pattern and its basename contains * or ?, use
947
+ # it as the complete glob expression. Otherwise append * as a
948
+ # prefix, so a literal ? in a directory name such as What?/
949
+ # still lists that directory. A pattern equal to the current
950
+ # word is the typed text echoed back (as path() does), so its
951
+ # ? and * are literal characters, not wildcards.
950
952
  # Note: [ is NOT treated as a glob because it commonly
951
953
  # appears in literal filenames like [draft] or foo[1].txt.
952
954
  set -l __has_glob 0
953
955
  if test $__from_pattern -eq 1
954
- and string match -q '*[*?]*' -- "$glob_base"
956
+ and string match -qr '[*?][^/]*$' -- "$glob_base"
957
+ and test "$pattern" != "$current"
955
958
  set __has_glob 1
956
959
  end
957
960
  set -l __candidates
958
961
  if test $__has_glob -eq 1
959
962
  # Safe glob expansion without eval: split the pattern into
960
- # directory and filter parts, list the directory, then use
961
- # string match for wildcard filtering
962
- set -l __glob_dir (string replace -r '/[^/]*$' '' -- "$glob_base")
963
+ # a directory prefix and a basename filter, list the
964
+ # directory, then match basenames against a regex built
965
+ # from the filter. The prefix keeps one empty element for
966
+ # bare patterns so that $__glob_prefix* still expands.
967
+ set -l __glob_prefix ""
968
+ if string match -q '*/*' -- "$glob_base"
969
+ set __glob_prefix (string replace -r '[^/]*$' '' -- "$glob_base")
970
+ end
963
971
  set -l __glob_filter (string replace -r '.*/' '' -- "$glob_base")
964
- if test -z "$__glob_dir"; or test "$__glob_dir" = "$glob_base"
965
- set __glob_dir "."
972
+ # Translate the filter into an anchored regex: * and ? are
973
+ # wildcards and every other character is literal. Fish's
974
+ # own wildcards cannot be used here because ? is literal
975
+ # when the qmark-noglob feature is enabled (fish 4 default).
976
+ set -l __glob_regex '^'
977
+ for __ch in (string split '' -- "$__glob_filter")
978
+ if test "$__ch" = '*'
979
+ set __glob_regex "$__glob_regex.*"
980
+ else if test "$__ch" = '?'
981
+ set __glob_regex "$__glob_regex."
982
+ else
983
+ set __glob_regex "$__glob_regex"(string escape --style=regex -- "$__ch")
984
+ end
966
985
  end
986
+ set __glob_regex "$__glob_regex"'$'
967
987
  # Match files by the glob filter. Fish's * does not match
968
- # dotfiles, so also scan .* when the filter targets them.
969
- for __item in $__glob_dir/*
988
+ # dotfiles, so also scan .* when the filter targets them or
989
+ # hidden files are requested.
990
+ set -l __entries $__glob_prefix*
991
+ if test "$hidden" = "1"; or string match -q '.*' -- "$__glob_filter"
992
+ set -a __entries $__glob_prefix.*
993
+ end
994
+ for __item in $__entries
970
995
  if test -e "$__item"
971
- set -l __bn (basename -- "$__item")
972
- if string match -q -- "$__glob_filter" "$__bn"
973
- set -a __candidates "$__item"
996
+ set -l __bn (string replace -r '.*/' '' -- "$__item")
997
+ if contains -- "$__bn" . ..
998
+ continue
974
999
  end
975
- end
976
- end
977
- if string match -q '.*' -- "$__glob_filter"
978
- for __item in $__glob_dir/.*
979
- if test -e "$__item"
980
- set -l __bn (basename -- "$__item")
981
- if test "$__bn" = "." -o "$__bn" = ".."
982
- continue
983
- end
984
- if string match -q -- "$__glob_filter" "$__bn"
985
- set -a __candidates "$__item"
986
- end
1000
+ if string match -qr -- "$__glob_regex" "$__bn"
1001
+ set -a __candidates "$__item"
987
1002
  end
988
1003
  end
989
1004
  end
990
1005
  # For file/any modes, also include directories for navigation.
991
1006
  # Skip for directory mode so the pattern filter is respected.
1007
+ # Directories the filter already matched are not repeated.
992
1008
  if test "$type" != "directory"
993
- for __item in $__glob_dir/*/
1009
+ set -l __nav_dirs $__glob_prefix*/
1010
+ if test "$hidden" = "1"
1011
+ set -a __nav_dirs $__glob_prefix.*/
1012
+ end
1013
+ for __item in $__nav_dirs
1014
+ set __item (string replace -r '/$' '' -- "$__item")
1015
+ set -l __bn (string replace -r '.*/' '' -- "$__item")
1016
+ if contains -- "$__bn" . ..
1017
+ continue
1018
+ end
994
1019
  if test -d "$__item"
995
- set -a __candidates (string replace -r '/$' '' -- "$__item")
1020
+ and not string match -qr -- "$__glob_regex" "$__bn"
1021
+ set -a __candidates "$__item"
996
1022
  end
997
1023
  end
998
1024
  end
@@ -902,15 +902,13 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
902
902
  # Normalize leading ./ so that ./src/ma matches pattern src/
903
903
  set -l __norm_current (string replace -r '^\\./' '' -- "$current")
904
904
  set -l __norm_pattern (string replace -r '^\\./' '' -- "$pattern")
905
- # For wildcard patterns, compare only the directory prefix
905
+ # For wildcard patterns, compare only the directory prefix.
906
+ # Use a regex: fish wildcards have no character classes.
907
+ # Only the basename can hold wildcards; a ? or * in a
908
+ # directory name such as What?/ is literal.
906
909
  set -l __compare_pattern "$__norm_pattern"
907
- if string match -q '*[*?]*' -- "$__compare_pattern"
908
- set __compare_pattern (string replace -r '[*?].*' '' -- "$__compare_pattern")
909
- if string match -q '*/*' -- "$__compare_pattern"
910
- set __compare_pattern (string replace -r '/[^/]*$' '/' -- "$__compare_pattern")
911
- else
912
- set __compare_pattern ""
913
- end
910
+ if string match -qr '[*?][^/]*$' -- "$__compare_pattern"
911
+ set __compare_pattern (string replace -r '[^/]*$' '' -- "$__compare_pattern")
914
912
  end
915
913
  set -l __cp_len (string length -- "$__compare_pattern")
916
914
  set -l __nc_len (string length -- "$__norm_current")
@@ -945,54 +943,82 @@ ${escapedArgs ? ` set -l output (${programName} ${escapedArgs} $prev $current
945
943
  end
946
944
 
947
945
  # Pre-expand file candidates. When the glob base came from
948
- # the program's pattern and contains * or ?, use it as the
949
- # complete glob expression. Otherwise append * as a prefix.
946
+ # the program's pattern and its basename contains * or ?, use
947
+ # it as the complete glob expression. Otherwise append * as a
948
+ # prefix, so a literal ? in a directory name such as What?/
949
+ # still lists that directory. A pattern equal to the current
950
+ # word is the typed text echoed back (as path() does), so its
951
+ # ? and * are literal characters, not wildcards.
950
952
  # Note: [ is NOT treated as a glob because it commonly
951
953
  # appears in literal filenames like [draft] or foo[1].txt.
952
954
  set -l __has_glob 0
953
955
  if test $__from_pattern -eq 1
954
- and string match -q '*[*?]*' -- "$glob_base"
956
+ and string match -qr '[*?][^/]*$' -- "$glob_base"
957
+ and test "$pattern" != "$current"
955
958
  set __has_glob 1
956
959
  end
957
960
  set -l __candidates
958
961
  if test $__has_glob -eq 1
959
962
  # Safe glob expansion without eval: split the pattern into
960
- # directory and filter parts, list the directory, then use
961
- # string match for wildcard filtering
962
- set -l __glob_dir (string replace -r '/[^/]*$' '' -- "$glob_base")
963
+ # a directory prefix and a basename filter, list the
964
+ # directory, then match basenames against a regex built
965
+ # from the filter. The prefix keeps one empty element for
966
+ # bare patterns so that $__glob_prefix* still expands.
967
+ set -l __glob_prefix ""
968
+ if string match -q '*/*' -- "$glob_base"
969
+ set __glob_prefix (string replace -r '[^/]*$' '' -- "$glob_base")
970
+ end
963
971
  set -l __glob_filter (string replace -r '.*/' '' -- "$glob_base")
964
- if test -z "$__glob_dir"; or test "$__glob_dir" = "$glob_base"
965
- set __glob_dir "."
972
+ # Translate the filter into an anchored regex: * and ? are
973
+ # wildcards and every other character is literal. Fish's
974
+ # own wildcards cannot be used here because ? is literal
975
+ # when the qmark-noglob feature is enabled (fish 4 default).
976
+ set -l __glob_regex '^'
977
+ for __ch in (string split '' -- "$__glob_filter")
978
+ if test "$__ch" = '*'
979
+ set __glob_regex "$__glob_regex.*"
980
+ else if test "$__ch" = '?'
981
+ set __glob_regex "$__glob_regex."
982
+ else
983
+ set __glob_regex "$__glob_regex"(string escape --style=regex -- "$__ch")
984
+ end
966
985
  end
986
+ set __glob_regex "$__glob_regex"'$'
967
987
  # Match files by the glob filter. Fish's * does not match
968
- # dotfiles, so also scan .* when the filter targets them.
969
- for __item in $__glob_dir/*
988
+ # dotfiles, so also scan .* when the filter targets them or
989
+ # hidden files are requested.
990
+ set -l __entries $__glob_prefix*
991
+ if test "$hidden" = "1"; or string match -q '.*' -- "$__glob_filter"
992
+ set -a __entries $__glob_prefix.*
993
+ end
994
+ for __item in $__entries
970
995
  if test -e "$__item"
971
- set -l __bn (basename -- "$__item")
972
- if string match -q -- "$__glob_filter" "$__bn"
973
- set -a __candidates "$__item"
996
+ set -l __bn (string replace -r '.*/' '' -- "$__item")
997
+ if contains -- "$__bn" . ..
998
+ continue
974
999
  end
975
- end
976
- end
977
- if string match -q '.*' -- "$__glob_filter"
978
- for __item in $__glob_dir/.*
979
- if test -e "$__item"
980
- set -l __bn (basename -- "$__item")
981
- if test "$__bn" = "." -o "$__bn" = ".."
982
- continue
983
- end
984
- if string match -q -- "$__glob_filter" "$__bn"
985
- set -a __candidates "$__item"
986
- end
1000
+ if string match -qr -- "$__glob_regex" "$__bn"
1001
+ set -a __candidates "$__item"
987
1002
  end
988
1003
  end
989
1004
  end
990
1005
  # For file/any modes, also include directories for navigation.
991
1006
  # Skip for directory mode so the pattern filter is respected.
1007
+ # Directories the filter already matched are not repeated.
992
1008
  if test "$type" != "directory"
993
- for __item in $__glob_dir/*/
1009
+ set -l __nav_dirs $__glob_prefix*/
1010
+ if test "$hidden" = "1"
1011
+ set -a __nav_dirs $__glob_prefix.*/
1012
+ end
1013
+ for __item in $__nav_dirs
1014
+ set __item (string replace -r '/$' '' -- "$__item")
1015
+ set -l __bn (string replace -r '.*/' '' -- "$__item")
1016
+ if contains -- "$__bn" . ..
1017
+ continue
1018
+ end
994
1019
  if test -d "$__item"
995
- set -a __candidates (string replace -r '/$' '' -- "$__item")
1020
+ and not string match -qr -- "$__glob_regex" "$__bn"
1021
+ set -a __candidates "$__item"
996
1022
  end
997
1023
  end
998
1024
  end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.15-dev.2822",
3
+ "version": "1.0.15-dev.2824",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",