command-t 1.11.4 → 1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.txt +128 -39
  4. data/Rakefile +2 -18
  5. data/doc/command-t.txt +128 -39
  6. data/doc/tags +6 -1
  7. data/plugin/command-t.vim +7 -10
  8. data/ruby/command-t.rb +17 -0
  9. data/ruby/command-t/Makefile +8 -8
  10. data/ruby/command-t/controller.rb +89 -22
  11. data/ruby/command-t/ext.bundle +0 -0
  12. data/ruby/command-t/finder.rb +8 -2
  13. data/ruby/command-t/finder/buffer_finder.rb +8 -10
  14. data/ruby/command-t/finder/file_finder.rb +22 -27
  15. data/ruby/command-t/finder/jump_finder.rb +8 -10
  16. data/ruby/command-t/finder/mru_buffer_finder.rb +20 -22
  17. data/ruby/command-t/finder/tag_finder.rb +18 -20
  18. data/ruby/command-t/match_window.rb +30 -13
  19. data/ruby/command-t/path_utilities.rb +17 -0
  20. data/ruby/command-t/prompt.rb +1 -1
  21. data/ruby/command-t/scanner.rb +7 -3
  22. data/ruby/command-t/scanner/buffer_scanner.rb +14 -15
  23. data/ruby/command-t/scanner/file_scanner.rb +75 -66
  24. data/ruby/command-t/scanner/file_scanner/file_limit_exceeded.rb +10 -0
  25. data/ruby/command-t/scanner/file_scanner/find_file_scanner.rb +38 -38
  26. data/ruby/command-t/scanner/file_scanner/git_file_scanner.rb +46 -26
  27. data/ruby/command-t/scanner/file_scanner/ruby_file_scanner.rb +43 -43
  28. data/ruby/command-t/scanner/file_scanner/watchman_file_scanner.rb +46 -46
  29. data/ruby/command-t/scanner/jump_scanner.rb +22 -23
  30. data/ruby/command-t/scanner/mru_buffer_scanner.rb +20 -21
  31. data/ruby/command-t/scanner/tag_scanner.rb +23 -23
  32. data/ruby/command-t/scm_utilities.rb +22 -0
  33. data/ruby/command-t/settings.rb +0 -2
  34. data/ruby/command-t/util.rb +1 -1
  35. data/ruby/command-t/vim.rb +3 -3
  36. data/ruby/command-t/watchman.c +0 -15
  37. metadata +6 -3
  38. data/ruby/command-t/vim/path_utilities.rb +0 -34
@@ -0,0 +1,10 @@
1
+ # Copyright 2014 Greg Hurrell. All rights reserved.
2
+ # Licensed under the terms of the BSD 2-clause license.
3
+
4
+ module CommandT
5
+ class Scanner
6
+ class FileScanner
7
+ FileLimitExceeded = Class.new(::RuntimeError)
8
+ end # class FileScanner
9
+ end # class Scanner
10
+ end # module Command-T
@@ -2,49 +2,49 @@
2
2
  # Licensed under the terms of the BSD 2-clause license.
3
3
 
4
4
  require 'open3'
5
- require 'command-t/vim/path_utilities'
6
- require 'command-t/scanner/file_scanner'
7
5
 
8
6
  module CommandT
9
- class FileScanner
10
- # A FileScanner which shells out to the `find` executable in order to scan.
11
- class FindFileScanner < FileScanner
12
- include VIM::PathUtilities
7
+ class Scanner
8
+ class FileScanner
9
+ # A FileScanner which shells out to the `find` executable in order to scan.
10
+ class FindFileScanner < FileScanner
11
+ include PathUtilities
13
12
 
14
- def paths!
15
- # temporarily set field separator to NUL byte; this setting is
16
- # respected by both `readlines` and `chomp!` below, and makes it easier
17
- # to parse the output of `find -print0`
18
- separator = $/
19
- $/ = "\x00"
13
+ def paths!
14
+ # temporarily set field separator to NUL byte; this setting is
15
+ # respected by both `readlines` and `chomp!` below, and makes it easier
16
+ # to parse the output of `find -print0`
17
+ separator = $/
18
+ $/ = "\x00"
20
19
 
