diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7d43163 --- /dev/null +++ b/README.md @@ -0,0 +1,137 @@ +# lat +> lat | lazy cat - a cat clone with some quality-of-life embellishments + +## About + +`lat` is a solution to a problem that doesn't exist. It's the awkward middle child in-between `cat` and `bat`. It was created because the author didn't want to have to configure `bat` just to get decent file printing, but wanted a little more control than `cat` offered. + +`lat` does not expect to be used. `lat` expects to be forgotten and shunted into a corner because it does not belong in the slightest. + +`lat` is fast. Here are the hyperfine results comparing `cat`, `lat`, and `bat` on a ~24MB text file: + +```test +❯ hyperfine "cat log.log" "lat log.log" "bat log.log" -N --warmup 200 + Benchmark 1: cat log.log + Time (mean ± σ): 3.6 ms ± 0.3 ms [User: 0.4 ms, System: 2.3 ms] + Range (min … max): 3.1 ms … 5.0 ms 851 runs + + Benchmark 2: lat log.log + Time (mean ± σ): 6.2 ms ± 0.7 ms [User: 0.4 ms, System: 4.2 ms] + Range (min … max): 5.5 ms … 14.5 ms 496 runs + + Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options. + + Benchmark 3: bat log.log + Time (mean ± σ): 103.9 ms ± 0.5 ms [User: 37.5 ms, System: 65.6 ms] + Range (min … max): 103.2 ms … 104.8 ms 28 runs + + Summary + 'cat log.log' ran + 1.74 ± 0.26 times faster than 'lat log.log' + 29.10 ± 2.85 times faster than 'bat log.log' +``` +> tested on a 2020 M1 MacBook Pro 16GB + +as you can see, the extra features do take their toll on performance, but overall, `lat` is generally nearly on-par with `cat`, and *far* faster than `bat`. + +## Use + +`lat` can, for the most part, be a direct drop in for `cat`, however it really shines when embedded into another program. For example, in `fzf` `lat` makes an excellent viewer with the command `fzf --command lat -l {}`. + +![Using lat in fzf](social/render/fzf_embed.gif) + +Soon, I plan to add the ability to live-write to `lat`. That means that `lat` can become yet another output stream. + +For example, this should be possible in a future version of `lat` + +```c +int main(void) { + FILE *st = popen("lat -l", "w"); + if (st == NULL) + exit(1); + + fprintf(st, "look ma, i'm formatted!") + + pclose(st); +} +``` + +### Features and Flags + +#### `--color` +Completely disables or enables all colored output from `lat`. +##### Example +![Color in lat](social/render/color.gif) +> `lat` also respects [NO_COLOR](https://no-color.org/), but `--color` overrides it + +#### `--lines` +Print numbers for each line of the file. +##### Example +![Line numbers in lat](social/render/line_numbers.gif) + +#### `--headers` +Shows or hides formatted file data headers. +##### Example +![Headers in lat](social/render/headers.gif) + +#### `--binary` +By default, `lat` will attempt to detect if the file is printable or not. If the file isn't (e.g. you ran `lat file.pdf`) then lat will enter *`binary mode`*. In *`binary mode`*, `lat` will skip a lot of processing in favor of speed. +You can force *`binary mode`* to be `on` or `off` with the flags `-b` and `-bb` respectively. +##### Example +![Binary Mode in lat](social/render/binary.gif) + +#### `--literal` +`lat` is smart enough to print all non-file characters to a separate filestream. That way, the output of `lat` can be used to con**cat**enate files, the way it was originally meant to be. +However, sometimes you want those extra symbols. +`--literal` prints everything out to the primary filestream (usually `stdout`) +##### Example +![Literal output in lat](social/render/literal.gif) + +#### `--pager` +`lat` comes with out-of-the-box support for paging in `less`. If you don't want your file messing up your terminal, just `-p` it. +##### Example +![Paging in lat](social/render/pager.gif) + +#### If there is a feature you'd like to see, feel free to make an issue (1x points). If you're feeling especially savvy, make a PR with the feature (10x points). + + +## Helptext +> `lat --help` + +```text +lat | lazy cat - a cat clone with some quality-of-life embellishments + +usage: lat [-cntblpVh] [file...] + +options: + -c, --color toggle color + -n, --lines toggle line numbers + -t, --headers toggle file info headers + -b, --binary toggle binary mode, -b forces binary and -bb forces NOT binary + -l, --literal print everything to stdout (or equivalent) + -p, --pager print file with the pager (uses less) + -V, --version show program version + -h, --help display this help text (--help shows additional info) + +environment: + NO_COLOR, see https://no-color.org/ + +examples: +lat file1 + print the contents of file1 with the default formatting +lat - file1 + read from stdin (the '-' flag reads from stdin) and then print the contents of stdin and file1 +lat -nc file1 file2 + print the contents of file1 and file2 without printing line numbers or colors +lat --binary file.txt + force file.txt to be treated as a binary file +lat -bb --pager file.txt + force file.txt to NOT be treated as a binary file and print it in the pager +curl example.com | lat + pipe the results of 'curl example.com' into lat +fzf --preview 'lat -l {}' + use lat as the file viewer in fzf + +``` + + diff --git a/social/binary.tape b/social/binary.tape new file mode 100644 index 0000000..1d72483 --- /dev/null +++ b/social/binary.tape @@ -0,0 +1,55 @@ +Require lat +Output social/render/binary.gif + +Set Theme "Gruvbox Dark" +Set WindowBar Rings +Set BorderRadius 10 +Set Margin 10 + +Set FontSize 32 +Set Width 2400 +Set Height 1200 +Set TypingSpeed 0.2 +Set PlaybackSpeed 0.5 + +Type "lat src/main.c" +Sleep 2s +Enter + +Sleep 5s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat -b src/main.c" +Sleep 2s +Enter + +Sleep 5s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat ./build/lat" +Sleep 2s +Enter + +Sleep 5s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat -bb ./build/lat" +Sleep 2s +Enter + +Sleep 5s diff --git a/social/color.tape b/social/color.tape new file mode 100644 index 0000000..2fbae90 --- /dev/null +++ b/social/color.tape @@ -0,0 +1,32 @@ +Require lat +Output social/render/color.gif + +Set Theme "Gruvbox Dark" +Set WindowBar Rings +Set BorderRadius 10 +Set Margin 10 + +Set FontSize 32 +Set Width 2400 +Set Height 1200 +Set TypingSpeed 0.2 +Set PlaybackSpeed 0.5 + +Type "lat src/main.c" +Sleep 2s +Enter + +Sleep 5s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat --color src/main.c" +Sleep 2s +Enter + +Sleep 5s + diff --git a/social/fzf_embed.tape b/social/fzf_embed.tape new file mode 100644 index 0000000..1b65489 --- /dev/null +++ b/social/fzf_embed.tape @@ -0,0 +1,82 @@ +Require lat +Output social/render/fzf_embed.gif + +Set Theme "Gruvbox Dark" +Set WindowBar Rings +Set BorderRadius 10 +Set Margin 10 + +Set FontSize 32 +Set Width 2400 +Set Height 1200 +Set TypingSpeed 0.2 + +Type "fzf --preview 'lat -l {}'" +Sleep 1s + +Enter +Sleep 2s + +Type "main.c" +Sleep 2s +Backspace 7 +Sleep 1s + +Type "types.h" +Sleep 1s +Backspace 8 +Sleep 2s + +Type "file.c" +Sleep 3s +Backspace 7 +Sleep 2s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Up +Sleep 3s + +Enter + +Sleep 2s diff --git a/social/headers.tape b/social/headers.tape new file mode 100644 index 0000000..2116960 --- /dev/null +++ b/social/headers.tape @@ -0,0 +1,33 @@ +Require lat +Output social/render/headers.gif + +Set Theme "Gruvbox Dark" +Set WindowBar Rings +Set BorderRadius 10 +Set Margin 10 + +Set FontSize 32 +Set Width 2400 +Set Height 1200 +Set TypingSpeed 0.2 +Set PlaybackSpeed 0.5 + +Type "lat src/main.c" +Sleep 2s +Enter + +Sleep 5s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat --headers src/main.c" +Sleep 2s +Enter + +Sleep 5s + + diff --git a/social/line_numbers.tape b/social/line_numbers.tape new file mode 100644 index 0000000..0e2a24f --- /dev/null +++ b/social/line_numbers.tape @@ -0,0 +1,31 @@ +Require lat +Output social/render/line_numbers.gif + +Set Theme "Gruvbox Dark" +Set WindowBar Rings +Set BorderRadius 10 +Set Margin 10 + +Set FontSize 32 +Set Width 2400 +Set Height 1200 +Set TypingSpeed 0.2 +Set PlaybackSpeed 0.5 + +Type "lat src/main.c" +Sleep 2s +Enter + +Sleep 4s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat -n src/main.c" +Sleep 2s +Enter + +Sleep 4s diff --git a/social/literal.tape b/social/literal.tape new file mode 100644 index 0000000..9077018 --- /dev/null +++ b/social/literal.tape @@ -0,0 +1,47 @@ +Require lat +Output social/render/literal.gif + +Set Theme "Gruvbox Dark" +Set WindowBar Rings +Set BorderRadius 10 +Set Margin 10 + +Set FontSize 32 +Set Width 2400 +Set Height 1200 +Set TypingSpeed 0.2 +Set PlaybackSpeed 0.5 + +Type "lat src/main.c > example.c" +Sleep 2s +Enter + +Sleep 5s + +Type "cat example.c" +Sleep 2s +Enter + +Sleep 5s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat --literal src/main.c > example.c" +Sleep 2s +Enter + +Sleep 3s + +Type "cat example.c" +Sleep 2s +Enter + +Sleep 5s + +Hide +Type "rm example.c" +Enter diff --git a/social/pager.tape b/social/pager.tape new file mode 100644 index 0000000..2a5ec49 --- /dev/null +++ b/social/pager.tape @@ -0,0 +1,41 @@ +Require lat +Output social/render/pager.gif + +Set Theme "Gruvbox Dark" +Set WindowBar Rings +Set BorderRadius 10 +Set Margin 10 + +Set FontSize 32 +Set Width 2400 +Set Height 1200 +Set TypingSpeed 0.2 +Set PlaybackSpeed 0.5 + +Type "lat src/main.c" +Sleep 2s +Enter + +Sleep 5s + +Type "clear" +Sleep 1s +Enter + +Sleep 2s + +Type "lat --pager src/main.c" +Sleep 2s +Enter + +Sleep 5s + +Down 100 + +Sleep 3s + +Type "q" +Sleep 4s + + +