# Copyright 2010-present Greg Hurrell. All rights reserved.
# Licensed under the terms of the BSD 2-clause license.

module CommandT
  class Scanner
    # Returns a list of all open buffers.
    class BufferScanner < Scanner
      include PathUtilities

      def paths
        (0..(::VIM::Buffer.count - 1)).map do |n|
          buffer = ::VIM::Buffer[n]
          # Beware, name may be nil, and on Neovim unlisted buffers (like
          # Command-T's match listing itself) will be returned and must be
          # skipped.
          if buffer.name && ::VIM::evaluate("buflisted(#{buffer.number})") != 0
            relative_path_under_working_directory buffer.name
          end
        end.compact
      end
    end
  end
end

# Copyright 2010-present Greg Hurrell. All rights reserved.
# Licensed under the terms of the BSD 2-clause license.

module CommandT
  class Scanner
    # Returns a list of all open buffers.
    class BufferScanner < Scanner
      include PathUtilities

      def paths
        VIM.capture('silent ls').scan(/\n\s*(\d+)[^\n]+/).map do |n|
          number = n[0].to_i
          name = ::VIM.evaluate("bufname(#{number})")
          relative_path_under_working_directory(name) unless name == ''
        end.compact
      end
    end
  end
end

Work around pathologically slow buffer scanning in Neovim
Work around pathologically slow buffer scanning in Neovim

In Neovim, unlisted buffers are returned to the Ruby layer. If you run
Ferret's :Ack, for example, you might find yourself with a large number
of those (as `:h unlisted-buffer` says, Vim uses these to track things
like file names). As such, it is too easy to wind up with a *huge*
number of unlisted buffers, and the scanner takes forever.

This is exacerbated by the scanner being called on every keypress.

Fix the slow processing by avoiding use of `VIM::Buffer` entirely, and
instead call out to native Vim commands.

This alone makes it usable again. In a follow-up commit I'll do the
"right" thing and make it not call the scanner repeatedly during a
single invocation.
