command-t 3.0.2 → 4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -2
- data/doc/command-t.txt +312 -147
- data/ruby/command-t.rb +13 -12
- data/ruby/command-t/controller.rb +86 -15
- data/ruby/command-t/depend +4 -0
- data/ruby/command-t/ext.h +9 -2
- data/ruby/command-t/extconf.rb +2 -2
- data/ruby/command-t/finder.rb +6 -2
- data/ruby/command-t/finder/buffer_finder.rb +3 -3
- data/ruby/command-t/finder/command_finder.rb +23 -0
- data/ruby/command-t/finder/file_finder.rb +3 -3
- data/ruby/command-t/finder/help_finder.rb +25 -0
- data/ruby/command-t/finder/history_finder.rb +27 -0
- data/ruby/command-t/finder/jump_finder.rb +3 -3
- data/ruby/command-t/finder/line_finder.rb +23 -0
- data/ruby/command-t/finder/mru_buffer_finder.rb +3 -3
- data/ruby/command-t/finder/tag_finder.rb +3 -3
- data/ruby/command-t/heap.c +146 -0
- data/ruby/command-t/heap.h +22 -0
- data/ruby/command-t/match.c +183 -116
- data/ruby/command-t/match.h +16 -10
- data/ruby/command-t/match_window.rb +10 -1
- data/ruby/command-t/matcher.c +203 -63
- data/ruby/command-t/metadata/fallback.rb +2 -2
- data/ruby/command-t/mru.rb +2 -2
- data/ruby/command-t/path_utilities.rb +2 -2
- data/ruby/command-t/progress_reporter.rb +38 -0
- data/ruby/command-t/prompt.rb +4 -4
- data/ruby/command-t/scanner.rb +22 -2
- data/ruby/command-t/scanner/buffer_scanner.rb +3 -3
- data/ruby/command-t/scanner/command_scanner.rb +33 -0
- data/ruby/command-t/scanner/file_scanner.rb +30 -6
- data/ruby/command-t/scanner/file_scanner/find_file_scanner.rb +12 -7
- data/ruby/command-t/scanner/file_scanner/git_file_scanner.rb +11 -8
- data/ruby/command-t/scanner/file_scanner/ruby_file_scanner.rb +7 -4
- data/ruby/command-t/scanner/file_scanner/watchman_file_scanner.rb +13 -5
- data/ruby/command-t/scanner/help_scanner.rb +40 -0
- data/ruby/command-t/scanner/history_scanner.rb +24 -0
- data/ruby/command-t/scanner/jump_scanner.rb +3 -3
- data/ruby/command-t/scanner/line_scanner.rb +45 -0
- data/ruby/command-t/scanner/mru_buffer_scanner.rb +3 -3
- data/ruby/command-t/scanner/tag_scanner.rb +3 -3
- data/ruby/command-t/scm_utilities.rb +2 -2
- data/ruby/command-t/settings.rb +2 -2
- data/ruby/command-t/stub.rb +7 -2
- data/ruby/command-t/util.rb +2 -2
- data/ruby/command-t/vim.rb +27 -2
- data/ruby/command-t/vim/screen.rb +3 -3
- data/ruby/command-t/vim/window.rb +3 -3
- data/ruby/command-t/watchman.c +1 -1
- metadata +13 -2
data/ruby/command-t/mru.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright 2010-present Greg Hurrell. All rights reserved.
|
2
|
+
# Licensed under the terms of the BSD 2-clause license.
|
3
|
+
|
4
|
+
module CommandT
|
5
|
+
# Simple class for displaying scan progress to the user.
|
6
|
+
#
|
7
|
+
# The active scanner calls the `#update` method with a `count` to inform it of
|
8
|
+
# progress, the reporter updates the UI and then returns a suggested count at
|
9
|
+
# which to invoke `#update` again in the future (the suggested count is based
|
10
|
+
# on a heuristic that seeks to update the UI about 5 times per second).
|
11
|
+
class ProgressReporter
|
12
|
+
SPINNER = %w[^ > v <]
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@spinner ||= SPINNER.first
|
16
|
+
end
|
17
|
+
|
18
|
+
def update(count)
|
19
|
+
@spinner = SPINNER[(SPINNER.index(@spinner) + 1) % SPINNER.length]
|
20
|
+
|
21
|
+
::VIM::command "echon '#{@spinner} #{count}'"
|
22
|
+
::VIM::command 'redraw'
|
23
|
+
|
24
|
+
# Aim for 5 updates per second.
|
25
|
+
now = Time.now.to_f
|
26
|
+
if @last_time
|
27
|
+
time_diff = now - @last_time
|
28
|
+
count_diff = count - @last_count
|
29
|
+
next_count = count + ((0.2 / time_diff) * count_diff).to_i
|
30
|
+
else
|
31
|
+
next_count = count + 100
|
32
|
+
end
|
33
|
+
@last_time = now
|
34
|
+
@last_count = count
|
35
|
+
next_count
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/ruby/command-t/prompt.rb
CHANGED
@@ -112,8 +112,6 @@ module CommandT
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
private
|
116
|
-
|
117
115
|
def redraw
|
118
116
|
if @has_focus
|
119
117
|
prompt_highlight = 'Comment'
|
@@ -133,6 +131,8 @@ module CommandT
|
|
133
131
|
set_status *components
|
134
132
|
end
|
135
133
|
|
134
|
+
private
|
135
|
+
|
136
136
|
# Returns the @abbrev string divided up into three sections, any of
|
137
137
|
# which may actually be zero width, depending on the location of the
|
138
138
|
# cursor:
|
@@ -158,5 +158,5 @@ module CommandT
|
|
158
158
|
end
|
159
159
|
::VIM::command 'echohl None'
|
160
160
|
end
|
161
|
-
end
|
162
|
-
end
|
161
|
+
end
|
162
|
+
end
|
data/ruby/command-t/scanner.rb
CHANGED
@@ -4,9 +4,29 @@
|
|
4
4
|
module CommandT
|
5
5
|
class Scanner
|
6
6
|
autoload :BufferScanner, 'command-t/scanner/buffer_scanner'
|
7
|
+
autoload :CommandScanner, 'command-t/scanner/command_scanner'
|
7
8
|
autoload :FileScanner, 'command-t/scanner/file_scanner'
|
9
|
+
autoload :HelpScanner, 'command-t/scanner/help_scanner'
|
10
|
+
autoload :HistoryScanner, 'command-t/scanner/history_scanner'
|
8
11
|
autoload :JumpScanner, 'command-t/scanner/jump_scanner'
|
12
|
+
autoload :LineScanner, 'command-t/scanner/line_scanner'
|
9
13
|
autoload :MRUBufferScanner, 'command-t/scanner/mru_buffer_scanner'
|
10
14
|
autoload :TagScanner, 'command-t/scanner/tag_scanner'
|
11
|
-
|
12
|
-
|
15
|
+
|
16
|
+
# Subclasses implement this method to return the list of paths that should
|
17
|
+
# be searched.
|
18
|
+
#
|
19
|
+
# Note that as an optimization, the C extension will record the
|
20
|
+
# `Object#object_id` of the returned array and assumes it will not be
|
21
|
+
# mutated.
|
22
|
+
def paths
|
23
|
+
raise RuntimeError, 'Subclass responsibility'
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def progress_reporter
|
29
|
+
@progress_reporter ||= ProgressReporter.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright 2011-present 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 CommandScanner < Scanner
|
7
|
+
def paths
|
8
|
+
@paths ||= paths!
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def paths!
|
14
|
+
# Get user commands.
|
15
|
+
commands = VIM.capture('silent command').split("\n")[2..-1].map do |line|
|
16
|
+
line.sub(/\A.{4}(\S+).+/, '\1')
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get built-in commands from `ex-cmd-index`.
|
20
|
+
ex_cmd_index = ::VIM.evaluate('expand(findfile("doc/index.txt", &runtimepath))')
|
21
|
+
if File.readable?(ex_cmd_index)
|
22
|
+
File.readlines(ex_cmd_index).each do |line|
|
23
|
+
if line =~ %r{\A\|:([^|]+)\|\s+}
|
24
|
+
commands << $~[1]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
commands.uniq
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -22,7 +22,7 @@ module CommandT
|
|
22
22
|
@paths_keys = []
|
23
23
|
@path = path
|
24
24
|
@max_depth = options[:max_depth] || 15
|
25
|
-
@max_files = options[:max_files] ||
|
25
|
+
@max_files = options[:max_files] || 100_000
|
26
26
|
@max_caches = options[:max_caches] || 1
|
27
27
|
@scan_dot_directories = options[:scan_dot_directories] || false
|
28
28
|
@wild_ignore = options[:wild_ignore]
|
@@ -44,6 +44,26 @@ module CommandT
|
|
44
44
|
|
45
45
|
private
|
46
46
|
|
47
|
+
def show_max_files_warning
|
48
|
+
unless VIM::get_bool('g:CommandTSuppressMaxFilesWarning', false)
|
49
|
+
::VIM::command('redraw!')
|
50
|
+
::VIM::command('echohl ErrorMsg')
|
51
|
+
warning =
|
52
|
+
"Warning: maximum file limit reached\n" +
|
53
|
+
"\n" +
|
54
|
+
"Increase it by setting a higher value in $MYVIMRC; eg:\n" +
|
55
|
+
" let g:CommandTMaxFiles=#{@max_files * 2}\n" +
|
56
|
+
"Or suppress this warning by setting:\n" +
|
57
|
+
" let g:CommandTSuppressMaxFilesWarning=1\n" +
|
58
|
+
"For best performance, consider using a fast scanner; see:\n" +
|
59
|
+
" :help g:CommandTFileScanner\n" +
|
60
|
+
"\n" +
|
61
|
+
"Press ENTER to continue."
|
62
|
+
::VIM::evaluate(%{input("#{warning}")})
|
63
|
+
::VIM::command('echohl None')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
47
67
|
def wild_ignore
|
48
68
|
VIM::exists?('&wildignore') && ::VIM::evaluate('&wildignore').to_s
|
49
69
|
end
|
@@ -71,13 +91,17 @@ module CommandT
|
|
71
91
|
end
|
72
92
|
|
73
93
|
def has_custom_wild_ignore?
|
74
|
-
|
94
|
+
!!@wild_ignore
|
75
95
|
end
|
76
96
|
|
77
97
|
# Used to skip expensive calls to `expand()` when there is no applicable
|
78
98
|
# wildignore.
|
79
99
|
def apply_wild_ignore?
|
80
|
-
has_custom_wild_ignore?
|
100
|
+
if has_custom_wild_ignore?
|
101
|
+
!@wild_ignore.empty?
|
102
|
+
else
|
103
|
+
!!@base_wild_ignore
|
104
|
+
end
|
81
105
|
end
|
82
106
|
|
83
107
|
def set_wild_ignore(&block)
|
@@ -86,6 +110,6 @@ module CommandT
|
|
86
110
|
ensure
|
87
111
|
::VIM::command("set wildignore=#{@base_wild_ignore}") if has_custom_wild_ignore?
|
88
112
|
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -12,7 +12,7 @@ module CommandT
|
|
12
12
|
|
13
13
|
def paths!
|
14
14
|
# temporarily set field separator to NUL byte; this setting is
|
15
|
-
# respected by both `
|
15
|
+
# respected by both `each_line` and `chomp!` below, and makes it easier
|
16
16
|
# to parse the output of `find -print0`
|
17
17
|
separator = $/
|
18
18
|
$/ = "\x00"
|
@@ -34,17 +34,22 @@ module CommandT
|
|
34
34
|
'-print0' # NUL-terminate results
|
35
35
|
].flatten.compact)) do |stdin, stdout, stderr|
|
36
36
|
counter = 1
|
37
|
-
|
37
|
+
next_progress = progress_reporter.update(counter)
|
38
|
+
stdout.each_line do |line|
|
38
39
|
next if path_excluded?(line.chomp!)
|
39
40
|
paths << line[@prefix_len..-1]
|
40
|
-
|
41
|
+
next_progress = progress_reporter.update(counter) if counter == next_progress
|
42
|
+
if (counter += 1) > @max_files
|
43
|
+
show_max_files_warning
|
44
|
+
break
|
45
|
+
end
|
41
46
|
end
|
42
47
|
end
|
43
48
|
paths
|
44
49
|
ensure
|
45
50
|
$/ = separator
|
46
51
|
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -26,11 +26,14 @@ module CommandT
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
all_files.
|
29
|
+
filtered = all_files.
|
30
30
|
map { |path| path.chomp }.
|
31
|
-
reject { |path| path_excluded?(path, 0) }
|
32
|
-
|
33
|
-
|
31
|
+
reject { |path| path_excluded?(path, 0) }
|
32
|
+
truncated = filtered.take(@max_files)
|
33
|
+
if truncated.count < filtered.count
|
34
|
+
show_max_files_warning
|
35
|
+
end
|
36
|
+
truncated.to_a
|
34
37
|
end
|
35
38
|
rescue LsFilesError
|
36
39
|
super
|
@@ -48,7 +51,7 @@ module CommandT
|
|
48
51
|
raise LsFilesError if stderr && stderr.gets
|
49
52
|
end
|
50
53
|
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -12,9 +12,11 @@ module CommandT
|
|
12
12
|
accumulator = []
|
13
13
|
@depth = 0
|
14
14
|
@files = 0
|
15
|
+
@next_progress = progress_reporter.update(@files)
|
15
16
|
add_paths_for_directory(@path, accumulator)
|
16
17
|
accumulator
|
17
18
|
rescue FileLimitExceeded
|
19
|
+
show_max_files_warning
|
18
20
|
accumulator
|
19
21
|
end
|
20
22
|
|
@@ -34,6 +36,7 @@ module CommandT
|
|
34
36
|
unless path_excluded?(path)
|
35
37
|
if File.file?(path)
|
36
38
|
@files += 1
|
39
|
+
@next_progress = progress_reporter.update(@files) if @files == @next_progress
|
37
40
|
raise FileLimitExceeded if @files > @max_files
|
38
41
|
accumulator << path[@prefix_len..-1]
|
39
42
|
elsif File.directory?(path)
|
@@ -51,7 +54,7 @@ module CommandT
|
|
51
54
|
rescue ArgumentError
|
52
55
|
# skip over bad file names
|
53
56
|
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -42,7 +42,15 @@ module CommandT
|
|
42
42
|
paths = Watchman::Utils.query(query, socket)
|
43
43
|
|
44
44
|
# could return error if watch is removed
|
45
|
-
extract_value(paths, 'files')
|
45
|
+
extracted = extract_value(paths, 'files')
|
46
|
+
if (
|
47
|
+
apply_wild_ignore? &&
|
48
|
+
(regex = VIM::wildignore_to_regexp(@wild_ignore || @base_wild_ignore))
|
49
|
+
)
|
50
|
+
extracted.select { |path| path !~ regex }
|
51
|
+
else
|
52
|
+
extracted
|
53
|
+
end
|
46
54
|
end
|
47
55
|
rescue Errno::ENOENT, WatchmanError
|
48
56
|
# watchman executable not present, or unable to fulfil request
|
@@ -61,7 +69,7 @@ module CommandT
|
|
61
69
|
raise WatchmanError, 'get-sockname failed' if !$?.exitstatus.zero?
|
62
70
|
raw_sockname
|
63
71
|
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright 2011-present 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 HelpScanner < Scanner
|
7
|
+
def paths
|
8
|
+
@cached_tags ||= paths!
|
9
|
+
end
|
10
|
+
|
11
|
+
def flush
|
12
|
+
@cached_tags = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def paths!
|
18
|
+
# Vim doesn't provide an easy way to get a list of all help tags.
|
19
|
+
# `tagfiles()` only shows the tagfiles for the current buffer, so you
|
20
|
+
# need to already be in a buffer of `'buftype'` `help` for that to work.
|
21
|
+
# Likewise, `taglist()` only shows tags that apply to the current file
|
22
|
+
# type, and `:tag` has the same restriction.
|
23
|
+
#
|
24
|
+
# So, we look for a "doc/tags" file at every location in the
|
25
|
+
# `'runtimepath'` and try to manually parse it.
|
26
|
+
tags = []
|
27
|
+
|
28
|
+
::VIM::evaluate('findfile("doc/tags", &runtimepath, -1)').each do |path|
|
29
|
+
if File.readable?(path)
|
30
|
+
File.readlines(path).each do |tag|
|
31
|
+
tags << tag.split.first if tag.split.first
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
tags
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright 2011-present 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 HistoryScanner < Scanner
|
7
|
+
def initialize(history_command)
|
8
|
+
@history_command = history_command
|
9
|
+
end
|
10
|
+
|
11
|
+
def paths
|
12
|
+
@paths ||= paths!
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def paths!
|
18
|
+
VIM.capture(@history_command).split("\n")[2..-1].map do |line|
|
19
|
+
line.sub(/\A>?\s*\d+\s*(.+)/, '\1').strip
|
20
|
+
end.uniq
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Copyright 2011-present 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 LineScanner < Scanner
|
7
|
+
def paths
|
8
|
+
@lines ||= paths!
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def paths!
|
14
|
+
# $curbuf is the Command-T match listing; we actually want the last
|
15
|
+
# buffer, but passing `$`, `#`, `%` etc to `bufnr()` returns the wrong
|
16
|
+
# value.
|
17
|
+
number = ::VIM.evaluate("g:CommandTCurrentBuffer").to_i
|
18
|
+
return [] unless number > 0
|
19
|
+
buffer = nil
|
20
|
+
(0...(::VIM::Buffer.count)).each do |n|
|
21
|
+
buffer = ::VIM::Buffer[n]
|
22
|
+
if buffer_number(buffer) == number
|
23
|
+
break
|
24
|
+
else
|
25
|
+
buffer = nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
return [] unless buffer
|
29
|
+
|
30
|
+
(1..(buffer.length)).map do |n|
|
31
|
+
line = buffer[n]
|
32
|
+
unless line.match(/\A\s*\z/)
|
33
|
+
line.sub(/\A\s*/, '') + ':' + n.to_s
|
34
|
+
end
|
35
|
+
end.compact
|
36
|
+
end
|
37
|
+
|
38
|
+
def buffer_number(buffer)
|
39
|
+
buffer && buffer.number
|
40
|
+
rescue Vim::DeletedBufferError
|
41
|
+
# Beware of people manually deleting Command-T's hidden, unlisted buffer.
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|