21
- unless @scan_dot_directories
22
- dot_directory_filter = [
23
- '-not', '-path', "#{@path}/.*/*", # top-level dot dir
24
- '-and', '-not', '-path', "#{@path}/*/.*/*" # lower-level dot dir
25
- ]
26
- end
20
+ unless @scan_dot_directories
21
+ dot_directory_filter = [
22
+ '-not', '-path', "#{@path}/.*/*", # top-level dot dir
23
+ '-and', '-not', '-path', "#{@path}/*/.*/*" # lower-level dot dir
24
+ ]
25
+ end
27
26
 
28
- paths = []
29
- Open3.popen3(*([
30
- 'find', '-L', # follow symlinks
31
- @path, # anchor search here
32
- '-maxdepth', @max_depth.to_s, # limit depth of DFS
33
- '-type', 'f', # only show regular files (not dirs etc)
34
- dot_directory_filter, # possibly skip out dot directories
35
- '-print0' # NUL-terminate results
36
- ].flatten.compact)) do |stdin, stdout, stderr|
37
- counter = 1
38
- stdout.readlines.each do |line|
39
- next if path_excluded?(line.chomp!)
40
- paths << line[@prefix_len..-1]
41
- break if (counter += 1) > @max_files
27
+ paths = []
28
+ Open3.popen3(*([
29
+ 'find', '-L', # follow symlinks
30
+ @path, # anchor search here
31
+ '-maxdepth', @max_depth.to_s, # limit depth of DFS
32
+ '-type', 'f', # only show regular files (not dirs etc)
33
+ dot_directory_filter, # possibly skip out dot directories
34
+ '-print0' # NUL-terminate results
35
+ ].flatten.compact)) do |stdin, stdout, stderr|
36
+ counter = 1
37
+ stdout.readlines.each do |line|
38
+ next if path_excluded?(line.chomp!)
39
+ paths << line[@prefix_len..-1]
40
+ break if (counter += 1) > @max_files
41
+ end
42
42
  end
43
+ paths
44
+ ensure
45
+ $/ = separator
43
46
  end
44
- paths
45
- ensure
46
- $/ = separator
47
- end
48
- end # class FindFileScanner
49
- end # class FileScanner
47
+ end # class FindFileScanner
48
+ end # class FileScanner
49
+ end # class Scanner
50
50
  end # module CommandT
@@ -1,34 +1,54 @@
1
1
  # Copyright 2014 Greg Hurrell. All rights reserved.
2
2
  # Licensed under the terms of the BSD 2-clause license.
3
3
 
4
- require 'command-t/scanner/file_scanner/find_file_scanner'
5
-
6
4
  module CommandT
7
- class FileScanner
8
- # Uses git ls-files to scan for files
9
- class GitFileScanner < FindFileScanner
10
- def paths!
11
- Dir.chdir(@path) do
12
- stdin, stdout, stderr = Open3.popen3(*[
13
- 'git',
14
- 'ls-files',
15
- '--exclude-standard',
16
- @path
17
- ])
5
+ class Scanner
6
+ class FileScanner
7
+ # Uses git ls-files to scan for files
8
+ class GitFileScanner < FindFileScanner
9
+ LsFilesError = Class.new(::RuntimeError)
10
+
11
+ def paths!
12
+ Dir.chdir(@path) do
13
+ all_files = list_files(%w[git ls-files --exclude-standard -z])
14
+
15
+ if @scan_submodules
16
+ base = nil
17
+ list_files(%w[
18
+ git submodule foreach --recursive
19
+ git ls-files --exclude-standard -z
20
+ ]).each do |path|
21
+ if path =~ /\AEntering '(.*)'\n(.*)\z/
22
+ base = $~[1]
23
+ path = $~[2]
24
+ end
25
+ all_files.push(base + File::SEPARATOR + path)
26
+ end
27
+ end
18
28
 
19
- all_files = stdout.readlines.
20
- map { |path| path.chomp }.
21
- reject { |path| path_excluded?(path, 0) }.
22
- take(@max_files).
23
- to_a
29
+ all_files.
30
+ map { |path| path.chomp }.
31
+ reject { |path| path_excluded?(path, 0) }.
32
+ take(@max_files).
33
+ to_a
34
+ end
35
+ rescue LsFilesError
36
+ super
37
+ rescue Errno::ENOENT
38
+ # git executable not present and executable
39
+ super
40
+ end
41
+
42
+ private
24
43
 
