Add support for MRU buffer ordering

Originally submitted at:

  https://github.com/wincent/Command-T/pull/50

Modifications from the original pull request:

- rebased (controller has changed quite a bit in the meantime)
- removed duplicate definition of `#list_matches` method
- replaced some `and`/`not` with `&&` and `!`
- broke a long ternary across multiple lines

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Add missing copyright headers

Signed-off-by: Wincent Colaiuta <win@wincent.com>
doc: Add Ton van den Heuvel to AUTHORS section

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Get rid of $scanner global variable

Move the concern of tracking MRU buffers out of the MruBufferScanner and
into a dedicated module, thus eliminating the $scanner global variable.

It's true that the new (singleton) MRU module is a global in disguise,
but at least it is a namespaced global which means that we're not
polluting the Ruby environment that other plug-ins might be operating in
with additional variables.

As a bonus, this allows us to keep some noise out of the scanner, and
encapsulate it in a well-contained module with a single purpose.

Also, this means that we track seen buffers from the very beginning, as
soon as the plug-in is loaded. Previously, tracking would only start as
a side effect of a call to the `#list_matches` method in the controller
(because it calls `#buffer_finder`, which instantiates the
MruBufferFinder and memoizes it).

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Fix some cosmetic typos

Noticed while refactoring the MRU buffer code.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Add missing method to CommandT::Stub

Noticed while refactoring the MRU buffer code.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Improve diagnostic info in CommandT::Stub error message

Was looking at this file while refactoring the MRU buffer code; took the
opportunity to leave it better. Hopefully this is the first of several
improvements that will make it easier to troubleshoot installation woes.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Make MruBufferFinder inherit from BufferFinder

Even though they don't share any code, they are conceptually related
(there is a stronger "is a" relationship between the MruBufferFinder and
the BufferFinder than there is between the MruBufferFinder and the
abstract Finder superclass).

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Make the MRU buffer stack an actual stack

It was really being used as a queue; if we're going to call it a stack,
let's make it one for consistency.

The added `#reverse` may look like we're doing more work here, but
getting rid of the repeated `#unshift` operations probably make this a
net win.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Make MruBufferScanner inherit from BufferScanner

Much like we did for the MruBufferFinder, make the MruBufferScanner
inherit from the BufferScanner, and for the same reasons.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Rename Mru -> MRU

For consistency, let's use "MRU" consistently over "Mru", because it is
more idiomatic.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Drop an unnecessary `#compact` call

We `#compact` further down in the method, so this first call isn't
necessary.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Split MRU functionality into separate command

Instead of having an option that changes the behavior of the existing
buffer finder, make a separate command so you can do either
`:CommandTBuffer` or `:CommandTMRU`.

If a user prefers the MRU approach, they can bind the existing buffer
finder to something else:

  nnoremap <silent> <leader>f :CommentTBuffer<CR>
  nnoremap <silent> <leader>b :CommentTMRU<CR>

(or similar...)

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Work around missing matches_for method

Back when the MRU pull request was submitted there used to be a
matches_for method. It went away during some performance optimizations
around the time of the move towards phtreads.

Make it so that `sorted_matches_for` can optionally take an override for
how things should be sorted.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Teach MRU module to ignore unlisted buffers

The MRU module itself feels like a better place to put this concern.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Update docs with info about :CommandTMRU

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Merge branch 'mru_buffer_ordering' into next

* mru_buffer_ordering:
  Update docs with info about :CommandTMRU
  Teach MRU module to ignore unlisted buffers
  Work around missing matches_for method
  Split MRU functionality into separate command
  Drop an unnecessary `#compact` call
  Rename Mru -> MRU
  Make MruBufferScanner inherit from BufferScanner
  Make the MRU buffer stack an actual stack
  Make MruBufferFinder inherit from BufferFinder
  Improve diagnostic info in CommandT::Stub error message
  Add missing method to CommandT::Stub
  Fix some cosmetic typos
  Get rid of $scanner global variable
  doc: Add Ton van den Heuvel to AUTHORS section
  Add missing copyright headers
  Add support for MRU buffer ordering
Only move MRU results if appropriate

We had a bug where we would unconditionally move the first search result
to the end, thinking that it was the current buffer.

This is not necessarily always for the case. For example, if I've
visited:

  foo1
  foo2
  bar
  baz

in that order, then it's correct to move baz to the end of the list. But
if I filter my query by typing "f", only "foo1" and "foo2" will be
shown, and it would be incorrect to attempt moving either of them.

I think this bug was likely present in the original pull request too --
although it was moving the selection rather than moving items within the
list -- but I didn't notice it.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Merge branch 'master' into next

* master:
  Update docs for 1.8 release

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Never overwrite other mappings

Use `maparg()` to ensure we don't ever overwrite existing mappings.
There's also `mapcheck()` which will find partial matches, but I think
the more stricter check is appropriate here (`mapcheck()` is good for
finding prefix collisions which could make mappings slow).

Signed-off-by: Greg Hurrell <greg@hurrell.net>