command-t 3.0.2 → 4.0
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.
- 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
|