colorls 1.4.4.pre.846 → 1.4.4.pre.851

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58cb9ea31adb10c218637e72959a4847204de72dbc3927c77bde98eeb5bc6e29
4
- data.tar.gz: 9e3a67a9b41f8b183ee21ae8d85cb8f62b210f7dd23c6d0b88d2af6bc3c4367e
3
+ metadata.gz: 10f77d6d62a7eabd60fe2ad90259876e8c264ac39394324308b024da81865074
4
+ data.tar.gz: b64efbf3c5cdfff854c87b653796edd257159b18f8c80c67686b4fdfecb602bb
5
5
  SHA512:
6
- metadata.gz: 73989cd541cf8a14ed7c9cba49f048abab0e194ac7090c20e19c86641bcfcc4624a4afc0c4df3cb89d1c727547dcf0e528f550e4d07f63c949a48f5bfc77a560
7
- data.tar.gz: cf64b80250860816552ef49cdde8d57ff349c93839d18b365285142bca609e2db9249c8332b8843b7e5765abdd428269bdc01a2290c924e9c67c7673d72b87cf
6
+ metadata.gz: b99aa056b748c5f0342543466dad706653bc42be2c04bd00259661061b1e4d248586780d2bf73b348112b2e66ba73c9e775b6f7495bee497833de2607bd708b7
7
+ data.tar.gz: cbf72ae7c0d52c80a048958fbc8457ef24608f530b78d21b8147297eeeb2b1e5c144a00f0e226e048829b2afe511cb0c8f7fa30bfec1fb6290159a54cf8dea5a
@@ -1,14 +1,13 @@
1
- require: rubocop-performance
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+ - rubocop-rspec
2
5
 
3
6
  AllCops:
4
- Include:
5
- - 'lib/**/*'
6
7
  Exclude:
7
8
  - 'vendor/**/*'
8
9
  - 'benchmarks/*'
9
10
  - 'profile/*'
10
- - 'lib/yaml/*'
11
- - 'lib/**/*.sh'
12
11
  DisplayCopNames: true
13
12
  NewCops: enable
14
13
  TargetRubyVersion: 2.5
@@ -118,3 +117,15 @@ Metrics/PerceivedComplexity:
118
117
 
119
118
  Style/Documentation:
120
119
  Enabled: false
120
+
121
+ RSpec/NamedSubject:
122
+ Enabled: false
123
+
124
+ RSpec/SubjectStub:
125
+ Enabled: false
126
+
127
+ RSpec/ExampleLength:
128
+ Enabled: false
129
+
130
+ RSpec/ContextWording:
131
+ Enabled: false
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
data/Rakefile CHANGED
@@ -1,16 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/setup'
2
4
  require 'rubygems/tasks'
3
5
  Gem::Tasks.new
4
6
 
5
7
  require 'rspec/core/rake_task'
6
8
  RSpec::Core::RakeTask.new(:spec) do |t|
7
- t.rspec_opts = "--warnings"
9
+ t.rspec_opts = '--warnings'
8
10
  end
9
11
 
10
12
  require 'rubocop/rake_task'
11
- RuboCop::RakeTask.new do |task|
12
- task.requires << 'rubocop-rspec'
13
- end
13
+ RuboCop::RakeTask.new
14
14
 
15
15
  desc 'Build the manual'
16
16
  file 'man/colorls.1' => ['man/colorls.1.ronn', 'lib/colorls/flags.rb'] do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'colorls/version'
@@ -21,7 +23,7 @@ POST_INSTALL_MESSAGE = %(
21
23
  Man pages have been added. Checkout `man colorls`.
22
24
 
23
25
  *******************************************************************
24
- ).freeze
26
+ )
25
27
 
26
28
  # rubocop:disable Metrics/BlockLength
27
29
  Gem::Specification.new do |spec|
@@ -47,7 +49,7 @@ Gem::Specification.new do |spec|
47
49
 
48
50
  spec.required_ruby_version = '>= 2.5.0'
49
51
 