25
- # will fall back to find if not a git repository or there's an error
26
- stderr.gets ? super : all_files
44
+ def list_files(command)
45
+ stdin, stdout, stderr = Open3.popen3(*command)
46
+ stdout.read.split("\0")
47
+ ensure
48
+ raise LsFilesError if stderr && stderr.gets
27
49
  end
28
- rescue Errno::ENOENT => e
29
- # git executable not present and executable
30
- super
31
- end
32
- end # class GitFileScanner
33
- end # class FileScanner
50
+
51
+ end # class GitFileScanner
52
+ end # class FileScanner
53
+ end # class Scanner
34
54
  end # module CommandT
@@ -1,55 +1,55 @@
1
1
  # Copyright 2010-2014 Greg Hurrell. All rights reserved.
2
2
  # Licensed under the terms of the BSD 2-clause license.
3
3
 
4
- require 'command-t/scanner/file_scanner'
5
-
6
4
  module CommandT
7
- class FileScanner
8
- # Pure Ruby implementation of a file scanner.
9
- class RubyFileScanner < FileScanner
10
- def paths!
11
- accumulator = []
12
- @depth = 0
13
- @files = 0
14
- add_paths_for_directory(@path, accumulator)
15
- accumulator
16
- rescue FileLimitExceeded
17
- accumulator
18
- end
5
+ class Scanner
6
+ class FileScanner
7
+ # Pure Ruby implementation of a file scanner.
8
+ class RubyFileScanner < FileScanner
9
+ def paths!
10
+ accumulator = []
11
+ @depth = 0
12
+ @files = 0
13
+ add_paths_for_directory(@path, accumulator)
14
+ accumulator
15
+ rescue FileLimitExceeded
16
+ accumulator
17
+ end
19
18
 
20
- private
19
+ private
21
20
 
22
- def looped_symlink?(path)
23
- if File.symlink?(path)
24
- target = File.expand_path(File.readlink(path), File.dirname(path))
25
- target.include?(@path) || @path.include?(target)
21
+ def looped_symlink?(path)
22
+ if File.symlink?(path)
23
+ target = File.expand_path(File.readlink(path), File.dirname(path))
24
+ target.include?(@path) || @path.include?(target)
25
+ end
26
26
  end
27
- end
28
27
 
29
- def add_paths_for_directory(dir, accumulator)
30
- Dir.foreach(dir) do |entry|
31
- next if ['.', '..'].include?(entry)
32
- path = File.join(dir, entry)
33
- unless path_excluded?(path)
34
- if File.file?(path)
35
- @files += 1
36
- raise FileLimitExceeded if @files > @max_files
37
- accumulator << path[@prefix_len..-1]
38
- elsif File.directory?(path)
39
- next if @depth >= @max_depth
40
- next if (entry.match(/\A\./) && !@scan_dot_directories)
41
- next if looped_symlink?(path)
42
- @depth += 1
43
- add_paths_for_directory(path, accumulator)
44
- @depth -= 1
28
+ def add_paths_for_directory(dir, accumulator)
29
+ Dir.foreach(dir) do |entry|
30
+ next if ['.', '..'].include?(entry)
31
+ path = File.join(dir, entry)
32
+ unless path_excluded?(path)
33
+ if File.file?(path)
34
+ @files += 1
35
+ raise FileLimitExceeded if @files > @max_files
36
+ accumulator << path[@prefix_len..-1]
37
+ elsif File.directory?(path)
38
+ next if @depth >= @max_depth
39
+ next if (entry.match(/\A\./) && !@scan_dot_directories)
40
+ next if looped_symlink?(path)
41
+ @depth += 1
42
+ add_paths_for_directory(path, accumulator)
43
+ @depth -= 1
44
+ end
45
45
  end
46
46
  end
47
+ rescue Errno::EACCES
48
+ # skip over directories for which we don't have access
49
+ rescue ArgumentError
50
+ # skip over bad file names
47
51
  end
