Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add "list" finder #408

Merged
merged 7 commits into from
Sep 18, 2022
Merged

feat: add "list" finder #408

merged 7 commits into from
Sep 18, 2022

Conversation

wincent
Copy link
Owner

@wincent wincent commented Sep 16, 2022

Allows you to pass in an arbitrary list of candidates into a scanner.

Includes some refactorings of scanners/finders in general.

Will look into further refactoring to potentially implement existing scanners/finders in terms of either the list finder (eg. CommandTHelp, CommandTBuffer) or the command finder (eg. CommandTGit, CommandTFind etc).

This probably isn't the final API, but wanted to show how you could add
an arbitrary scanner + finder that lets you supply a list of candidates
and then implement a pretty novel "open"-ing scheme.

    local has_commandt, commandt = pcall(require, 'wincent.commandt')
    if has_commandt then
      commandt.setup({

        -- Demo: mimic the old CommandTLine scanner + finder.
        finders = {
          line = {
            candidates = function()
              local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
              local result = {}
              for i, line in ipairs(lines) do
                -- Skip blank/empty lines.
                if not line:match('^%s*$') then
                  table.insert(result, vim.trim(line) .. ':' .. tostring(i))
                end
              end
              return result
            end,
            open = function(item, _kind)
              -- Extract line number from (eg) "some line contents:100".
              local suffix = string.find(item, "%d+$")
              local index = tonumber(item:sub(suffix))
              vim.api.nvim_win_set_cursor(0, {index, 0})
            end,
          },
        },
      })

      -- :CommandTLines (named so as not to clash with :CommandTLine).
      vim.api.nvim_create_user_command('CommandTLines', function(command)
        require('wincent.commandt').finder('line', command.args)
      end, {
        nargs = 0,
      })
    end
This is desirable for two reasons:

1. Consistency with how we call the `command` scanner.
2. It allows a `command` scanner to implement custom `open` logic too.
Sorry for the uselessly abstract subject line. What's actually happening
here is this:

- Move `fnameescape()` call into `commandt.open()`. The only finder that
  won't use this is the `help` one, which provides its own. Everything
  else can assume it is working with files.
- Hoist `commandt.open()` up into a local `open` variable so it can be
  declared before `default_option` ans assigned there; note that we're
  getting rid of one layer of indirection here.
- Simplify most finders, now that they don't need to call
  `fnameescape()` themselves.
Replaces 5 custom finders/scanners with default config that just calls
the list and command scanners. Primary motivation here is to dogfood the
extension mechanisms, but the obvious secondary benefit is that it DRYs
up a lot of duplication.

This breaks the scanner benchmarks so I've commented them out. I will
fix them in the next commit (or soon after).
These are obviously fragile because they repeat a fair chunk of the
implementation of each scanner. I wanted to avoid requiring the main
`init.lua` file, but I might try that out anyway in the next commit as I
suspect it will be the lesser of two evils.
More duplication in the stubbing (which is fine), and less duplication
in the scanner set-up (which is good to reduce, because we don't want
this drifting out of sync).
@wincent wincent merged commit f6a6cf7 into main Sep 18, 2022
@wincent wincent deleted the wincent/list-finder branch September 18, 2022 09:42
@wincent wincent restored the wincent/list-finder branch September 18, 2022 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant