m/fzf
1
0
mirror of https://github.com/junegunn/fzf.git synced 2025-11-18 08:13:40 -05:00

Allow {q} placeholders with range expressions

e.g. {q:1}, {q:2..}
This commit is contained in:
Junegunn Choi
2025-01-27 15:40:21 +09:00
parent 2f8a72a42a
commit a2aa1a156c
6 changed files with 49 additions and 34 deletions

View File

@@ -39,7 +39,7 @@ cases for example.
\\?(?: # escaped type
{\+?s?f?RANGE(?:,RANGE)*} # token type
|{q} # query type
{q[:s?RANGE]} # query type
|{\+?n?f?} # item type (notice no mandatory element inside brackets)
)
RANGE = (?:
@@ -65,7 +65,7 @@ const maxFocusEvents = 10000
const blockDuration = 1 * time.Second
func init() {
placeholder = regexp.MustCompile(`\\?(?:{[+sf]*[0-9,-.]*}|{q}|{fzf:(?:query|action|prompt)}|{\+?f?nf?})`)
placeholder = regexp.MustCompile(`\\?(?:{[+sf]*[0-9,-.]*}|{q(?::s?[0-9,-.]+)?}|{fzf:(?:query|action|prompt)}|{\+?f?nf?})`)
whiteSuffix = regexp.MustCompile(`\s*$`)
offsetComponentRegex = regexp.MustCompile(`([+-][0-9]+)|(-?/[1-9][0-9]*)`)
offsetTrimCharsRegex = regexp.MustCompile(`[^0-9/+-]`)
@@ -3621,28 +3621,26 @@ func parsePlaceholder(match string) (bool, string, placeholderFlags) {
return false, match, flags
}
skipChars := 1
trimmed := ""
for _, char := range match[1:] {
switch char {
case '+':
flags.plus = true
skipChars++
case 's':
flags.preserveSpace = true
skipChars++
case 'n':
flags.number = true
skipChars++
case 'f':
flags.file = true
skipChars++
case 'q':
flags.forceUpdate = true
// query flag is not skipped
trimmed += string(char)
default:
trimmed += string(char)
}
}
matchWithoutFlags := "{" + match[skipChars:]
matchWithoutFlags := "{" + trimmed
return false, matchWithoutFlags, flags
}
@@ -3756,6 +3754,19 @@ func replacePlaceholder(params replacePlaceholderParams) (string, []string) {
return match
case match == "{q}" || match == "{fzf:query}":
return params.executor.QuoteEntry(params.query)
case strings.HasPrefix(match, "{q:"):
if nth, err := splitNth(match[3 : len(match)-1]); err == nil {
elems, prefixLength := awkTokenizer(params.query)
tokens := withPrefixLengths(elems, prefixLength)
trans := Transform(tokens, nth)
result := joinTokens(trans)
if !flags.preserveSpace {
result = strings.TrimSpace(result)
}
return params.executor.QuoteEntry(result)
}
return match
case match == "{}":
replace = func(item *Item) string {
switch {

View File

@@ -484,7 +484,12 @@ func TestParsePlaceholder(t *testing.T) {
// III. query type placeholder
// query flag is not removed after parsing, so it gets doubled
// while the double q is invalid, it is useful here for testing purposes
`{q}`: `{qq}`,
`{q}`: `{qq}`,
`{q:1}`: `{qq:1}`,
`{q:2..}`: `{qq:2..}`,
`{q:..}`: `{qq:..}`,
`{q:2..-1}`: `{qq:2..-1}`,
`{q:s2..-1}`: `{sqq:2..-1}`, // FIXME
// IV. escaping placeholder
`\{}`: `{}`,