Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/symbolic folders #616

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pkg/
*.gem
.bundle/
.yardoc/
.vscode/
Gemfile.lock
/_yardoc/
*.DS_store
Expand Down
30 changes: 30 additions & 0 deletions .rake_tasks~
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
build
build:colorls
build:gem
build:gem:colorls
console
console:colorls
default
gem
install
install:colorls
install_gem
man/colorls.1
package
pkg
pkg/colorls-1.5.0.gem
publish
push
push:colorls
release
rubocop
rubocop:auto_correct
rubocop:autocorrect
rubocop:autocorrect_all
scm:push
scm:status
scm:tag[name]
spec
validate
zsh
zsh/_colorls
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ A Ruby script that colorizes the `ls` output with color and icons. Here are the
- `--gs` (or) `--git-status`
- `--sd` (or) `--sort-dirs` or `--group-directories-first`
- `--sf` (or) `--sort-files`
- `--df` (or) `--dots-first`
- `-t`
- [Combination of flags](#combination-of-flags)
- [Installation](#installation)
Expand Down
2 changes: 2 additions & 0 deletions colorls.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ POST_INSTALL_MESSAGE = %(
Sort by files : -sf flag has been renamed to --sf
Git status : -gs flag has been renamed to --gs

Sort Dots First: --df, --dots-first - sort dot-files and dot-folders first

Clubbed flags : `colorls -ald` works
Help menu : `colorls -h` provides all possible flag options

Expand Down
139 changes: 116 additions & 23 deletions lib/colorls/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def init_colors(colors)
color = case key
when 'r' then :read
when 'w' then :write
when '-' then :no_access
when 'd', '-' then :no_access
when 'x', 's', 'S', 't', 'T' then :exec
end
hash[key] = key.colorize(@colors[color]).freeze
Expand Down Expand Up @@ -196,22 +196,88 @@ def filter_contents
def sort_contents
case @sort
when :extension
@contents.sort_by! do |f|
name = f.name
ext = File.extname(name)
name = name.chomp(ext) unless ext.empty?
[ext, name].map { |s| CLocale.strxfrm(s) }
end
sort_by_extension
when :time
@contents.sort_by! { |a| -a.mtime.to_f }
sort_by_time
when :size
@contents.sort_by! { |a| -a.size }
sort_by_size
when :df
sort_by_dot_first
else
@contents.sort_by! { |a| CLocale.strxfrm(a.name) }
sort_normal
end
@contents.reverse! if @reverse
end

def sort_by_size
@contents.sort_by! do |f|
if @group
link_context = update_content_if_show_symbol_dest(f, true)
is_dir = f.symlink? && link_context.directory? ? 0 : 1
else
is_dir = 0
end
[is_dir, -f.size]
end
end

def sort_by_time
@contents.sort_by! do |f|
if @group
link_context = update_content_if_show_symbol_dest(f, true)
is_dir = f.symlink? && link_context.directory? ? 0 : 1
else
is_dir = 0
end
[is_dir, -f.mtime.to_f]
end
end

def sort_normal
@contents.sort_by! do |f|
if @group
link_context = update_content_if_show_symbol_dest(f, true)
is_dir = f.symlink? && link_context.directory? ? 0 : 1
else
is_dir = 0
end
[is_dir, CLocale.strxfrm(f.name)]
end
end

def sort_by_extension
@contents.sort_by! do |f|
name = f.name
ext = File.extname(name)
name = name.chomp(ext) unless ext.empty?
[ext, name].map { |s| CLocale.strxfrm(s) }
end
end

def sort_by_dot_first_grouped(content)
name = content.name
link_context = update_content_if_show_symbol_dest(content, true)
# Check if the name starts with a dot
if content.symlink? && link_context.directory?
name.start_with?('.') ? 0 : 1
else
name.start_with?('.') ? 2 : 3
end
end

def sort_by_dot_first
@contents.sort_by! do |f|
name = f.name
dot_prefix = if @group
sort_by_dot_first_grouped(f)
else
name.start_with?('.') ? 0 : 1
end
# Return an array where dot-prefixed names are sorted first
[dot_prefix, CLocale.strxfrm(name)]
end
end

def group_contents
return unless @group

Expand Down Expand Up @@ -245,9 +311,11 @@ def format_mode(rwx, special, char)
def mode_info(stat)
m = stat.mode

format_mode(m >> 6, stat.setuid?, 's') +
format_mode(m >> 3, stat.setgid?, 's') +
format_mode(m, stat.sticky?, 't')
info = stat.directory? ? @modes['d'] : @modes['-']
info += format_mode(m >> 6, stat.setuid?, 's')
info += format_mode(m >> 3, stat.setgid?, 's')
info += format_mode(m, stat.sticky?, 't')
info
end

def user_info(content)
Expand Down Expand Up @@ -367,7 +435,9 @@ def update_content_if_show_symbol_dest(content, show_symbol_dest_flag)
return content if content.link_target.nil?
return content if content.dead?

FileInfo.info(content.link_target)
target = content.link_target
target = File.join(content.parent, target) if !target.start_with?('/') && !target.start_with?('\\')
FileInfo.info(target)
end

def out_encode(str)
Expand All @@ -376,17 +446,30 @@ def out_encode(str)

def fetch_string(content, key, color, increment)
@count[increment] += 1
value = increment == :folders ? @folders[key] : @files[key]
logo = value.gsub(/\\u[\da-f]{4}/i) { |m| [m[-4..].to_i(16)].pack('U') }
name = @hyperlink ? make_link(content) : content.show
name += content.directory? && @indicator_style != 'none' ? '/' : ' '
entry = @icons ? "#{out_encode(logo)} #{out_encode(name)}" : out_encode(name).to_s
entry = entry.bright if !content.directory? && content.executable?

symlink_info_string = symlink_info(content)
symlink_content = update_content_if_show_symbol_dest(content,true)
entry, color = fetch_string_entry(content, symlink_content, key, color, increment)
git_info_string = git_info(content)

content = update_content_if_show_symbol_dest(content,@show_symbol_dest)

"#{inode(content)} #{long_info(content)} #{git_info(content)} #{entry.colorize(color)}#{symlink_info_string}"
"#{inode(content)} #{long_info(content)} #{git_info_string} #{entry.colorize(color)}#{symlink_info_string}"
end

def fetch_string_name(content, symlink_content)
name = @hyperlink ? make_link(content) : content.show
name += (content.directory? || symlink_content.directory?) && @indicator_style != 'none' ? '/' : ' '
name
end

def fetch_string_entry(content, symlink_content, key, color, increment)
key, color, = options(symlink_content) if content.symlink?
value = increment == :folders || symlink_content.directory? ? @folders[key] : @files[key]
logo = value.gsub(/\\u[\da-f]{4}/i) { |m| [m[-4..].to_i(16)].pack('U') }
name = fetch_string_name(content, symlink_content)
entry = @icons ? "#{out_encode(logo)} #{out_encode(name)}" : out_encode(name).to_s
entry = entry.bright if !content.directory? && !content.symlink? && content.executable?
[entry, color]
end

def ls_line(chunk, widths)
Expand Down Expand Up @@ -433,7 +516,7 @@ def options_directory(content)
end

def options_file(content)
key = File.extname(content.name).delete_prefix('.').downcase.to_sym
key = determine_key_for_file(content)
key = @file_aliases[key] unless @files.key?(key)

color = file_color(content, key)
Expand All @@ -444,6 +527,16 @@ def options_file(content)
{key: key, color: color, group: group}
end

def determine_key_for_file(content)
extension = File.extname(content.name).delete_prefix('.').downcase
if extension.empty?
filename = content.name.match(/\A\.?(.+)/)[1]
filename.downcase.to_sym
else
extension.to_sym
end || :default
end

def tree_contents(path)
@contents = Dir.entries(path, encoding: ColorLS.file_encoding)

Expand Down
15 changes: 8 additions & 7 deletions lib/colorls/flags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,24 @@ def add_sort_options(options)
options.separator ''
options.separator 'sorting options:'
options.separator ''
configure_sort_options(options)
end

def configure_sort_options(options)
options.on('--sd', '--sort-dirs', '--group-directories-first', 'sort directories first') { @opts[:group] = :dirs }
options.on('--sf', '--sort-files', 'sort files first') { @opts[:group] = :files }
options.on('--df', '--dots-first', 'sort dot-files and dot-folders first') { @opts[:sort] = :df }
options.on('-t', 'sort by modification time, newest first') { @opts[:sort] = :time }
options.on('-U', 'do not sort; list entries in directory order') { @opts[:sort] = false }
options.on('-S', 'sort by file size, largest first') { @opts[:sort] = :size }
options.on('-X', 'sort by file extension') { @opts[:sort] = :extension }
options.on(
'--sort=WORD',
%w[none time size extension],
'sort by WORD instead of name: none, size (-S), time (-t), extension (-X)'
%w[none time size extension df],
'sort by WORD instead of name: none, size (-S), time (-t), extension (-X), df (--df)'
) do |word|
@opts[:sort] = case word
when 'none' then false
else word.to_sym
end
@opts[:sort] = (word == 'none' ? false : word.to_sym)
end

options.on('-r', '--reverse', 'reverse order while sorting') { @opts[:reverse] = true }
end

Expand Down
2 changes: 1 addition & 1 deletion lib/colorls/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module ColorLS
VERSION = '1.5.0'
VERSION = '1.5.1'
end
Loading