diff --git a/dev-ls.plx b/dev-ls.plx new file mode 100755 index 0000000..7ed22af --- /dev/null +++ b/dev-ls.plx @@ -0,0 +1,231 @@ +#!/usr/bin/perl -w +use strict; +use warnings; + +my $colorize = 1; +my %extension = %{extensions()}; +my $colmax; +eval{ + my $terminal = q|/dev/pts/1|; + $colmax = `stty -a <$terminal | grep -Po '(?<=columns )\\d+'`; +}; +$colmax ||= 100; + +my $target; +my $lists; + +foreach (@ARGV){ + if ($_ eq '--demo'){ + my @files = sort keys %extension; + push @files, "[default]"; + $lists = { dirs => [qw/dir1 dir2 dir2/], files => [@files[2..scalar @files]]}; + } elsif ($_ =~ m/(--nocolor|-bw)/i) { + $colorize = 0; + } elsif ($_ =~ m/(--width|-w)=(\d+)/i){ + $colmax = $2; + } elsif ($_ =~ m/(--help|-h|\?)/i){ + print "usage:\n dev-icons.plx [target] [options]\n" + . " default [target] is current directory\n\nOptions:\n" + . " --help, -h, ? : display this info\n" + . " --demo : print a list of all current extensions\n" + . " -w=[number], --width=[number] : set screen width (default 100)\n" + . " -bw, --nocolor : turn off colorization (default is on)\n"; + } elsif ($_ !~ /-/){ + $target = $_; + } +} + +$lists ||= build_lists($target || '.'); + +my @dlist = @{ $lists->{dirs} }; +my @flist = @{ $lists->{files} }; + +my $maxlen = 10; +map {$maxlen = length $_ if length $_ > $maxlen} (@dlist,@flist); + +# hard limit at half colmax, else add 5 +$maxlen = ($maxlen > $colmax/2) ? $colmax/2 : $maxlen + 5; +my @result; +my $line = ''; +my $col = 0; +my $d = scalar @dlist + 1; +@dlist = (@dlist,@flist); +foreach (@dlist){ + $d-- if $d; # is directory? + my $cell = devicons_format($_,$d); + + $line .= $cell; + $col++; + if ($col >= int($colmax/$maxlen)){ + $col = 0; + $line =~ s/\s+$//; # trim + push @result, $line; + $line = ''; + next; + } +} +push @result, ''; +printf join "\n", @result; + +sub build_lists { + my $target = shift; + + opendir(DIR, $target) || die "Unable to access $target: $!"; + my @d_ls = grep {(!/^\.\.?$/) and -d "$target/$_"} readdir(DIR); + rewinddir DIR; + my @f_ls = grep {(!/^\.\.?$/) and -f "$target/$_"} readdir(DIR); + closedir DIR; + + return {dirs => \@d_ls, files => \@f_ls}; + + + } +sub devicons_format { + my ($name, $dir) = @_; + return '' unless $name; + $name =~ m/([^\.]*)$/; + my $ext = $extension{$1} + || $extension{uc $1} + || $extension{'.default'}; + $ext = $extension{'.dir'} if $dir; + + $name = substr($name, 0, $maxlen-8) . "..." if length $name > $maxlen - 1; + $name = "$ext->{symbol} $name"; + my $pad = " " x ($maxlen - length $name); + $name = "$ext->{color}$name\x1b[0m" if $colorize; + + return "$name$pad"; + + + } +sub extensions { + my %color = ( + '.default' => 248, + archive => 2, + audio => 136, + config => 9, + data => 13, + diff => 8, + disk => 1, + err => 196, + font => 108, + game => 177, + image => 5, + image_v => 10, + install => 255, + key => 15, + lock => 248, + markup => 11, + props => 6, + script => 130, + sheet => 148, + src => 4, + src_py => 36, + src_perl => 1, + sql => 223, + style => 161, + txt => 7, + txt_doc => 12, + txt_note => 3, + txt_slide => 166, + video => 10, + x => 240, + ); + + my %category = ( + archive => { symbol => '', set => [qw/7z a arj bz bz2 gz lrz lz lzm lzo rar s7z tar xz zip zipx zoo zpaq zz/]}, + archive_p => { symbol => '', set => [qw/apk bsp cab deb jar jad pak pk3 rpm vdf vpk/]}, + audio => { symbol => '', set => [qw/aac aiff alac ape cda dat fcm flac m4a mid midi mod mp3 sid mp4a wav wma wv wvc/]}, + config => { symbol => '', set => [qw/cfg conf ini Makefile MANIFEST pcf rc viminfo/]}, + data => { symbol => '', set => [qw/accdb accde accdr accdt dump db fmp12 fp7 localstorage mdb mde nc sqlite/]}, + diff => { symbol => '', set => [qw/diff patch/]}, + disk => { symbol => '', set => [qw/bin dmg iso nrg qcow sparseimage toast vcd vmdk/]}, + err => { symbol => '', set => [qw/deny err error stderr/]}, + font => { symbol => '', set => [qw/afm fon fnt otf PFA pfb pfm ttf/]}, + game => { symbol => '', set => [qw/32x a00 a52 a64 a78 adf atr fm2 cdi gb gba gbc gel gg ggl j64 nds nes rom sav sms st/]}, + image => { symbol => '', set => [qw/bmp gif ico jpg jpeg nth png psb psd tif tiff ts/]}, + image_v => { symbol => '', set => [qw/ai eps epsf/]}, + key => { symbol => '', set => [qw/asc bfe enc gpg pem p12 sig signature/]}, + lock => { symbol => '', set => [qw/lock lockfile pid state/]}, + markup => { symbol => '', set => [qw/eml hbs htm html jhtm mustache mht slim twig tt tt2 ejs/]}, + props => { symbol => '', set => [qw/cue description directory json properties rdata rss srt theme torrent urlview xml yml/]}, + script => { symbol => '', set => [qw/awk bash bat fish sed sh vim zsh/]}, + sheet => { symbol => '', set => [qw/csv ods xla xls xlsm xlsx xltm xltx/]}, + src => { symbol => '', set => [qw/d dart go java jl php rb rs scala/]}, + src_c => { symbol => '', set => [qw/c c++ cpp cxx H h++ hpp hxx M tcc/]}, + src_cljr => { symbol => '', set => [qw/clj cljc cljs edn/]}, + src_erl => { symbol => '', set => [qw/erl hrl/]}, + src_f => { symbol => '', set => [qw/fs fsi fsscript fsx/]}, + src_hkl => { symbol => '', set => [qw/hs lhs/]}, + src_js => { symbol => '', set => [qw/coffee js jsm jsp jsx/]}, + src_ms => { symbol => '', set => [qw/cc cp cs sln suo/]}, + src_lisp => { symbol => '', set => [qw/cl lisp ml mli/]}, + src_py => { symbol => '', set => [qw/py pyc pyd pyo/]}, + src_perl => { symbol => '', set => [qw/PL pl plx pm/]}, + sql => { symbol => '', set => [qw/msql mysql pgsql rlib sql/]}, + style => { symbol => '', set => [qw/css less sass scss styl/]}, + txt => { symbol => '', set => [qw/etx info markdown md mkd nfo t txt/]}, + txt_doc => { symbol => '', set => [qw/doc docm docx odb odt pdf rtf/]}, + txt_note => { symbol => '', set => [qw/AUTHORS CHANGES CONTRIBUTORS COPYRIGHT HISTORY INSTALL LICENCE log note NOTICE PATENTS README VERSION/]}, + txt_slide => { symbol => '', set => [qw/pps ppt ppts pptsm pptx pptxm/]}, + video => { symbol => '', set => [qw/asf asm avi divx flv m2v m4v mkv mov mp4/]}, + x_backup => { symbol => '', set => [qw/bak BUP old orig un~/]}, + x_docker => { symbol => '', set => [qw/Dockerfile dockerignore/]}, + x_apple => { symbol => '', set => [qw/CFUserTextEncoding DS_store localized/]}, + x_git => { symbol => '', set => [qw/git gitattributes gitmodules gitignore/]}, + ); + + my %extension = ( + '.default' => { symbol => '', color => "\x1b[38;5;$color{'.default'}m",}, + '.dir' => { symbol => '', color => "\x1b[38;5;14m", }, + ai => { symbol => '' }, + cljs => { symbol => '' }, + d => { symbol => '' }, + Dockerfile => { color => 190 }, + edn => { symbol => '' }, + git => { color => 125 }, + go => { symbol => '' }, + hbs => { symbol => '' }, + java => { symbol => '' }, + jl => { symbol => '' }, + jsx => { symbol => '' }, + mustache => { symbol => '' }, + Makefile => { color => 190 }, + pgsql => { symbol => '' }, + php => { symbol => '' }, + psb => { symbol => '' }, + psd => { symbol => '' }, + rb => { symbol => '' }, + rlib => { symbol => '' }, + rs => { symbol => '' }, + rss => { symbol => '' }, + sass => { symbol => '' }, + scala => { symbol => '' }, + scss => { symbol => '' }, + styl => { symbol => '' }, + ts => { symbol => '' }, + twig => { symbol => '' }, + vim => { symbol => '' }, + ); + + foreach my $cat (keys %category){ + my $color = $color{$cat} + || $color{(split '_', $cat)[0]} + || $color{'.default'}; + + foreach ( @{$category{$cat}{set}} ){ + $extension{$_}{symbol} ||= $category{$cat}{symbol}; + $extension{$_}{color} ||= $color; + + next if $extension{$_}{color} =~ /[^\d]/; + + # condition for 8 / black = background 200 / magenta + $extension{$_}{color} = ($extension{$_}{color} != 8) + ? "\x1b[38;5;$extension{$_}{color}m" + : "\x1b[48;5;200m"; + } + } + + return \%extension; + } +1; diff --git a/devicons-ls b/devicons-ls index 7189187..c8e5b40 100755 --- a/devicons-ls +++ b/devicons-ls @@ -2,132 +2,160 @@ # Author: Ryan L McIntyre # Project: devicons-shell +declare -A colors=( + [dir]=159 + [image]=225 + [code]=085 + [src]=078 + [perl]=085 + [python]=085 + [script]=085 + [data]=085 + [template]=135 + [style]=162 + [text]=105 + [archive]=229 + [default]=248 +) + function devicons_get_directory_symbol { local symbol="" + local clr="${colors[dir]}" - echo "$symbol $1" + echo -e "\x1b[38;5;${clr}m${symbol} $1 \x1b[0m" return 0 } function devicons_get_filetype_symbol { declare -A extensions=( - [txt]=e - [styl]= - [scss]= - [htm]= - [html]= - [slim]= - [ejs]= - [css]= - [less]= - [md]= - [markdown]= - [json]= - [js]= - [jsx]= - [rb]= - [php]= - [py]= - [pyc]= - [pyo]= - [pyd]= - [coffee]= - [mustache]= - [hbs]= - [conf]= - [ini]= - [yml]= - [bat]= - [jpg]= - [jpeg]= - [bmp]= - [png]= - [gif]= - [ico]= - [twig]= - [cpp]= - [c++]= - [cxx]= - [cc]= - [cp]= - [c]= - [hs]= - [lhs]= - [lua]= - [java]= - [sh]= - [fish]= - [ml]=λ - [mli]=λ - [diff]= - [db]= - [sql]= - [dump]= - [clj]= - [cljc]= - [cljs]= - [edn]= - [scala]= - [go]= - [dart]= - [xul]= - [sln]= - [suo]= - [pl]= - [pm]= - [t]= - [rss]= - [f#]= - [fsscript]= - [fsx]= - [fs]= - [fsi]= - [rs]= - [rlib]= - [d]= - [erl]= - [hrl]= - [vim]= - [ai]= - [psd]= - [psb]= - [ts]= - [jl]= + [txt]=e,text + [t]=,text + [markdown]=,text + [md]=,text + [rss]=,text + [styl]=,style + [scss]=,style + [less]=,style + [css]=,style + [htm]=,template + [html]=,template + [slim]=,code + [json]=,data + [coffee]=,src + [js]=,code + [jsx]=,code + [rb]=,src + [php]=,code + [py]=,python + [pyc]=,python + [pyo]=,python + [pyd]=,python + [conf]=,data + [ini]=,data + [yml]=,data + [bat]=,script + [jpg]=,image + [jpeg]=,image + [bmp]=,image + [png]=,image + [gif]=,image + [ico]=,image + [twig]=,template + [tt2]=,template + [mustache]=,template + [hbs]=,template + [ejs]=,template + [cpp]=,src + [c++]=,src + [cxx]=,src + [cc]=,src + [cp]=,src + [c]=,src + [xul]=,code + [hs]=,code + [lhs]=,code + [lua]=,code + [java]=,src + [sh]=,script + [fish]=,script + [ml]=λ,code + [mli]=λ,code + [diff]=,data + [db]=,data + [sql]=,data + [dump]=,data + [clj]=,code + [cljc]=,src + [cljs]=,src + [edn]=,code + [scala]=,src + [go]=,src + [dart]=,src + [sln]=,src + [suo]=,src + [pl]=,perl + [pm]=,perl + [f#]=,src + [fsscript]=,code + [fsx]=,code + [fs]=,code + [fsi]=,code + [rs]=,code + [rlib]=,data + [d]=,code + [erl]=,src + [hrl]=,src + [vim]=,code + [ai]=,image + [psd]=,image + [psb]=,image + [ts]=,image + [jl]=,code + [7z]=,archive + [bz]=,archive + [bz2]=,archive + [gz]=,archive + [tar]=,archive + [xz]=,archive + [zip]=,archive ) local filetype local default= + local symbol=$default local exist_check=1 local input=$1 - local filename="$1" + local clr="default" + local filename=" $1" # using ## for possibly more than one "." (get after last one): local filetype="${filename##*.}" if [ ! -z "$filetype" ] && [ ${extensions[$filetype]+$exist_check} ]; then - local symbol=${extensions[$filetype]} - else - local symbol=$default + clr=${extensions[$filetype]:2} + symbol=${extensions[$filetype]:0:1} fi - echo "$symbol $1" + clr="${colors[$clr]}" + + echo -e "\x1b[38;5;${clr}m${symbol}$filename \x1b[0m " return 0 } # for now wrap piped portion so uses the same 'subshell' # @todo fixme - dont use pipe -find $1 -maxdepth 1 -type f -printf "%P\n" | sort | { while read line; do - lines="$lines $(devicons_get_filetype_symbol $line) \n" +find $1 -maxdepth 1 -mindepth 1 -type d -printf "%P \n" | sort | { while read line; do + lines="$lines $(devicons_get_directory_symbol $line) \n" done -echo -en "$lines \n" | column -n +echo -en "$lines \n" | column } -find $1 -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | sort | { while read line; do - lines="$lines $(devicons_get_directory_symbol $line) \n" +find $1 -maxdepth 1 -type f -printf "%P\n" | sort | { while read line; do + lines="$lines $(devicons_get_filetype_symbol $line)\n" done -echo -en "$lines \n" | column -n +echo -e "$lines \n" | column -c90 } diff --git a/tests/test.7z b/tests/test.7z new file mode 100644 index 0000000..e69de29