summaryrefslogtreecommitdiff
path: root/lua/telescope/pickers
diff options
context:
space:
mode:
authorTJ DeVries <devries.timothyj@gmail.com>2021-01-11 13:29:37 -0500
committerGitHub <noreply@github.com>2021-01-11 13:29:37 -0500
commit8783bea06e1e0dfa8dfd4834058923088471d832 (patch)
tree050096ba649a94bb01e7c0b3a029e9b4eb060029 /lua/telescope/pickers
parentde80a9837cd1d207981c1f6dbf504436f8bfee13 (diff)
feat: quickfix (#293)
* feat: quickfix (not implemented) * [WIP]: Wed 09 Dec 2020 11:11:30 PM EST * somewhat working linked list impl * getting closer * might be working * might be working for real * works and implemented basic example * dont forget to close prompt * fix descending and add more tests * test fixes * fix test * more logging * Fix some more tests * Fix logging messing up tests * fix: lint * fix: multi select stuffs
Diffstat (limited to 'lua/telescope/pickers')
-rw-r--r--lua/telescope/pickers/_test.lua187
-rw-r--r--lua/telescope/pickers/_test_helpers.lua12
-rw-r--r--lua/telescope/pickers/highlights.lua23
-rw-r--r--lua/telescope/pickers/scroller.lua93
4 files changed, 231 insertions, 84 deletions
diff --git a/lua/telescope/pickers/_test.lua b/lua/telescope/pickers/_test.lua
index ddd245a..1ab5a97 100644
--- a/lua/telescope/pickers/_test.lua
+++ b/lua/telescope/pickers/_test.lua
@@ -1,10 +1,14 @@
local assert = require('luassert')
local builtin = require('telescope.builtin')
+local log = require('telescope.log')
local Job = require("plenary.job")
+local Path = require("plenary.path")
local tester = {}
+tester.debug = false
+
local replace_terms = function(input)
return vim.api.nvim_replace_termcodes(input, true, false, true)
end
@@ -15,7 +19,53 @@ local nvim_feed = function(text, feed_opts)
vim.api.nvim_feedkeys(text, feed_opts, true)
end
-tester.picker_feed = function(input, test_cases, debug)
+local writer = function(val)
+ if type(val) == "table" then
+ val = vim.fn.json_encode(val) .. "\n"
+ end
+
+ if tester.debug then
+ print(val)
+ else
+ io.stderr:write(val)
+ end
+end
+
+local execute_test_case = function(location, key, spec)
+ local ok, actual = pcall(spec[2])
+
+ if not ok then
+ writer {
+ location = 'Error: ' .. location,
+ case = key,
+ expected = 'To succeed and return: ' .. tostring(spec[1]),
+ actual = actual,
+
+ _type = spec._type,
+ }
+ else
+ writer {
+ location = location,
+ case = key,
+ expected = spec[1],
+ actual = actual,
+
+ _type = spec._type,
+ }
+ end
+end
+
+local end_test_cases = function()
+ vim.cmd [[qa!]]
+end
+
+local invalid_test_case = function(k)
+ writer { case = k, expected = '<a valid key>', actual = k }
+
+ end_test_cases()
+end
+
+tester.picker_feed = function(input, test_cases)
input = replace_terms(input)
return coroutine.wrap(function()
@@ -28,75 +78,66 @@ tester.picker_feed = function(input, test_cases, debug)
if string.match(char, "%g") then
coroutine.yield()
end
+
+ if tester.debug then
+ vim.wait(200)
+ end
end
- vim.wait(10, function() end)
+ vim.wait(10)
+
+ if tester.debug then
+ coroutine.yield()
+ end
- local timer = vim.loop.new_timer()
- timer:start(20, 0, vim.schedule_wrap(function()
+ vim.defer_fn(function()
+ if test_cases.post_typed then
+ for k, v in ipairs(test_cases.post_typed) do
+ execute_test_case('post_typed', k, v)
+ end
+ end
+
+ nvim_feed(replace_terms("<CR>"), "")
+ end, 20)
+
+ vim.defer_fn(function()
if test_cases.post_close then
for k, v in ipairs(test_cases.post_close) do
- io.stderr:write(vim.fn.json_encode({ case = k, expected = v[1], actual = v[2]() }))
- io.stderr:write("\n")
+ execute_test_case('post_close', k, v)
end
end
- if debug then
+ if tester.debug then
return
end
- vim.defer_fn(function()
- vim.cmd [[qa!]]
- end, 10)
- end))
-
- if not debug then
- vim.schedule(function()
- if test_cases.post_typed then
- for k, v in ipairs(test_cases.post_typed) do
- io.stderr:write(vim.fn.json_encode({ case = k, expected = v[1], actual = v[2]() }))
- io.stderr:write("\n")
- end
- end
+ vim.defer_fn(end_test_cases, 20)
+ end, 40)
- nvim_feed(replace_terms("<CR>"), "")
- end)
- end
coroutine.yield()
end)
end
--- local test_cases = {
--- post_typed = {
--- },
--- post_close = {
--- { "README.md", function() return "README.md" end },
--- },
--- }
-
local _VALID_KEYS = {
post_typed = true,
post_close = true,
}
-tester.builtin_picker = function(key, input, test_cases, opts)
+tester.builtin_picker = function(builtin_key, input, test_cases, opts)
opts = opts or {}
- local debug = opts.debug or false
+ tester.debug = opts.debug or false
for k, _ in pairs(test_cases) do
if not _VALID_KEYS[k] then
- -- TODO: Make an error type for the json protocol.
- io.stderr:write(vim.fn.json_encode({ case = k, expected = '<a valid key>', actual = k }))
- io.stderr:write("\n")
- vim.cmd [[qa!]]
+ return invalid_test_case(k)
end
end
opts.on_complete = {
- tester.picker_feed(input, test_cases, debug)
+ tester.picker_feed(input, test_cases),
}
- builtin[key](opts)
+ builtin[builtin_key](opts)
end
local get_results_from_file = function(file)
@@ -107,11 +148,14 @@ local get_results_from_file = function(file)
'-u',
'scripts/minimal_init.vim',
'-c',
- 'luafile ' .. file
+ string.format(
+ [[lua require("telescope.pickers._test")._execute("%s")]],
+ file
+ ),
},
}
- j:sync()
+ j:sync(1000)
local results = j:stderr_result()
local result_table = {}
@@ -122,10 +166,27 @@ local get_results_from_file = function(file)
return result_table
end
+
+local asserters = {
+ _default = assert.are.same,
+
+ are = assert.are.same,
+ are_not = assert.are_not.same,
+}
+
+
local check_results = function(results)
-- TODO: We should get all the test cases here that fail, not just the first one.
for _, v in ipairs(results) do
- assert.are.same(v.expected, v.actual)
+ local assertion = asserters[v._type or 'default']
+
+ assertion(
+ v.expected,
+ v.actual,
+ string.format("Test Case: %s // %s",
+ v.location,
+ v.case)
+ )
end
end
@@ -144,14 +205,52 @@ tester.run_string = function(contents)
vim.fn.delete(tempname)
check_results(result_table)
- -- assert.are.same(result_table.expected, result_table.actual)
end
tester.run_file = function(filename)
local file = './lua/tests/pickers/' .. filename .. '.lua'
+ if not Path:new(file):exists() then
+ assert.are.same("<An existing file>", file)
+ end
+
local result_table = get_results_from_file(file)
- assert.are.same(result_table.expected, result_table.actual)
+
+ check_results(result_table)
end
+tester.not_ = function(val)
+ val._type = 'are_not'
+ return val
+end
+
+tester._execute = function(filename)
+ -- Important so that the outputs don't get mixed
+ log.use_console = false
+
+ vim.cmd(string.format("luafile %s", filename))
+
+ local f = loadfile(filename)
+ if not f then
+ writer {
+ location = 'Error: ' .. filename,
+ case = filename,
+ expected = 'To succeed',
+ actual = nil,
+ }
+ end
+
+ local ok, msg = pcall(f)
+ if not ok then
+ writer {
+ location = "Error: " .. msg,
+ case = msg,
+ expected = msg,
+ }
+ end
+
+ end_test_cases()
+end
+
+
return tester
diff --git a/lua/telescope/pickers/_test_helpers.lua b/lua/telescope/pickers/_test_helpers.lua
index a430fae..63d1a0f 100644
--- a/lua/telescope/pickers/_test_helpers.lua
+++ b/lua/telescope/pickers/_test_helpers.lua
@@ -22,9 +22,15 @@ test_helpers.get_results = function()
return vim.api.nvim_buf_get_lines(test_helpers.get_results_bufnr(), 0, -1, false)
end
-test_helpers.get_last_result = function()
+test_helpers.get_best_result = function()
local results = test_helpers.get_results()
- return results[#results]
+ local picker = test_helpers.get_picker ()
+
+ if picker.sorting_strategy == 'ascending' then
+ return results[1]
+ else
+ return results[#results]
+ end
end
test_helpers.get_selection = function()
@@ -41,7 +47,7 @@ test_helpers.make_globals = function()
GetPrompt = test_helpers.get_prompt -- luacheck: globals GetPrompt
GetResults = test_helpers.get_results -- luacheck: globals GetResults
- GetLastResult = test_helpers.get_last_result -- luacheck: globals GetLastResult
+ GetBestResult = test_helpers.get_best_result -- luacheck: globals GetBestResult
GetSelection = test_helpers.get_selection -- luacheck: globals GetSelection
GetSelectionValue = test_helpers.get_selection_value -- luacheck: globals GetSelectionValue
diff --git a/lua/telescope/pickers/highlights.lua b/lua/telescope/pickers/highlights.lua
index 23e796e..62ffb4b 100644
--- a/lua/telescope/pickers/highlights.lua
+++ b/lua/telescope/pickers/highlights.lua
@@ -3,6 +3,7 @@ local a = vim.api
local highlights = {}
local ns_telescope_selection = a.nvim_create_namespace('telescope_selection')
+local ns_telescope_multiselection = a.nvim_create_namespace('telescope_mulitselection')
local ns_telescope_entry = a.nvim_create_namespace('telescope_entry')
local Highlighter = {}
@@ -75,6 +76,28 @@ function Highlighter:hi_selection(row, caret)
)
end
+function Highlighter:hi_multiselect(row, entry)
+ local results_bufnr = assert(self.picker.results_bufnr, "Must have a results bufnr")
+
+ if self.picker.multi_select[entry] then
+ vim.api.nvim_buf_add_highlight(
+ results_bufnr,
+ ns_telescope_multiselection,
+ "TelescopeMultiSelection",
+ row,
+ 0,
+ -1
+ )
+ else
+ vim.api.nvim_buf_clear_namespace(
+ results_bufnr,
+ ns_telescope_multiselection,
+ row,
+ row + 1
+ )
+ end
+end
+
highlights.new = function(...)
return Highlighter:new(...)
end
diff --git a/lua/telescope/pickers/scroller.lua b/lua/telescope/pickers/scroller.lua
index 324627b..3169c4b 100644
--- a/lua/telescope/pickers/scroller.lua
+++ b/lua/telescope/pickers/scroller.lua
@@ -1,56 +1,75 @@
local scroller = {}
-local calc_count_fn = function(sorting_strategy)
- if sorting_strategy == 'ascending' then
- return function(a, b) return math.min(a, b) end
- else
- return function(a, b, row)
- if a == b or not row then
- return math.max(a, b)
- else
- local x = a - b
- if row < x then
- return math.max(a, b) - 1, true
- elseif row == a then
- return x, true
- else
- return math.max(a, b)
- end
- end
- end
- end
-end
+local range_calculators = {
+ ascending = function(max_results, num_results)
+ return 0, math.min(max_results, num_results)
+ end,
-scroller.create = function(strategy, sorting_strategy)
- local calc_count = calc_count_fn(sorting_strategy)
+ descending = function(max_results, num_results)
+ return math.max(max_results - num_results, 0), max_results
+ end,
+}
- if strategy == 'cycle' then
+local scroll_calculators = {
+ cycle = function(range_fn)
return function(max_results, num_results, row)
- local count, b = calc_count(max_results, num_results, row)
- if b then return count end
+ local start, finish = range_fn(max_results, num_results)
- if row >= count then
- return 0
- elseif row < 0 then
- return count - 1
+ if row >= finish then
+ return start
+ elseif row < start then
+ return finish - 1
end
return row
end
- elseif strategy == 'limit' or strategy == nil then
+ end,
+
+ limit = function(range_fn)
return function(max_results, num_results, row)
- local count = calc_count(max_results, num_results)
+ local start, finish = range_fn(max_results, num_results)
- if row >= count then
- return count - 1
- elseif row < 0 then
- return 0
+ if row >= finish then
+ return finish - 1
+ elseif row < start then
+ return start
end
return row
end
- else
- error("Unsupported strategy: " .. strategy)
+ end,
+}
+
+scroller.create = function(scroll_strategy, sorting_strategy)
+ local range_fn = range_calculators[sorting_strategy]
+ if not range_fn then
+ error(debug.traceback("Unknown sorting strategy: " .. sorting_strategy))
+ end
+
+ local scroll_fn = scroll_calculators[scroll_strategy]
+ if not scroll_fn then
+ error(debug.traceback("Unknown scroll strategy: " .. (scroll_strategy or '')))
+ end
+
+ local calculator = scroll_fn(range_fn)
+ return function(max_results, num_results, row)
+ local result = calculator(max_results, num_results, row)
+
+ if result < 0 then
+ error(string.format(
+ "Must never return a negative row: { result = %s, args = { %s %s %s } }",
+ result, max_results, num_results, row
+ ))
+ end
+
+ if result >= max_results then
+ error(string.format(
+ "Must never exceed max results: { result = %s, args = { %s %s %s } }",
+ result, max_results, num_results, row
+ ))
+ end
+
+ return result
end
end