diff --git a/README.md b/README.md index b19ac36..9fe0a6f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # `ll` - a more informative `ls`, based on [`k`][1] -[![Waffle.io - Summary][7]][8] [![Travis Build][9]][10] +[![Travis Build][9]][10] ## Description @@ -29,7 +29,7 @@ Calling `ll` provides a full file listing for a directory, similar to calling Files sizes are graded from green for small (< 1k), to red for huge (> 1mb). -Human readable files sizes can be shown by using the `-h` flag. +Human readable files sizes can be shown by using the `-h` or `--human` flag. ### "Rotting" dates @@ -74,35 +74,33 @@ and install using the following instructions. ### Requirements -- [Nim][3], minimum v0.19.0 +- [Nim][3], minimum v0.20.0 - `make` ### Steps -Firstly install [Nim][3]. You'll need to install version 0.19 as a +Firstly install [Nim][3]. You'll need to install version 0.20 as a minimum. I personally use [`asdf`][6] to manage Nim versions on my machine. With `asdf` installed, this is as simple as calling `asdf -install nim v0.19.0`. +install nim v0.20.0`. Once Nim is installed, clone this repository. From within the cloned -directory, call `make release` which will build `ll` into the working -directory. Copy the resulting `ll` binary to a location in your -`$PATH` (eg. `/usr/local/bin`). +directory, call `make install` which will build `ll` into the working +directory and will then opy the resulting `ll` binary to `/usr/local/bin`. ## Usage $ ll -That's it. For more options, pass `--help`. Alternatively, read the -[usage](src/usage.txt) file. +That's it. For more options, pass `-?` or `--help`. ## Development -`ll` is developed using Github issues and [Kanban][4] (via -[Waffle][5]). If you would like to request a feature or report a bug, -please add a new issue [here](https://github.com/OldhamMade/ll/issues) -and we'll do our best to address them. Please note that this is not a -funded project and fixes will be addressed on a best-effort basis. +`ll` is developed using Github issues and [Kanban][4]. If you would +like to request a feature or report a bug, please add a new issue +[here](https://github.com/OldhamMade/ll/issues) and we'll do our best +to address them. Please note that this is not a funded project and +fixes will be addressed on a best-effort basis. Contributions and pull-requests are always welcome, as is constructive feedback around code structure, hints, tips, etc. @@ -147,7 +145,6 @@ the listing; I'm currently reviewing what would be most useful. [2]: https://en.wikipedia.org/wiki/Z_shell [3]: https://nim-lang.org [4]: https://en.wikipedia.org/wiki/Kanban -[5]: https://waffle.io [6]: https://github.com/asdf-vm/asdf [7]: https://badge.waffle.io/03e04bd3c5dd71dd392210b4479adccc.svg?columns=all [8]: https://waffle.io/OldhamMade/ll diff --git a/ll.nimble b/ll.nimble index a0fb14e..3bc6bbd 100644 --- a/ll.nimble +++ b/ll.nimble @@ -1,6 +1,6 @@ # Package -version = "0.1.0" +version = "0.2.0" author = "Phillip Oldham" description = "ll - a more informative ls, based on k" license = "MIT" diff --git a/src/ll.nim b/src/ll.nim index 706e7cb..5cc8ab2 100644 --- a/src/ll.nim +++ b/src/ll.nim @@ -592,6 +592,15 @@ proc getFileList(path: string, displayopts: DisplayOpts): seq[Entry] = proc llCompose( path: string, + displayopts: DisplayOpts): string = + let + entries = getFileList(path, displayopts) + formatted = formatattributes(entries, displayopts) + + result = formatSummary(entries) & "\n" & tabulate(formatted) + + +proc buildDisplayOpts( all = false, aall = true, dirsOnly = false, @@ -600,8 +609,7 @@ proc llCompose( sortByMtime = false, sortReverse = false, human = false, - vcs = true): string = - + vcs = true): DisplayOpts = var optAll = if all: DisplayAll.all @@ -619,24 +627,22 @@ proc llCompose( elif sortByMtime: DisplaySort.mtime else: DisplaySort.default - let - displayOpts = DisplayOpts( - all: optAll, - dirs: optDirs, - size: optSize, - sortBy: optSort, - reversed: sortReverse, - vcs: vcs, - hasGit: gitAvailable(), - ) - entries = getFileList(path, displayopts) - formatted = formatattributes(entries, displayopts) - - result = formatSummary(entries) & "\n" & tabulate(formatted) + return DisplayOpts( + all: optAll, + dirs: optDirs, + size: optSize, + sortBy: optSort, + reversed: sortReverse, + vcs: vcs, + hasGit: gitAvailable(), + ) -proc getTargetPath(path: string): string = - var path = path +proc getTargetPath(path: seq[string]): string = + var + path = + if path.len < 1: "" + else: path[0] case path of "": @@ -656,7 +662,7 @@ when isMainModule: import cligen proc ll( - path = @[""], + path: seq[string], all = false, almost_all = false, directory = false, @@ -666,16 +672,25 @@ when isMainModule: reverse = false, human = false, no_vcs = false) = - echo llCompose(getTargetPath path[0], all, almost_all, directory, - no_directory, size, mtime, reverse, human, not no_vcs) + + var + displayOpts = + buildDisplayOpts(all, almost_all, directory, no_directory, + size, mtime, reverse, human, no_vcs) + + echo llCompose(getTargetPath path, displayOpts) clCfg.version = AppVersionFull dispatch ll, - short = {"size": 'S', - "mtime": 't', - "no_vcs": 'V', - "almost_all": 'A', - "version": 'v'}, + short = { + "size": 'S', + "mtime": 't', + "no_vcs": 'V', + "almost_all": 'A', + "version": 'v', + "human": 'h', + "help": '?' + }, help = { "all": "list entries starting with .", "almost_all": "list all except . and ..", diff --git a/tests/listing_tests.nim b/tests/listing_tests.nim index f2472dc..204d6db 100644 --- a/tests/listing_tests.nim +++ b/tests/listing_tests.nim @@ -23,7 +23,7 @@ var proc setUpBasicListing() = tmpdir = mkdtemp() if tmpdir.len != 0: - echo " [su] Created tmpdir: $#".format(tmpdir).fgDarkGray() + echo " [su] Created tmpdir: $#".format(tmpdir, buildDisplayOpts()).fgDarkGray() for i in 1..9: writeFile(tmpdir / $i, $i) @@ -33,7 +33,7 @@ proc setUpBasicListing() = proc setUpDirectoryListing() = tmpdir = mkdtemp() if tmpdir.len != 0: - echo " [su] Created tmpdir: $#".format(tmpdir).fgDarkGray() + echo " [su] Created tmpdir: $#".format(tmpdir, buildDisplayOpts()).fgDarkGray() for i in 1..9: createDir(tmpdir / $i) @@ -42,7 +42,7 @@ proc setUpDirectoryListing() = proc setUpMixedListing() = tmpdir = mkdtemp() if tmpdir.len != 0: - echo " [su] Created tmpdir: $#".format(tmpdir).fgDarkGray() + echo " [su] Created tmpdir: $#".format(tmpdir, buildDisplayOpts()).fgDarkGray() for i in 1..4: createDir(tmpdir / $i) @@ -54,7 +54,7 @@ proc setUpMixedListing() = proc setUpSymlinkListing() = tmpdir = mkdtemp() if tmpdir.len != 0: - echo " [su] Created tmpdir: $#".format(tmpdir).fgDarkGray() + echo " [su] Created tmpdir: $#".format(tmpdir, buildDisplayOpts()).fgDarkGray() for i in 1..4: writeFile(tmpdir / $i, $i) @@ -68,7 +68,7 @@ proc setUpSymlinkListing() = proc setUpSizedListing() = tmpdir = mkdtemp() if tmpdir.len != 0: - echo " [su] Created tmpdir: $#".format(tmpdir).fgDarkGray() + echo " [su] Created tmpdir: $#".format(tmpdir, buildDisplayOpts()).fgDarkGray() for i in 1..9: writeFile(tmpdir / $i, $i.repeat(i)) @@ -87,10 +87,12 @@ proc getExampleOutput(sortReverse=false, sortBySize=false, sortByMtime=false, di echo "\nExample output:" echo llCompose( tmpdir, - sortReverse=sortReverse, - sortBySize=sortBySize, - sortByMtime=sortByMtime, - dirsOnly=dirsOnly, + buildDisplayOpts( + sortReverse=sortReverse, + sortBySize=sortBySize, + sortByMtime=sortByMtime, + dirsOnly=dirsOnly, + ) ) echo "" @@ -101,7 +103,7 @@ suite "basic file listing tests": test "it returns the correct number of entries": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -115,7 +117,7 @@ suite "basic file listing tests": var entries: seq[string] expected: seq[string] - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -133,7 +135,7 @@ suite "basic file listing tests": test "it contains permissions": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -148,7 +150,7 @@ suite "basic file listing tests": test "it contains owner details": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -167,7 +169,7 @@ suite "basic file listing tests": test "it contains a modified datetime": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -200,7 +202,7 @@ suite "directory listing tests": test "it returns the correct number of entries": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -212,7 +214,7 @@ suite "directory listing tests": test "it identifies directories": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -229,7 +231,7 @@ suite "symlink listing tests": test "it returns the correct number of entries": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -241,7 +243,7 @@ suite "symlink listing tests": test "it identifies symlinks": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -254,7 +256,7 @@ suite "symlink listing tests": test "it displays symlinks": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -267,7 +269,7 @@ suite "symlink listing tests": test "it displays broken symlinks": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -367,7 +369,7 @@ suite "sorting option tests: reverse": var entries: seq[string] expected: seq[string] - lines = llCompose(tmpdir, sortReverse=true).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts(sortReverse=true)).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -397,7 +399,7 @@ suite "sorting option tests: size": var entries: seq[string] expected: seq[string] - lines = llCompose(tmpdir, sortBySize=true).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts(sortBySize=true)).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -419,7 +421,7 @@ suite "sorting option tests: size": var entries: seq[string] expected: seq[string] - lines = llCompose(tmpdir, sortBySize=true, sortReverse=true).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts(sortBySize=true, sortReverse=true)).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -447,7 +449,7 @@ suite "sorting option tests: modified time": var entries: seq[string] expected: seq[string] - lines = llCompose(tmpdir, sortByMtime=true).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts(sortByMtime=true)).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -469,7 +471,7 @@ suite "sorting option tests: modified time": var entries: seq[string] expected: seq[string] - lines = llCompose(tmpdir, sortByMtime=true, sortReverse=true).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts(sortByMtime=true, sortReverse=true)).splitLines() lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -495,7 +497,7 @@ suite "filter option tests: directories": test "it shows only directories": var - lines = llCompose(tmpdir, dirsOnly=true).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts(dirsOnly=true)).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) @@ -507,7 +509,7 @@ suite "filter option tests: directories": test "it shows only files": var - lines = llCompose(tmpdir, filesOnly=true).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts(filesOnly=true)).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine).map(clean) diff --git a/tests/path_tests.nim b/tests/path_tests.nim index 8c93a35..541c8f2 100644 --- a/tests/path_tests.nim +++ b/tests/path_tests.nim @@ -15,13 +15,13 @@ suite "basic path tests": trim = (s: string) => s.strip(leading=false, chars={'/'}) check: - getTargetPath("..").trim == expandFilename(getCurrentDir() / "..").trim - getTargetPath(".").trim == getCurrentDir().trim - getTargetPath("~").trim == getHomeDir().trim + getTargetPath(@[".."]).trim == expandFilename(getCurrentDir() / "..").trim + getTargetPath(@["."]).trim == getCurrentDir().trim + getTargetPath(@["~"]).trim == getHomeDir().trim test "it recognises absolute paths": if defined(macosx): - check getTargetPath("/tmp") == "/private/tmp" + check getTargetPath(@["/tmp"]) == "/private/tmp" else: - check getTargetPath("/tmp") == "/tmp" + check getTargetPath(@["/tmp"]) == "/tmp" diff --git a/tests/specials_tests.nim b/tests/specials_tests.nim index 435ac6e..7f5f568 100644 --- a/tests/specials_tests.nim +++ b/tests/specials_tests.nim @@ -45,7 +45,7 @@ proc tearDownSuite() = proc getExampleOutput() = echo "\nExample output:" - echo llCompose(tmpdir) + echo llCompose(tmpdir, buildDisplayOpts()) echo "" @@ -55,7 +55,7 @@ suite "setuid file listing tests": test "it identifies the setuid bit": var - lines = llCompose(tmpdir).splitLines() + lines = llCompose(tmpdir, buildDisplayOpts()).splitLines() entries: seq[string] lines = filter(lines, (l) => not l.isSummaryLine)