50
- spec.files = IO.popen(
52
+ spec.files = IO.popen(
51
53
  %w[git ls-files -z], external_encoding: Encoding::ASCII_8BIT
52
54
  ).read.split("\x0").reject do |f|
53
55
  f.match(%r{^(test|spec|features)/})
@@ -59,6 +61,7 @@ Gem::Specification.new do |spec|
59
61
 
60
62
  spec.post_install_message = POST_INSTALL_MESSAGE
61
63
 
64
+ spec.add_runtime_dependency 'addressable', '~> 2.7'
62
65
  spec.add_runtime_dependency 'clocale', '~> 0'
63
66
  spec.add_runtime_dependency 'filesize', '~> 0'
64
67
  spec.add_runtime_dependency 'manpages', '~> 0'
@@ -75,6 +78,7 @@ Gem::Specification.new do |spec|
75
78
  spec.add_development_dependency 'rspec-its', '~> 1.2'
76
79
  spec.add_development_dependency 'rubocop', '~> 1.8.0'
77
80
  spec.add_development_dependency 'rubocop-performance', '~> 1.9.0'
81
+ spec.add_development_dependency 'rubocop-rake', '~> 0.5'
78
82
  spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
79
83
  spec.add_development_dependency 'rubygems-tasks', '~> 0'
80
84
  spec.add_development_dependency 'simplecov', '~> 0.20.0'
@@ -8,11 +8,12 @@ require 'io/console'
8
8
  require 'rainbow/ext/string'
9
9
  require 'clocale'
10
10
  require 'unicode/display_width'
11
+ require 'addressable/uri'
11
12
 
12
- require 'colorls/core'
13
- require 'colorls/fileinfo'
14
- require 'colorls/flags'
15
- require 'colorls/layout'
16
- require 'colorls/yaml'
17
- require 'colorls/monkeys'
18
- require 'colorls/git'
13
+ require_relative 'colorls/core'
14
+ require_relative 'colorls/fileinfo'
15
+ require_relative 'colorls/flags'
16
+ require_relative 'colorls/layout'
17
+ require_relative 'colorls/yaml'
18
+ require_relative 'colorls/monkeys'
19
+ require_relative 'colorls/git'
@@ -8,16 +8,21 @@ module ColorLS
8
8
  @file_encoding
9
9
  end
10
10
 
11
+ @screen_width = IO.console.winsize[1]
12
+ @screen_width = 80 if @screen_width.zero?
13
+
14
+ def self.screen_width
15
+ @screen_width
16
+ end
17
+
11
18
  class Core
12
- def initialize(input, all: false, report: false, sort: false, show: false,
19
+ def initialize(all: false, sort: false, show: false,
13
20
  mode: nil, git_status: false, almost_all: false, colors: [], group: nil,
14
21
  reverse: false, hyperlink: false, tree_depth: nil, show_group: true, show_user: true)
15
- @input = (+input).force_encoding(ColorLS.file_encoding)
16
- @count = {folders: 0, recognized_files: 0, unrecognized_files: 0}
22
+ @count = {folders: 0, recognized_files: 0, unrecognized_files: 0}
17
23
  @all = all
18
24
  @almost_all = almost_all
19
25
  @hyperlink = hyperlink
20
- @report = report
21
26
  @sort = sort
22
27
  @reverse = reverse
23
28
  @group = group
@@ -26,42 +31,68 @@ module ColorLS
26
31
  init_long_format(mode,show_group,show_user)
27
32
  @tree = {mode: mode == :tree, depth: tree_depth}
28
33
  @horizontal = mode == :horizontal
29
- process_git_status_details(git_status)
30
-
31
- @screen_width = IO.console.winsize[1]
32
- @screen_width = 80 if @screen_width.zero?
34
+ @git_status = init_git_status(git_status)
33
35
 
34
36
  init_colors colors
35
37
 
36
- @contents = init_contents(@input)
37
38
  init_icons
38
39
  end
39
40
 
40
- def ls
41
+ def ls_dir(info)
42
+ if @tree[:mode]
43
+ print "\n"
44
+ return tree_traverse(info.path, 0, 1, 2)
45
+ end
46
+
47
+ @contents = Dir.entries(info.path, encoding: ColorLS.file_encoding)
48
+
49
+ filter_hidden_contents
50
+
51
+ @contents.map! { |e| FileInfo.dir_entry(info.path, e, link_info: @long) }
52
+
53
+ filter_contents if @show
54
+ sort_contents if @sort
55
+ group_contents if @group
56
+
41
57
  return print "\n Nothing to show here\n".colorize(@colors[:empty]) if @contents.empty?
42
58
 
59
+ ls
60
+ end
61
+
62
+ def ls_files(files)
63
+ @contents = files
64
+
65
+ ls
66
+ end
67
+
68
+ def display_report
69
+ print "\n Found #{@count.values.sum} items in total.".colorize(@colors[:report])
70
+
71
+ puts "\n\n\tFolders\t\t\t: #{@count[:folders]}"\
72
+ "\n\tRecognized files\t: #{@count[:recognized_files]}"\
73
+ "\n\tUnrecognized files\t: #{@count[:unrecognized_files]}"
74
+ .colorize(@colors[:report])
75
+ end
76
+
77
+ private
78
+
79
+ def ls
80
+ init_column_lengths
81
+
43
82
  layout = case
44
- when @tree[:mode]
45
- print "\n"
46
- return tree_traverse(@input, 0, 1, 2)
47
83
  when @horizontal
48
- HorizontalLayout.new(@contents, item_widths, @screen_width)
84
+ HorizontalLayout.new(@contents, item_widths, ColorLS.screen_width)
49
85
  when @one_per_line || @long
50
86
  SingleColumnLayout.new(@contents)
51
87
  else
52
- VerticalLayout.new(@contents, item_widths, @screen_width)
88
+ VerticalLayout.new(@contents, item_widths, ColorLS.screen_width)
53
89
  end
54
90
 
55
91
  layout.each_line do |line, widths|
56
92
  ls_line(line, widths)
57
93
  end
58
-
59
- display_report if @report
60
- true
61
94
  end
62
95
 
63
- private
64
-
65
96
  def init_colors(colors)
66
97
  @colors = colors
67
98
  @modes = Hash.new do |hash, key|
@@ -75,12 +106,26 @@ module ColorLS
75
106
  end
76
107
  end
77
108
 
78
- def init_long_format(mode,show_group,show_user)
109
+ def init_long_format(mode, show_group, show_user)
79
110
  @long = mode == :long
80
111
  @show_group = show_group
81
112
  @show_user = show_user
82
113
  end
83
114
 
115
+ def init_git_status(show_git)
116
+ return {}.freeze unless show_git
117
+
118
+ # stores git status information per directory
119
+ Hash.new do |hash, key|
120
+ path = File.absolute_path key.parent
121
+ if hash.key? path
122
+ hash[path]
123
+ else
124
+ hash[path] = Git.status(path)
125
+ end
126
+ end
127
+ end
128
+
84
129
  # how much characters an item occupies besides its name
85
130
  CHARS_PER_ITEM = 12
86
131
 
@@ -88,29 +133,6 @@ module ColorLS
88
133
  @contents.map { |item| Unicode::DisplayWidth.of(item.show) + CHARS_PER_ITEM }
89
134
  end
90
135
 
91
- def init_contents(path)
92
- info = FileInfo.new(path, link_info: @long)
93
-
94
- if info.directory?
95
- @contents = Dir.entries(path, encoding: ColorLS.file_encoding)
96
-
97
- filter_hidden_contents
98
-
99
- @contents.map! { |e| FileInfo.new(File.join(path, e), link_info: @long) }
100
-
101
- filter_contents if @show
102
- sort_contents if @sort
103
- group_contents if @group
104
- else
105
- @contents = [info]
106
- end
107
- @total_content_length = @contents.length
108
-
109
- init_column_lengths
110
-
111
- @contents
112
- end
113
-
114
136
  def filter_hidden_contents
115
137
  @contents -= %w[. ..] unless @all
116
138
  @contents.keep_if { |x| !x.start_with? '.' } unless @all || @almost_all
@@ -175,18 +197,6 @@ module ColorLS
175
197
  @folder_aliases = ColorLS::Yaml.new('folder_aliases.yaml').load(aliase: true)
176
198
  end
177
199
 
178
- def display_report
179
- print "\n Found #{@total_content_length} contents in directory "
180
- .colorize(@colors[:report])
181
-
182
- print File.expand_path(@input).to_s.colorize(@colors[:dir])
183
-
184
- puts "\n\n\tFolders\t\t\t: #{@count[:folders]}"\
185
- "\n\tRecognized files\t: #{@count[:recognized_files]}"\
186
- "\n\tUnrecognized files\t: #{@count[:unrecognized_files]}"
187
- .colorize(@colors[:report])
188
- end
189
-
190
200
  def format_mode(rwx, special, char)
191
201
  m_r = (rwx & 4).zero? ? '-' : 'r'
192
202
  m_w = (rwx & 2).zero? ? '-' : 'w'
@@ -233,42 +243,32 @@ module ColorLS
233
243
  mtime.colorize(@colors[:no_modifier])
234
244
  end
235
245
 
236
- def process_git_status_details(git_status)
237
- @git_status = case
238
- when !git_status then nil
239
- when File.directory?(@input) then Git.status(@input)
240
- else Git.status(File.dirname(@input))
241
- end
242
- end
243
-
244
246
  def git_info(content)
245
- return '' unless @git_status
247
+ return '' unless (status = @git_status[content])
246
248
 
247
249
  if content.directory?
248
- git_dir_info(content.name)
250
+ git_dir_info(content, status)
249
251
  else
250
- git_file_info(content.name)
252
+ git_file_info(status[content.name])
251
253
  end
252
254
  end
253
255
 
254
- def git_file_info(path)
255
- unless @git_status[path]
256
- return ' ✓ '
257
- .encode(Encoding.default_external, undef: :replace, replace: '=')
258
- .colorize(@colors[:unchanged])
259
- end
256
+ def git_file_info(status)
257
+ return Git.colored_status_symbols(status, @colors) if status
260
258
 
261
- Git.colored_status_symbols(@git_status[path], @colors)
259
+ ' ✓ '
260
+ .encode(Encoding.default_external, undef: :replace, replace: '=')
261
+ .colorize(@colors[:unchanged])
262
262
  end
263
263
 
264
- def git_dir_info(path)
265
- modes = if path == '.'
266
- Set.new(@git_status.values).flatten
264
+ def git_dir_info(content, status)
265
+ modes = if content.path == '.'
266
+ Set.new(status.values).flatten
267
267
  else
268
- @git_status[path]
268
+ status[content.name]
269
269
  end
270
270
 
271
- if modes.empty? && Dir.empty?(File.join(@input, path))
271
+ if modes.empty? && Dir.empty?(content.path)
272
272
  ' '
273
273
  else
274
274
  Git.colored_status_symbols(modes, @colors)
@@ -303,12 +303,12 @@ module ColorLS
303
303
  str.encode(Encoding.default_external, undef: :replace, replace: '')
304
304
  end
305
305
 
306
- def fetch_string(path, content, key, color, increment)
306
+ def fetch_string(content, key, color, increment)
307
307
  @count[increment] += 1
308
308
  value = increment == :folders ? @folders[key] : @files[key]
309
309
  logo = value.gsub(/\\u[\da-f]{4}/i) { |m| [m[-4..-1].to_i(16)].pack('U') }
310
310
  name = content.show
311
- name = make_link(path, name) if @hyperlink
311
+ name = make_link(content) if @hyperlink
312
312
  name += content.directory? ? '/' : ' '
313
313
  entry = "#{out_encode(logo)} #{out_encode(name)}"
314
314
  entry = entry.bright if !content.directory? && content.executable?
@@ -320,7 +320,7 @@ module ColorLS
320
320
  padding = 0
321
321
  line = +''
322
322
  chunk.each_with_index do |content, i|
323
- entry = fetch_string(@input, content, *options(content))
323
+ entry = fetch_string(content, *options(content))
324
324
  line << ' ' * padding
325
325
  line << ' ' << entry.encode(Encoding.default_external, undef: :replace)
326
326
  padding = widths[i] - Unicode::DisplayWidth.of(content.show) - CHARS_PER_ITEM
@@ -330,11 +330,11 @@ module ColorLS
330
330
 
331
331
  def file_color(file, key)
332
332
  color_key = case
333
- when file.chardev? then :chardev
334
- when file.blockdev? then :blockdev
335
- when file.socket? then :socket
336
- else
337
- @files.key?(key) ? :recognized_file : :unrecognized_file
333
+ when file.chardev? then :chardev
334
+ when file.blockdev? then :blockdev
335
+ when file.socket? then :socket
336
+ when @files.key?(key) then :recognized_file
337
+ else :unrecognized_file
338
338
  end
339
339
  @colors[color_key]
340
340
  end
@@ -357,12 +357,26 @@ module ColorLS
357
357
  [key, color, group]
358
358
  end
359
359
 
360
+ def tree_contents(path)
361
+ @contents = Dir.entries(path, encoding: ColorLS.file_encoding)
362
+
363
+ filter_hidden_contents
364
+
365
+ @contents.map! { |e| FileInfo.dir_entry(path, e, link_info: @long) }
366
+
367
+ filter_contents if @show
368
+ sort_contents if @sort
369
+ group_contents if @group
370
+
371
+ @contents
372
+ end
373
+
360
374
  def tree_traverse(path, prespace, depth, indent)
361
- contents = init_contents(path)
375
+ contents = tree_contents(path)
362
376
  contents.each do |content|
363
377
  icon = content == contents.last || content.directory? ? ' └──' : ' ├──'
364
378
  print tree_branch_preprint(prespace, indent, icon).colorize(@colors[:tree])
365
- print " #{fetch_string(path, content, *options(content))} \n"
379
+ print " #{fetch_string(content, *options(content))} \n"
366
380
  next unless content.directory?
367
381
 
368
382
  tree_traverse("#{path}/#{content}", prespace + indent, depth + 1, indent) if keep_going(depth)
@@ -379,9 +393,9 @@ module ColorLS
379
393
  ' │ ' * (prespace/indent) + prespace_icon + '─' * indent
380
394
  end
381
395
 
382
- def make_link(path, name)
383
- href = "file://#{File.absolute_path(path)}/#{name}"
384
- "\033]8;;#{href}\007#{name}\033]8;;\007"
396
+ def make_link(content)
397
+ uri = Addressable::URI.convert_path(File.absolute_path(content.path))
398
+ "\033]8;;#{uri}\007#{content.name}\033]8;;\007"
385
399
  end
386
400
  end
387
401
  end
@@ -9,19 +9,24 @@ module ColorLS
9
9
  @@users = {} # rubocop:disable Style/ClassVars
10
10
  @@groups = {} # rubocop:disable Style/ClassVars
11
11
 
12
- attr_reader :stats, :name
13
-
14
- def initialize(path, link_info: true)
15
- @name = File.basename(path)
16
- @stats = File.lstat(path)
12
+ attr_reader :stats, :name, :path, :parent
17
13
 
14
+ def initialize(name:, parent:, path: nil, link_info: true)
15
+ @name = name
16
+ @parent = parent
17
+ @path = path.nil? ? File.join(parent, name) : path
18
+ @stats = File.lstat(@path)
18
19
  @show_name = nil
19
20
 
20
- handle_symlink(path) if link_info && @stats.symlink?
21
+ handle_symlink(@path) if link_info && @stats.symlink?
22
+ end
23
+
24
+ def self.info(path, link_info: true)
25
+ FileInfo.new(name: File.basename(path), parent: File.dirname(path), path: path, link_info: link_info)
21
26
  end
22
27
 
23
- def self.info(path)
24
- FileInfo.new(path)
28
+ def self.dir_entry(dir, child, link_info: true)
29
+ FileInfo.new(name: child, parent: dir, link_info: link_info)
25
30
  end
26
31
 
27
32
  def show
@@ -11,6 +11,8 @@ module ColorLS
11
11
  @light_colors = false
12
12
 
13
13
  @opts = default_opts
14
+ @show_report = false
15
+ @exit_status_code = 0
14
16
 
15
17
  parse_options
16
18
 
@@ -19,30 +21,14 @@ module ColorLS
19
21
  # FIXME: `--all` and `--tree` do not work together, use `--almost-all` instead
20
22
  @opts[:almost_all] = true if @opts[:all]
21
23
  @opts[:all] = false
22
-
23
- # `--tree` does not support reports
24
- @opts[:report] = false
25
24
  end
26
25
 
27
26
  def process
28
27
  init_locale
29
28
 
30
29
  @args = ['.'] if @args.empty?
31
- exit_status_code = 0
32
- @args.sort!.each_with_index do |path, i|
33
- unless File.exist?(path)
34
- $stderr.puts "\n Specified path '#{path}' doesn't exist.".colorize(:red)
35
- exit_status_code = 2
36
- next
37
- end
38
30
 
39
- puts '' if i.positive?
40
- puts "\n#{path}:" if Dir.exist?(path) && @args.size > 1
41
- Core.new(path, **@opts).ls
42
- rescue SystemCallError => e
43
- $stderr.puts "#{path}: #{e}".colorize(:red)
44
- end
45
- exit_status_code
31
+ process_args
46
32
  end
47
33
 
48
34
  def options
@@ -69,6 +55,44 @@ module ColorLS
69
55
  warn "WARN: #{e}, check your locale settings"
70
56
  end
71
57
 
58
+ def group_files_and_directories
59
+ infos = @args.flat_map do |arg|
60
+ FileInfo.info(arg)
61
+ rescue Errno::ENOENT
62
+ $stderr.puts "colorls: Specified path '#{arg}' doesn't exist.".colorize(:red)
63
+ @exit_status_code = 2
64
+ []
65
+ rescue SystemCallError => e
66
+ $stderr.puts "#{path}: #{e}".colorize(:red)
67
+ @exit_status_code = 2
68
+ []
69
+ end
70
+
71
+ infos.group_by(&:directory?).values_at(true, false)
72
+ end
73
+
74
+ def process_args
75
+ core = Core.new(**@opts)
76
+
77
+ directories, files = group_files_and_directories
78
+
79
+ core.ls_files(files) unless files.nil?
80
+
81
+ directories&.sort_by! do |a|
82
+ CLocale.strxfrm(a.name)
83
+ end&.each do |dir|
84
+ puts "\n#{dir.show}:" if @args.size > 1
85
+
86
+ core.ls_dir(dir)
87
+ rescue SystemCallError => e
88
+ $stderr.puts "#{dir}: #{e}".colorize(:red)
89
+ end
90
+
91
+ core.display_report if @show_report
92
+
93
+ @exit_status_code
94
+ end
95
+
72
96
  def default_opts
73
97
  {
74
98
  show: false,
@@ -78,7 +102,6 @@ module ColorLS
78
102
  mode: STDOUT.tty? ? :vertical : :one_per_line, # rubocop:disable Style/GlobalStdStream
79
103
  all: false,
80
104
  almost_all: false,
81
- report: false,
82
105
  git_status: false,
83
106
  colors: [],
84
107
  tree_depth: 3,
@@ -117,7 +140,7 @@ module ColorLS
117
140
  options.on('-d', '--dirs', 'show only directories') { @opts[:show] = :dirs }
118
141
  options.on('-f', '--files', 'show only files') { @opts[:show] = :files }
119
142
  options.on('--gs', '--git-status', 'show git status for each file') { @opts[:git_status] = true }
120
- options.on('--report', 'show brief report') { @opts[:report] = true }
143
+ options.on('--report', 'show brief report') { @show_report = true }
121
144
  end
122
145
 
123
146
  def add_format_options(options)
@@ -6,29 +6,27 @@ require 'set'
6
6
  module ColorLS
7
7
  module Git
8
8
  def self.status(repo_path)
9
- prefix = git_prefix(repo_path)
9
+ prefix, success = git_prefix(repo_path)
10
10
 
11
- return unless $CHILD_STATUS.success?
11
+ return unless success
12
12
 
13
- prefix = Pathname.new(prefix.chomp)
13
+ prefix_path = Pathname.new(prefix)
14
14
 
15
15
  git_status = Hash.new { |hash, key| hash[key] = Set.new }
16
16
 
17
- git_subdir_status(repo_path) do |output|
18
- while (status_line = output.gets "\x0")
19
- mode, file = status_line.chomp("\x0").split(' ', 2)
20
-
21
- path = Pathname.new(file).relative_path_from(prefix)
22
-
17
+ git_subdir_status(repo_path) do |mode, file|
18
+ if file == prefix
19
+ git_status.default = Set[mode].freeze
20
+ else
21
+ path = Pathname.new(file).relative_path_from(prefix_path)
23
22
  git_status[path.descend.first.cleanpath.to_s].add(mode)
24
-
25
- # skip the next \x0 separated original path for renames, issue #185
26
- output.gets("\x0") if mode.start_with? 'R'
27
23
  end
28
24
  end
25
+
29
26
  warn "git status failed in #{repo_path}" unless $CHILD_STATUS.success?
30
27
 
31
- git_status
28
+ git_status.default = Set.new.freeze if git_status.default.nil?
29
+ git_status.freeze
32
30
  end
33
31
 
34
32
  def self.colored_status_symbols(modes, colors)
@@ -38,28 +36,39 @@ module ColorLS
38
36
  .colorize(colors[:unchanged])
39
37
  end
40
38
 
41
- modes = modes.to_a.join.uniq.rjust(3).ljust(4)
42
-
43
- modes
44
- .gsub('?', '?'.colorize(colors[:untracked]))
45
- .gsub('A', 'A'.colorize(colors[:addition]))
46
- .gsub('M', 'M'.colorize(colors[:modification]))
47
- .gsub('D', 'D'.colorize(colors[:deletion]))
48
- .tr('!', ' ')
39
+ modes.to_a.join.uniq.delete('!').rjust(3).ljust(4)
40
+ .sub('?', '?'.colorize(colors[:untracked]))
41
+ .sub('A', 'A'.colorize(colors[:addition]))
42
+ .sub('M', 'M'.colorize(colors[:modification]))
43
+ .sub('D', 'D'.colorize(colors[:deletion]))
49
44
  end
50
45
 
51
46
  class << self
52
47
  private
53
48
 
54
49
  def git_prefix(repo_path)
55
- IO.popen(['git', '-C', repo_path, 'rev-parse', '--show-prefix'], err: :close, &:gets)
50
+ [
51
+ IO.popen(['git', '-C', repo_path, 'rev-parse', '--show-prefix'], err: :close, &:gets)&.chomp,
52
+ $CHILD_STATUS.success?
53
+ ]
54
+ rescue Errno::ENOENT
55
+ [nil, false]
56
56
  end
57
57
 
58
58
  def git_subdir_status(repo_path)
59
- yield IO.popen(
59
+ IO.popen(
60
60
  ['git', '-C', repo_path, 'status', '--porcelain', '-z', '-unormal', '--ignored', '.'],
61
61
  external_encoding: Encoding::ASCII_8BIT
62
- )
62
+ ) do |output|
63
+ while (status_line = output.gets "\x0")
64
+ mode, file = status_line.chomp("\x0").split(' ', 2)
65
+
66
+ yield mode, file
67
+
68
+ # skip the next \x0 separated original path for renames, issue #185
69
+ output.gets("\x0") if mode.start_with? 'R'
70
+ end
71
+ end
63
72
  end
64
73
  end
65
74
  end
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "COLORLS" "1" "November 2020" "colorls 1.4.2" "colorls Manual"
4
+ .TH "COLORLS" "1" "December 2020" "colorls 1.4.3" "colorls Manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBcolorls\fR \- list directory contents with colors and icons
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: colorls
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.4.pre.846
4
+ version: 1.4.4.pre.851
5
5
  platform: ruby
6
6
  authors:
7
7
  - Athitya Kumar
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-09 00:00:00.000000000 Z
11
+ date: 2021-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: addressable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.7'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: clocale
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -226,6 +240,20 @@ dependencies:
226
240
  - - "~>"
227
241
  - !ruby/object:Gem::Version
228
242
  version: 1.9.0
243
+ - !ruby/object:Gem::Dependency
244
+ name: rubocop-rake
245
+ requirement: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - "~>"
248
+ - !ruby/object:Gem::Version
249
+ version: '0.5'
250
+ type: :development
251
+ prerelease: false
252
+ version_requirements: !ruby/object:Gem::Requirement
253
+ requirements:
254
+ - - "~>"
255
+ - !ruby/object:Gem::Version
256
+ version: '0.5'
229
257
  - !ruby/object:Gem::Dependency
230
258
  name: rubocop-rspec
231
259
  requirement: !ruby/object:Gem::Requirement