48
- rescue Errno::EACCES
49
- # skip over directories for which we don't have access
50
- rescue ArgumentError
51
- # skip over bad file names
52
- end
53
- end # class RubyFileScanner
54
- end # class FileScanner
52
+ end # class RubyFileScanner
53
+ end # class FileScanner
54
+ end # class Scanner
55
55
  end # module CommandT
@@ -3,54 +3,54 @@
3
3
 
4
4
  require 'pathname'
5
5
  require 'socket'
6
- require 'command-t/vim/path_utilities'
7
- require 'command-t/scanner/file_scanner'
8
- require 'command-t/scanner/file_scanner/find_file_scanner'
9
6
 
10
7
  module CommandT
11
- class FileScanner
12
- # A FileScanner which delegates the heavy lifting to Watchman
13
- # (https://github.com/facebook/watchman); useful for very large hierarchies.
14
- #
15
- # Inherits from FindFileScanner so that it can fall back to it in the event
16
- # that Watchman isn't available or able to fulfil the request.
17
- class WatchmanFileScanner < FindFileScanner
18
- # Exception raised when Watchman is unavailable or unable to process the
19
- # requested path.
20
- class WatchmanUnavailable < RuntimeError; end
21
-
22
- def paths!
23
- sockname = Watchman::Utils.load(
24
- %x{watchman --output-encoding=bser get-sockname}
25
- )['sockname']
26
- raise WatchmanUnavailable unless $?.exitstatus.zero?
27
-
28
- UNIXSocket.open(sockname) do |socket|
29
- root = Pathname.new(@path).realpath.to_s
30
- roots = Watchman::Utils.query(['watch-list'], socket)['roots']
31
- if !roots.include?(root)
32
- # this path isn't being watched yet; try to set up watch
33
- result = Watchman::Utils.query(['watch', root], socket)
34
-
35
- # root_restrict_files setting may prevent Watchman from working
36
- raise WatchmanUnavailable if result.has_key?('error')
8
+ class Scanner
9
+ class FileScanner
10
+ # A FileScanner which delegates the heavy lifting to Watchman
11
+ # (https://github.com/facebook/watchman); useful for very large hierarchies.
12
+ #
13
+ # Inherits from FindFileScanner so that it can fall back to it in the event
14
+ # that Watchman isn't available or able to fulfil the request.
15
+ class WatchmanFileScanner < FindFileScanner
16
+ # Exception raised when Watchman is unavailable or unable to process the
17
+ # requested path.
18
+ WatchmanError = Class.new(::RuntimeError)
19
+
20
+ def paths!
21
+ sockname = Watchman::Utils.load(
22
+ %x{watchman --output-encoding=bser get-sockname}
23
+ )['sockname']
24
+ raise WatchmanError, 'get-sockname failed' unless $?.exitstatus.zero?
25
+
26
+ UNIXSocket.open(sockname) do |socket|
27
+ root = Pathname.new(@path).realpath.to_s
28
+ roots = Watchman::Utils.query(['watch-list'], socket)['roots']
29
+ if !roots.include?(root)
30
+ # this path isn't being watched yet; try to set up watch
31
+ result = Watchman::Utils.query(['watch', root], socket)
32
+
33
+ # root_restrict_files setting may prevent Watchman from working
34
+ # or enforce_root_files/root_files (>= version 3.1)
35
+ raise WatchmanError, result['error'] if result.has_key?('error')
36
+ end
37
+
38
+ query = ['query', root, {
39
+ 'expression' => ['type', 'f'],
40
+ 'fields' => ['name'],
41
+ }]
42
+ paths = Watchman::Utils.query(query, socket)
43
+
44
+ # could return error if watch is removed
45
+ raise WatchmanError, paths['error'] if paths.has_key?('error')
46
+
47
+ paths['files']
37
48
  end
38
-
39
- query = ['query', root, {
40
- 'expression' => ['type', 'f'],
41
- 'fields' => ['name'],
42
- }]
43
- paths = Watchman::Utils.query(query, socket)
44
-
45
- # could return error if watch is removed
46
- raise WatchmanUnavailable if paths.has_key?('error')
47
-
48
- paths['files']
49
+ rescue Errno::ENOENT, WatchmanError
50
+ # watchman executable not present, or unable to fulfil request
51
+ super
49
52
  end
