colorls 1.0.9 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -1
- data/.travis.yml +6 -0
- data/CONTRIBUTING.md +1 -1
- data/README.md +101 -27
- data/Rakefile +35 -1
- data/colorls.gemspec +15 -1
- data/exe/colorls +1 -0
- data/lib/colorls.rb +5 -1
- data/lib/colorls/core.rb +127 -143
- data/lib/colorls/fileinfo.rb +69 -0
- data/lib/colorls/flags.rb +60 -22
- data/lib/colorls/git.rb +6 -6
- data/lib/colorls/version.rb +1 -1
- data/lib/colorls/yaml.rb +23 -0
- data/lib/tab_complete.sh +9 -4
- data/man/colorls.1 +135 -0
- data/man/colorls.1.ronn +41 -0
- data/zsh/_colorls +38 -0
- metadata +85 -15
- data/lib/colorls/load_from_yaml.rb +0 -22
- data/readme/pending.png +0 -0
- data/readme/usage1.png +0 -0
- data/readme/usage2.png +0 -0
- data/readme/usage3.png +0 -0
- data/readme/usage4.png +0 -0
- data/readme/usage5.png +0 -0
- data/readme/usage6.png +0 -0
- data/readme/usage7.png +0 -0
- data/readme/usage8.png +0 -0
- data/readme/usage9.png +0 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
module ColorLS
|
2
|
+
class FileInfo
|
3
|
+
@@users = {} # rubocop:disable Style/ClassVars
|
4
|
+
@@groups = {} # rubocop:disable Style/ClassVars
|
5
|
+
|
6
|
+
attr_reader :stats
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
def initialize(path, link_info=true)
|
10
|
+
@name = File.basename(path)
|
11
|
+
@stats = File.lstat(path)
|
12
|
+
|
13
|
+
return unless link_info && @stats.symlink?
|
14
|
+
@dead = !File.exist?(path)
|
15
|
+
@target = File.readlink(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.info(path)
|
19
|
+
FileInfo.new(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dead?
|
23
|
+
@dead
|
24
|
+
end
|
25
|
+
|
26
|
+
def owner
|
27
|
+
return @@users[@stats.uid] if @@users.key? @stats.uid
|
28
|
+
@@users[@stats.uid] = Etc.getpwuid(@stats.uid).name
|
29
|
+
rescue ArgumentError
|
30
|
+
@stats.uid.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def owned?
|
34
|
+
@stats.owned?
|
35
|
+
end
|
36
|
+
|
37
|
+
def group
|
38
|
+
return @@groups[@stats.gid] if @@groups.key? @stats.gid
|
39
|
+
@@groups[@stats.gid] = Etc.getgrgid(@stats.gid).name
|
40
|
+
rescue ArgumentError
|
41
|
+
@stats.gid.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def mtime
|
45
|
+
@stats.mtime
|
46
|
+
end
|
47
|
+
|
48
|
+
def size
|
49
|
+
@stats.size
|
50
|
+
end
|
51
|
+
|
52
|
+
def directory?
|
53
|
+
@stats.directory?
|
54
|
+
end
|
55
|
+
|
56
|
+
def symlink?
|
57
|
+
@stats.symlink?
|
58
|
+
end
|
59
|
+
|
60
|
+
# target of a symlink (only available for symlinks)
|
61
|
+
def link_target
|
62
|
+
@target
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
name
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/colorls/flags.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'colorls/version'
|
3
|
+
require 'ostruct'
|
3
4
|
|
4
5
|
module ColorLS
|
5
6
|
class Flags
|
6
7
|
def initialize(*args)
|
7
8
|
@args = args
|
8
9
|
@light_colors = false
|
9
|
-
@mode = :one_per_line unless STDOUT.tty?
|
10
10
|
|
11
11
|
@opts = {
|
12
12
|
show: false,
|
13
|
-
sort:
|
13
|
+
sort: true,
|
14
|
+
reverse: false,
|
15
|
+
group: nil,
|
16
|
+
mode: STDOUT.tty? || :one_per_line,
|
14
17
|
all: false,
|
15
18
|
almost_all: false,
|
16
19
|
report: false,
|
@@ -20,12 +23,7 @@ module ColorLS
|
|
20
23
|
|
21
24
|
parse_options
|
22
25
|
|
23
|
-
|
24
|
-
%i[tree long one_per_line].each do |value|
|
25
|
-
@opts[value] = @mode == value
|
26
|
-
end
|
27
|
-
|
28
|
-
return unless @mode == :tree
|
26
|
+
return unless @opts[:mode] == :tree
|
29
27
|
|
30
28
|
# FIXME: `--all` and `--tree` do not work together, use `--almost-all` instead
|
31
29
|
@opts[:almost_all] = true if @opts[:all]
|
@@ -36,11 +34,35 @@ module ColorLS
|
|
36
34
|
end
|
37
35
|
|
38
36
|
def process
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
# initialize locale from environment
|
38
|
+
CLocale.setlocale(CLocale::LC_COLLATE, '')
|
39
|
+
|
40
|
+
@args = [Dir.pwd] if @args.empty?
|
41
|
+
@args.sort!.each_with_index do |path, i|
|
42
|
+
begin
|
43
|
+
next STDERR.puts "\n Specified path '#{path}' doesn't exist.".colorize(:red) unless File.exist?(path)
|
44
|
+
puts '' if i > 0
|
45
|
+
puts "\n#{path}:" if Dir.exist?(path) && @args.size > 1
|
46
|
+
Core.new(path, @opts).ls
|
47
|
+
rescue SystemCallError => e
|
48
|
+
STDERR.puts "#{path}: #{e}".colorize(:red)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def options
|
54
|
+
list = @parser.top.list + @parser.base.list
|
55
|
+
|
56
|
+
result = list.collect do |o|
|
57
|
+
next unless o.respond_to? 'desc'
|
58
|
+
|
59
|
+
flags = o.short + o.long
|
60
|
+
next if flags.empty?
|
61
|
+
|
62
|
+
OpenStruct.new(flags: flags, desc: o.desc)
|
43
63
|
end
|
64
|
+
|
65
|
+
result.compact
|
44
66
|
end
|
45
67
|
|
46
68
|
private
|
@@ -49,17 +71,33 @@ module ColorLS
|
|
49
71
|
options.separator ''
|
50
72
|
options.separator 'sorting options:'
|
51
73
|
options.separator ''
|
52
|
-
options.on('--sd', '--sort-dirs', '--group-directories-first', 'sort directories first') { @opts[:
|
53
|
-
options.on('--sf', '--sort-files', 'sort files first')
|
74
|
+
options.on('--sd', '--sort-dirs', '--group-directories-first', 'sort directories first') { @opts[:group] = :dirs }
|
75
|
+
options.on('--sf', '--sort-files', 'sort files first') { @opts[:group] = :files }
|
76
|
+
options.on('-t', 'sort by modification time, newest first') { @opts[:sort] = :time }
|
77
|
+
options.on('-U', 'do not sort; list entries in directory order') { @opts[:sort] = false }
|
78
|
+
options.on('-S', 'sort by file size, largest first') { @opts[:sort] = :size }
|
79
|
+
options.on(
|
80
|
+
'--sort=WORD',
|
81
|
+
%w[none time size],
|
82
|
+
'sort by WORD instead of name: none, size (-S), time (-t)'
|
83
|
+
) do |word|
|
84
|
+
@opts[:sort] = case word
|
85
|
+
when 'none' then false
|
86
|
+
when 'time' then :time
|
87
|
+
when 'size' then :size
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
options.on('-r', '--reverse', 'reverse order while sorting') { @opts[:reverse] = true }
|
54
92
|
end
|
55
93
|
|
56
94
|
def add_common_options(options)
|
57
95
|
options.on('-a', '--all', 'do not ignore entries starting with .') { @opts[:all] = true }
|
58
96
|
options.on('-A', '--almost-all', 'do not list . and ..') { @opts[:almost_all] = true }
|
59
|
-
options.on('-l', '--long', 'use a long listing format') { @mode = :long }
|
60
|
-
options.on('
|
61
|
-
options.on('
|
62
|
-
options.on('-1', 'list one file per line') { @mode = :one_per_line }
|
97
|
+
options.on('-l', '--long', 'use a long listing format') { @opts[:mode] = :long }
|
98
|
+
options.on('--tree', 'shows tree view of the directory') { @opts[:mode] = :tree }
|
99
|
+
options.on('--report', 'show brief report') { @opts[:report] = true }
|
100
|
+
options.on('-1', 'list one file per line') { @opts[:mode] = :one_per_line }
|
63
101
|
options.on('-d', '--dirs', 'show only directories') { @opts[:show] = :dirs }
|
64
102
|
options.on('-f', '--files', 'show only files') { @opts[:show] = :files }
|
65
103
|
options.on('--gs', '--git-status', 'show git status for each file') { @opts[:git_status] = true }
|
@@ -100,7 +138,7 @@ EXAMPLES
|
|
100
138
|
end
|
101
139
|
|
102
140
|
def parse_options
|
103
|
-
parser = OptionParser.new do |opts|
|
141
|
+
@parser = OptionParser.new do |opts|
|
104
142
|
opts.banner = 'Usage: colorls [OPTION]... [FILE]...'
|
105
143
|
opts.separator ''
|
106
144
|
|
@@ -110,7 +148,7 @@ EXAMPLES
|
|
110
148
|
|
111
149
|
opts.separator ''
|
112
150
|
opts.on_tail('-h', '--help', 'prints this help') do
|
113
|
-
puts parser
|
151
|
+
puts @parser
|
114
152
|
show_examples
|
115
153
|
exit
|
116
154
|
end
|
@@ -120,14 +158,14 @@ EXAMPLES
|
|
120
158
|
end
|
121
159
|
end
|
122
160
|
|
123
|
-
parser.parse!(@args)
|
161
|
+
@parser.parse!(@args)
|
124
162
|
|
125
163
|
set_color_opts
|
126
164
|
end
|
127
165
|
|
128
166
|
def set_color_opts
|
129
167
|
color_scheme_file = @light_colors ? 'light_colors.yaml' : 'dark_colors.yaml'
|
130
|
-
@opts[:colors] = ColorLS.
|
168
|
+
@opts[:colors] = ColorLS::Yaml.new(color_scheme_file).load(aliase: true)
|
131
169
|
end
|
132
170
|
end
|
133
171
|
end
|
data/lib/colorls/git.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
module ColorLS
|
2
2
|
class Git < Core
|
3
3
|
def self.status(repo_path)
|
4
|
-
actual = Dir.pwd
|
5
|
-
Dir.chdir(repo_path)
|
6
|
-
|
7
4
|
@git_status = {}
|
8
5
|
|
9
|
-
|
10
|
-
|
6
|
+
IO.popen(['git', '-C', repo_path, 'status', '--porcelain', '-z', '-uall', '--ignored']) do |output|
|
7
|
+
output.read.split("\x0").map { |x| x.split(' ', 2) }.each do |mode, file|
|
8
|
+
@git_status[file] = mode
|
9
|
+
end
|
11
10
|
end
|
11
|
+
warn "git status failed in #{repo_path}" unless $CHILD_STATUS.success?
|
12
12
|
|
13
|
-
Dir.chdir(actual)
|
14
13
|
@git_status
|
15
14
|
end
|
16
15
|
|
@@ -28,6 +27,7 @@ module ColorLS
|
|
28
27
|
.gsub('A', 'A'.colorize(colors[:addition]))
|
29
28
|
.gsub('M', 'M'.colorize(colors[:modification]))
|
30
29
|
.gsub('D', 'D'.colorize(colors[:deletion]))
|
30
|
+
.tr('!', ' ')
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
data/lib/colorls/version.rb
CHANGED
data/lib/colorls/yaml.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module ColorLS
|
2
|
+
class Yaml
|
3
|
+
def initialize(filename)
|
4
|
+
@filepath = File.join(File.dirname(__FILE__),"../yaml/#{filename}")
|
5
|
+
@user_config_filepath = File.join(Dir.home, ".config/colorls/#{filename}")
|
6
|
+
end
|
7
|
+
|
8
|
+
def load(aliase: false)
|
9
|
+
yaml = read_file(@filepath)
|
10
|
+
if File.exist?(@user_config_filepath)
|
11
|
+
user_config_yaml = read_file(@user_config_filepath)
|
12
|
+
yaml = yaml.merge(user_config_yaml)
|
13
|
+
end
|
14
|
+
|
15
|
+
return yaml unless aliase
|
16
|
+
yaml.to_a.map! { |k, v| [k, v.to_sym] }.to_h
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_file(filepath)
|
20
|
+
::YAML.safe_load(File.read(filepath)).symbolize_keys
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/tab_complete.sh
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
|
2
|
+
if [ -z "${ZSH_VERSION+x}" ]; then
|
3
|
+
function _colorls_complete() {
|
4
|
+
COMPREPLY=( $( colorls --'*'-completion-bash="$2" ) )
|
5
|
+
}
|
6
|
+
complete -o default -F _colorls_complete colorls
|
7
|
+
else
|
8
|
+
fpath=("${0:A:h:h}/zsh" $fpath)
|
9
|
+
fi
|
data/man/colorls.1
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
.\" generated with Ronn/v0.7.3
|
2
|
+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
|
+
.
|
4
|
+
.TH "COLORLS" "1" "November 2017" "colorls 1.1.0" "colorls Manual"
|
5
|
+
.
|
6
|
+
.SH "NAME"
|
7
|
+
\fBcolorls\fR \- list directory contents with colors and icons
|
8
|
+
.
|
9
|
+
.SH "SYNOPSIS"
|
10
|
+
\fBcolorls\fR [OPTION]\.\.\. [FILE]\.\.\.
|
11
|
+
.
|
12
|
+
.br
|
13
|
+
.
|
14
|
+
.SH "DESCRIPTION"
|
15
|
+
List information about the given FILEs\. Uses different colors and icons for known file types\.
|
16
|
+
.
|
17
|
+
.P
|
18
|
+
By default, the output is sorted alphabetically\.
|
19
|
+
.
|
20
|
+
.P
|
21
|
+
Mandatory arguments to long options are mandatory for short options too\.
|
22
|
+
.
|
23
|
+
.SH "OPTIONS"
|
24
|
+
.
|
25
|
+
.TP
|
26
|
+
\fB\-a\fR, \fB\-\-all\fR
|
27
|
+
do not ignore entries starting with \.
|
28
|
+
.
|
29
|
+
.TP
|
30
|
+
\fB\-A\fR, \fB\-\-almost\-all\fR
|
31
|
+
do not list \. and \.\.
|
32
|
+
.
|
33
|
+
.TP
|
34
|
+
\fB\-l\fR, \fB\-\-long\fR
|
35
|
+
use a long listing format
|
36
|
+
.
|
37
|
+
.TP
|
38
|
+
\fB\-\-tree\fR
|
39
|
+
shows tree view of the directory
|
40
|
+
.
|
41
|
+
.TP
|
42
|
+
\fB\-\-report\fR
|
43
|
+
show brief report
|
44
|
+
.
|
45
|
+
.TP
|
46
|
+
\fB\-1\fR
|
47
|
+
list one file per line
|
48
|
+
.
|
49
|
+
.TP
|
50
|
+
\fB\-d\fR, \fB\-\-dirs\fR
|
51
|
+
show only directories
|
52
|
+
.
|
53
|
+
.TP
|
54
|
+
\fB\-f\fR, \fB\-\-files\fR
|
55
|
+
show only files
|
56
|
+
.
|
57
|
+
.TP
|
58
|
+
\fB\-\-gs\fR, \fB\-\-git\-status\fR
|
59
|
+
show git status for each file
|
60
|
+
.
|
61
|
+
.TP
|
62
|
+
\fB\-\-sd\fR, \fB\-\-sort\-dirs\fR, \fB\-\-group\-directories\-first\fR
|
63
|
+
sort directories first
|
64
|
+
.
|
65
|
+
.TP
|
66
|
+
\fB\-\-sf\fR, \fB\-\-sort\-files\fR
|
67
|
+
sort files first
|
68
|
+
.
|
69
|
+
.TP
|
70
|
+
\fB\-t\fR
|
71
|
+
sort by modification time, newest first
|
72
|
+
.
|
73
|
+
.TP
|
74
|
+
\fB\-U\fR
|
75
|
+
do not sort; list entries in directory order
|
76
|
+
.
|
77
|
+
.TP
|
78
|
+
\fB\-S\fR
|
79
|
+
sort by file size, largest first
|
80
|
+
.
|
81
|
+
.TP
|
82
|
+
\fB\-\-sort\fR
|
83
|
+
sort by WORD instead of name: none, size (\-S), time (\-t)
|
84
|
+
.
|
85
|
+
.TP
|
86
|
+
\fB\-r\fR, \fB\-\-reverse\fR
|
87
|
+
reverse order while sorting
|
88
|
+
.
|
89
|
+
.TP
|
90
|
+
\fB\-\-light\fR
|
91
|
+
use light color scheme
|
92
|
+
.
|
93
|
+
.TP
|
94
|
+
\fB\-\-dark\fR
|
95
|
+
use dark color scheme
|
96
|
+
.
|
97
|
+
.TP
|
98
|
+
\fB\-h\fR, \fB\-\-help\fR
|
99
|
+
prints this help
|
100
|
+
.
|
101
|
+
.TP
|
102
|
+
\fB\-\-version\fR
|
103
|
+
show version
|
104
|
+
.
|
105
|
+
.SH "EXAMPLES"
|
106
|
+
.
|
107
|
+
.TP
|
108
|
+
show the given file:
|
109
|
+
.
|
110
|
+
.IP
|
111
|
+
\fBcolorls README\.md\fR
|
112
|
+
.
|
113
|
+
.TP
|
114
|
+
show matching files and list matching directories:
|
115
|
+
.
|
116
|
+
.IP
|
117
|
+
\fBcolorls *\fR
|
118
|
+
.
|
119
|
+
.TP
|
120
|
+
filter output by a regular expression:
|
121
|
+
.
|
122
|
+
.IP
|
123
|
+
\fBcolorls | grep PATTERN\fR
|
124
|
+
.
|
125
|
+
.TP
|
126
|
+
several short options can be combined:
|
127
|
+
.
|
128
|
+
.IP
|
129
|
+
\fBcolorls \-d \-l \-a\fR
|
130
|
+
.
|
131
|
+
.br
|
132
|
+
\fBcolorls \-dla\fR
|
133
|
+
.
|
134
|
+
.SH "AUTHOR"
|
135
|
+
Written by Athitya Kumar\.
|
data/man/colorls.1.ronn
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
colorls(1) -- list directory contents with colors and icons
|
2
|
+
===========================================================
|
3
|
+
|
4
|
+
## SYNOPSIS
|
5
|
+
|
6
|
+
`colorls` [OPTION]... [FILE]...<br>
|
7
|
+
|
8
|
+
## DESCRIPTION
|
9
|
+
|
10
|
+
List information about the given FILEs. Uses different colors and icons for known file types.
|
11
|
+
|
12
|
+
By default, the output is sorted alphabetically.
|
13
|
+
|
14
|
+
Mandatory arguments to long options are mandatory for short options too.
|
15
|
+
|
16
|
+
## OPTIONS
|
17
|
+
|
18
|
+
{{ OPTIONS }}
|
19
|
+
|
20
|
+
## EXAMPLES
|
21
|
+
|
22
|
+
* show the given file:
|
23
|
+
|
24
|
+
`colorls README.md`
|
25
|
+
|
26
|
+
* show matching files and list matching directories:
|
27
|
+
|
28
|
+
`colorls *`
|
29
|
+
|
30
|
+
* filter output by a regular expression:
|
31
|
+
|
32
|
+
`colorls | grep PATTERN`
|
33
|
+
|
34
|
+
* several short options can be combined:
|
35
|
+
|
36
|
+
`colorls -d -l -a`<br>
|
37
|
+
`colorls -dla`
|
38
|
+
|
39
|
+
## AUTHOR
|
40
|
+
|
41
|
+
Written by Athitya Kumar.
|