diff options
| author | TJ DeVries <devries.timothyj@gmail.com> | 2021-01-11 13:29:37 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-11 13:29:37 -0500 |
| commit | 8783bea06e1e0dfa8dfd4834058923088471d832 (patch) | |
| tree | 050096ba649a94bb01e7c0b3a029e9b4eb060029 /lua/telescope/pickers | |
| parent | de80a9837cd1d207981c1f6dbf504436f8bfee13 (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.lua | 187 | ||||
| -rw-r--r-- | lua/telescope/pickers/_test_helpers.lua | 12 | ||||
| -rw-r--r-- | lua/telescope/pickers/highlights.lua | 23 | ||||
| -rw-r--r-- | lua/telescope/pickers/scroller.lua | 93 |
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 |