50
- end
51
- rescue Errno::ENOENT, WatchmanUnavailable
52
- # watchman executable not present, or unable to fulfil request
53
- super
54
- end # class WatchmanFileScanner
55
- end # class FileScanner
53
+ end # class WatchmanFileScanner
54
+ end # class FileScanner
55
+ end # class Scanner
56
56
  end # module CommandT
@@ -1,33 +1,32 @@
1
1
  # Copyright 2011-2014 Greg Hurrell. All rights reserved.
2
2
  # Licensed under the terms of the BSD 2-clause license.
3
3
 
4
- require 'command-t/vim/path_utilities'
5
- require 'command-t/scanner'
6
-
7
4
  module CommandT
8
- # Returns a list of files in the jumplist.
9
- class JumpScanner < Scanner
10
- include VIM::PathUtilities
5
+ class Scanner
6
+ # Returns a list of files in the jumplist.
7
+ class JumpScanner < Scanner
8
+ include PathUtilities
11
9
 
12
- def paths
13
- jumps_with_filename = jumps.lines.select do |line|
14
- line_contains_filename?(line)
15
- end
16
- filenames = jumps_with_filename[1..-2].map do |line|
17
- relative_path_under_working_directory line.split[3]
18
- end
10
+ def paths
11
+ jumps_with_filename = jumps.lines.select do |line|
12
+ line_contains_filename?(line)
13
+ end
14
+ filenames = jumps_with_filename[1..-2].map do |line|
15
+ relative_path_under_working_directory line.split[3]
16
+ end
19
17
 
20
- filenames.sort.uniq
21
- end
18
+ filenames.sort.uniq
19
+ end
22
20
 
23
- private
21
+ private
24
22
 
25
- def line_contains_filename?(line)
26
- line.split.count > 3
27
- end
23
+ def line_contains_filename?(line)
24
+ line.split.count > 3
25
+ end
28
26
 
29
- def jumps
30
- VIM::capture 'silent jumps'
31
- end
32
- end # class JumpScanner
27
+ def jumps
28
+ VIM::capture 'silent jumps'
29
+ end
30
+ end # class JumpScanner
31
+ end # class Scanner
33
32
  end # module CommandT
@@ -1,28 +1,27 @@
1
1
  # Copyright 2014 Greg Hurrell. All rights reserved.
2
2
  # Licensed under the terms of the BSD 2-clause license.
3
3
 
4
- require 'command-t/vim/path_utilities'
5
- require 'command-t/scanner/buffer_scanner'
6
-
7
4
  module CommandT
8
- # Returns a list of all open buffers, sorted in MRU order.
9
- class MRUBufferScanner < BufferScanner
10
- include VIM::PathUtilities
11
-
12
- def paths
13
- # Collect all buffers that have not been used yet.
14
- unused_buffers = (0..(::VIM::Buffer.count - 1)).map do |n|
15
- buffer = ::VIM::Buffer[n]
16
- buffer if buffer.name && !MRU.used?(buffer)
17
- end
5
+ class Scanner
6
+ # Returns a list of all open buffers, sorted in MRU order.
7
+ class MRUBufferScanner < BufferScanner
8
+ include PathUtilities
18
9
 
19
- # Combine all most recently used buffers and all unused buffers, and
20
- # return all listed buffer paths.
21
- (unused_buffers + MRU.stack).map do |buffer|
22
- if buffer && buffer.name
23
- relative_path_under_working_directory buffer.name
10
+ def paths
11
+ # Collect all buffers that have not been used yet.
12
+ unused_buffers = (0..(::VIM::Buffer.count - 1)).map do |n|
13
+ buffer = ::VIM::Buffer[n]
14
+ buffer if buffer.name && !MRU.used?(buffer)
24
15
  end
25
- end.compact.reverse
26
- end
27
- end # class MRUBufferScanner
16
+
17
+ # Combine all most recently used buffers and all unused buffers, and
18
+ # return all listed buffer paths.
19
+ (unused_buffers + MRU.stack).map do |buffer|
20
+ if buffer && buffer.name
21
+ relative_path_under_working_directory buffer.name
22
+ end
23
+ end.compact.reverse
24
+ end
25
+ end # class MRUBufferScanner
26
+ end # class Scanner
28
27
  end # module CommandT