From e311d77dbf658e532a81cdf1305f3f420779c07a Mon Sep 17 00:00:00 2001 From: lytex Date: Sat, 21 Jan 2023 23:07:49 +0100 Subject: [PATCH 1/7] add tokenize --- lua/telescope-live-grep-args/actions/init.lua | 3 ++- .../actions/tokenize.lua | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 lua/telescope-live-grep-args/actions/tokenize.lua diff --git a/lua/telescope-live-grep-args/actions/init.lua b/lua/telescope-live-grep-args/actions/init.lua index 2350a61..41306a9 100644 --- a/lua/telescope-live-grep-args/actions/init.lua +++ b/lua/telescope-live-grep-args/actions/init.lua @@ -3,5 +3,6 @@ -- SPDX-License-Identifier: MIT return { - quote_prompt = require("telescope-live-grep-args.actions.quote_prompt"), + quote_prompt = require("telescope-live-grep-args.actions.quote_prompt"), + tokenize = require("telescope-live-grep-args.actions.tokenize"), } diff --git a/lua/telescope-live-grep-args/actions/tokenize.lua b/lua/telescope-live-grep-args/actions/tokenize.lua new file mode 100644 index 0000000..d223b28 --- /dev/null +++ b/lua/telescope-live-grep-args/actions/tokenize.lua @@ -0,0 +1,23 @@ +local action_state = require("telescope.actions.state") + +local default_opts = { + quote_char = '"', + postfix = " ", + trim = true, +} + +return function(opts) + opts = opts or {} + opts = vim.tbl_extend("force", default_opts, opts) + + return function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + local prompt = picker:_get_prompt() + if opts.trim then + prompt = vim.trim(prompt) + end + prompt = prompt:gsub(opts.quote_char, "\\" .. opts.quote_char) + prompt = opts.quote_char .. prompt .. opts.quote_char .. opts.postfix + picker:set_prompt(prompt) + end +end From 5117f43fa8de07e5d4697480a9cea6b8ecf7813a Mon Sep 17 00:00:00 2001 From: lytex Date: Sun, 22 Jan 2023 00:15:15 +0100 Subject: [PATCH 2/7] implement tokenization --- .../actions/tokenize.lua | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/lua/telescope-live-grep-args/actions/tokenize.lua b/lua/telescope-live-grep-args/actions/tokenize.lua index d223b28..7adab7d 100644 --- a/lua/telescope-live-grep-args/actions/tokenize.lua +++ b/lua/telescope-live-grep-args/actions/tokenize.lua @@ -6,18 +6,56 @@ local default_opts = { trim = true, } + return function(opts) opts = opts or {} opts = vim.tbl_extend("force", default_opts, opts) return function(prompt_bufnr) + + local wrap, yield = coroutine.wrap, coroutine.yield + + local function permgen(a, n) + n = n or #a + if n <= 1 then + yield(a) + else + for i = 1, n do + -- put i-th element as the last one + a[n], a[i] = a[i], a[n] + -- generate all permutations of the other elements + permgen(a, n - 1) + -- restore i-th element + a[n], a[i] = a[i], a[n] + end + end + end + + function permutations(a) + -- call with coroutine.wrap() + return wrap(function() permgen(a) end) + end + local picker = action_state.get_current_picker(prompt_bufnr) local prompt = picker:_get_prompt() if opts.trim then prompt = vim.trim(prompt) end - prompt = prompt:gsub(opts.quote_char, "\\" .. opts.quote_char) - prompt = opts.quote_char .. prompt .. opts.quote_char .. opts.postfix + local tokens = {} + -- TODO interpret two spaces or more as a literal space + for token in prompt:gmatch("%S+") do + table.insert(tokens, token) + end + + prompt = "" + -- TODO Remove duplicate permutations + -- a a b → a.*b.*a|b.*a.*a|b.*a.*a|a.*b.*a|a.*a.*b|a.*b.*a it should be: + -- a a b → a.*b.*a|b.*a.*a|a.*a.*b + for combo in permutations(tokens) do + prompt = prompt .. "|" .. table.concat(combo, '.*') + end + prompt = prompt:sub(2) + picker:set_prompt(prompt) end end From c82ce64dd083473b117f8d57e0281f77a6913971 Mon Sep 17 00:00:00 2001 From: lytex Date: Wed, 15 Mar 2023 05:49:52 +0100 Subject: [PATCH 3/7] remove duplicates --- .../actions/tokenize.lua | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/lua/telescope-live-grep-args/actions/tokenize.lua b/lua/telescope-live-grep-args/actions/tokenize.lua index 7adab7d..4426d2a 100644 --- a/lua/telescope-live-grep-args/actions/tokenize.lua +++ b/lua/telescope-live-grep-args/actions/tokenize.lua @@ -6,34 +6,46 @@ local default_opts = { trim = true, } - return function(opts) opts = opts or {} opts = vim.tbl_extend("force", default_opts, opts) return function(prompt_bufnr) - local wrap, yield = coroutine.wrap, coroutine.yield local function permgen(a, n) - n = n or #a - if n <= 1 then - yield(a) - else - for i = 1, n do - -- put i-th element as the last one - a[n], a[i] = a[i], a[n] - -- generate all permutations of the other elements - permgen(a, n - 1) - -- restore i-th element - a[n], a[i] = a[i], a[n] - end + n = n or #a + if n <= 1 then + yield(a) + else + for i = 1, n do + -- put i-th element as the last one + a[n], a[i] = a[i], a[n] + -- generate all permutations of the other elements + permgen(a, n - 1) + -- restore i-th element + a[n], a[i] = a[i], a[n] end + end end function permutations(a) - -- call with coroutine.wrap() - return wrap(function() permgen(a) end) + -- call with coroutine.wrap() + return wrap(function() + permgen(a) + end) + end + + function removeDuplicates(tbl) + local newTbl = {} + local seen = {} + for _, value in ipairs(tbl) do + if not seen[value] then + table.insert(newTbl, value) + seen[value] = true + end + end + return newTbl end local picker = action_state.get_current_picker(prompt_bufnr) @@ -48,11 +60,8 @@ return function(opts) end prompt = "" - -- TODO Remove duplicate permutations - -- a a b → a.*b.*a|b.*a.*a|b.*a.*a|a.*b.*a|a.*a.*b|a.*b.*a it should be: - -- a a b → a.*b.*a|b.*a.*a|a.*a.*b - for combo in permutations(tokens) do - prompt = prompt .. "|" .. table.concat(combo, '.*') + for combo in permutations(removeDuplicates(tokens)) do + prompt = prompt .. "|" .. table.concat(combo, ".*") end prompt = prompt:sub(2) From ed77c49354d39d71a579c5d950fc03f94fb4dbeb Mon Sep 17 00:00:00 2001 From: lytex Date: Wed, 15 Mar 2023 05:55:43 +0100 Subject: [PATCH 4/7] implement separation by two spaces --- lua/telescope-live-grep-args/actions/tokenize.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lua/telescope-live-grep-args/actions/tokenize.lua b/lua/telescope-live-grep-args/actions/tokenize.lua index 4426d2a..86d87c7 100644 --- a/lua/telescope-live-grep-args/actions/tokenize.lua +++ b/lua/telescope-live-grep-args/actions/tokenize.lua @@ -53,10 +53,14 @@ return function(opts) if opts.trim then prompt = vim.trim(prompt) end + local tokens = {} - -- TODO interpret two spaces or more as a literal space - for token in prompt:gmatch("%S+") do - table.insert(tokens, token) + for chunks in prompt:gmatch("%S%S+") do + for chunk in chunks do + for token in chunk:gmatch("%S") do + table.insert(tokens, token) + end + end end prompt = "" From 64046ecfaa0a720554da1138d6042ee0ae9f0614 Mon Sep 17 00:00:00 2001 From: lytex Date: Wed, 15 Mar 2023 05:58:16 +0100 Subject: [PATCH 5/7] Revert "implement separation by two spaces" This reverts commit ed77c49354d39d71a579c5d950fc03f94fb4dbeb. --- lua/telescope-live-grep-args/actions/tokenize.lua | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lua/telescope-live-grep-args/actions/tokenize.lua b/lua/telescope-live-grep-args/actions/tokenize.lua index 86d87c7..4426d2a 100644 --- a/lua/telescope-live-grep-args/actions/tokenize.lua +++ b/lua/telescope-live-grep-args/actions/tokenize.lua @@ -53,14 +53,10 @@ return function(opts) if opts.trim then prompt = vim.trim(prompt) end - local tokens = {} - for chunks in prompt:gmatch("%S%S+") do - for chunk in chunks do - for token in chunk:gmatch("%S") do - table.insert(tokens, token) - end - end + -- TODO interpret two spaces or more as a literal space + for token in prompt:gmatch("%S+") do + table.insert(tokens, token) end prompt = "" From c4c8f65e07c11a2c5f7891d7f07dc85ac9f9f71f Mon Sep 17 00:00:00 2001 From: lytex Date: Sat, 15 Jul 2023 18:25:12 +0200 Subject: [PATCH 6/7] implement double string separation --- lua/telescope-live-grep-args/actions/tokenize.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lua/telescope-live-grep-args/actions/tokenize.lua b/lua/telescope-live-grep-args/actions/tokenize.lua index 4426d2a..6511445 100644 --- a/lua/telescope-live-grep-args/actions/tokenize.lua +++ b/lua/telescope-live-grep-args/actions/tokenize.lua @@ -29,14 +29,14 @@ return function(opts) end end - function permutations(a) + local function permutations(a) -- call with coroutine.wrap() return wrap(function() permgen(a) end) end - function removeDuplicates(tbl) + local function removeDuplicates(tbl) local newTbl = {} local seen = {} for _, value in ipairs(tbl) do @@ -54,8 +54,12 @@ return function(opts) prompt = vim.trim(prompt) end local tokens = {} - -- TODO interpret two spaces or more as a literal space + + -- Pretty sure nobody will use this as part of the prompt! + local unique_string = "" + prompt = prompt:gsub("%s%s+", unique_string) for token in prompt:gmatch("%S+") do + token = token:gsub(unique_string, " ") table.insert(tokens, token) end From 2f8dd161ed138cac596b948d187f8823799cc5c4 Mon Sep 17 00:00:00 2001 From: lytex Date: Sat, 15 Jul 2023 18:45:16 +0200 Subject: [PATCH 7/7] docs on tokenization new action --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 49a6a60..e7fe946 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ telescope.setup { i = { [""] = lga_actions.quote_prompt(), [""] = lga_actions.quote_prompt({ postfix = " --iglob " }), + [""] = lga_actions.tokenize(), }, }, -- ... also accepts theme settings, for example: @@ -126,6 +127,7 @@ This table provides some mapping ideas: | `actions.quote_prompt()` | Quote prompt | `foo` → `"foo"` | | `actions.quote_prompt({ postfix = ' --iglob ' })` | Quote prompt and add `--iglob` | `foo` → `"foo" --iglob ` | | `actions.quote_prompt({ postfix = ' -t' })` | Quote prompt and add `-t` | `foo` → `"foo" -t` | +| `actions.tokenize()` | "Fuzzy" tokenized search split by single space | `two words` → `words.*two|two.*words` | ## Development