command-t 1.11.4 → 1.12

Sign up to get free protection for your applications and to get access to all the features.
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