Compare commits

..

No commits in common. "6e577f1906229a3ec390904d9a26fe2c9fed3a0c" and "36c5d3f68adb0262481b4a7d95a616b1af9c27e1" have entirely different histories.

7 changed files with 107 additions and 31 deletions

2
.gitignore vendored
View File

@ -130,3 +130,5 @@ $RECYCLE.BIN/
*.lnk *.lnk
# End of https://www.toptal.com/developers/gitignore/api/c,macos,windows,linux,c # End of https://www.toptal.com/developers/gitignore/api/c,macos,windows,linux,c
build/

View File

@ -34,6 +34,7 @@ prep:
-@mkdir -p $(IDIR) -@mkdir -p $(IDIR)
-@mkdir -p $(ODIR) -@mkdir -p $(ODIR)
-@mkdir -p $(BINDIR) -@mkdir -p $(BINDIR)
@echo $(BINDIR)/ >> .gitignore
.PHONY: clean .PHONY: clean
clean: clean:

View File

@ -1,12 +1,47 @@
# lat # lat
> lat | lazy cat - a cat clone with some quality-of-life embellishments > lat | lazy cat - a cat clone with some quality-of-life embellishments
[![Build](https://github.com/secondary-smiles/lat/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/secondary-smiles/lat/actions/workflows/c-cpp.yml)
![lat demo](social/render/lat_demo.gif)
## About ## 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` 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` 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 `lat`'s `main.c` source file:
```text
hyperfine "./build/lat src/main.c" "cat src/main.c" "bat src/main.c" -N --warmup 200
Benchmark 1: ./build/lat src/main.c
Time (mean ± σ): 0.2 ms ± 0.0 ms [User: 0.1 ms, System: 0.0 ms]
Range (min … max): 0.1 ms … 0.7 ms 19651 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 2: cat src/main.c
Time (mean ± σ): 0.2 ms ± 0.0 ms [User: 0.2 ms, System: 0.0 ms]
Range (min … max): 0.2 ms … 0.4 ms 13717 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 src/main.c
Time (mean ± σ): 1.4 ms ± 0.7 ms [User: 1.1 ms, System: 0.3 ms]
Range (min … max): 1.1 ms … 6.5 ms 1057 runs
Warning: The first benchmarking run for this command was significantly slower than the rest (2.8 ms). This could be caused by (filesystem) caches that were not filled until after the first run. You are already using the '--warmup' option which helps to fill these caches before the actual benchmark. You can either try to increase the warmup count further or re-run this benchmark on a quiet system in case it was a random outlier. Alternatively, consider using the '--prepare' option to clear the caches before each timing run.
Summary
'./build/lat src/main.c' ran
1.29 ± 0.28 times faster than 'cat src/main.c'
9.14 ± 4.56 times faster than 'bat src/main.c'
```
~~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`.~~
**As of v0.12.2 `lat` is the new fastest of the three!** (on my machine)
## Install ## Install
`lat` is not yet at a stable version (`v1.0.0`), so it is not on any package managers. `lat` is not yet at a stable version (`v1.0.0`), so it is not on any package managers.
@ -15,6 +50,7 @@ git clone https://github.com/secondary-smiles/lat.git
cd lat cd lat
make prep
make make
./build/lat -V ./build/lat -V
@ -22,6 +58,58 @@ make
# now add lat to your $PATH/do whatever you want with the binary # now add lat to your $PATH/do whatever you want with the binary
``` ```
## 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 -r {}`.
![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 -r", "w");
if (st == NULL)
exit(1);
fprintf(st, "look ma, i'm formatted!")
pclose(st);
}
```
> UPDATE: this feature is possible, however the data is only printed upon `pclose`.
### Features and Flags
#### `-c` color
Completely disables or enables all colored output from `lat`.
#### `-l` line numbers
Print numbers for each line of the file.
#### `-t` file title
Shows or hides formatted file data headers.
#### `-b` binary mode
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.
#### `-r` raw output
`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 (with `>` or `|`).
However, sometimes you want those extra symbols.
`-r` prints everything out to the primary filestream (usually `stdout`)
#### `-p` 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.
### `-n` name
`lat` allows you to customize the name of the file shown. This can be useful in demonstrations or when `lat` is embedded in another program.
#### 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 ## Helptext
> `lat -h` > `lat -h`

View File

@ -2,7 +2,7 @@
#define ARG_H #define ARG_H
#include <stdbool.h> #include <stdbool.h>
#define LAT_VERSION "0.13.0" #define LAT_VERSION "0.12.2"
struct config { struct config {
bool isstdin; bool isstdin;

View File

@ -1,5 +1,5 @@
Require lat Require lat
Output social/render/lat_demo.gif Output social/render/name.gif
Set Theme "Gruvbox Dark" Set Theme "Gruvbox Dark"
Set WindowBar Rings Set WindowBar Rings
@ -8,7 +8,7 @@ Set Margin 10
Set FontSize 32 Set FontSize 32
Set Width 2400 Set Width 2400
Set Height 2000 Set Height 1200
Set TypingSpeed 0.2 Set TypingSpeed 0.2
Type "lat Makefile" Type "lat Makefile"

View File

@ -1,7 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdnoreturn.h> #include <stdnoreturn.h>
#include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include "arg.h" #include "arg.h"
@ -25,10 +24,9 @@ void help(void) {
"binary\n" "binary\n"
"\t-r print everything (headers, line numbers, etc.) to " "\t-r print everything (headers, line numbers, etc.) to "
"stdout (or equivalent)\n" "stdout (or equivalent)\n"
"\t-p disable or enable pager (uses less)\n" "\t-p print file with the pager (uses less)\n"
"\t-n <name> manually set the name of the file shown in the title\n" "\t-n <name> manually set the name of the file shown in the title\n"
// "\t-e <program> NONFUNCTIONAL (will be added soon) link extension "\t-e <program> link extension to lat\n"
// to lat\n"
"\t-V show program version\n" "\t-V show program version\n"
"\t-h display this help text\n\n"); "\t-h display this help text\n\n");
printf("environment:\n" printf("environment:\n"

View File

@ -1,13 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "arg.h" #include "arg.h"
#include "file.h" #include "file.h"
#include "process.h" #include "process.h"
#include "types.h" #include "types.h"
#include "util.h" #include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define INVERT_T "\x1b[7m" #define INVERT_T "\x1b[7m"
#define UINVERT_T "\x1b[27m" #define UINVERT_T "\x1b[27m"
@ -53,25 +51,6 @@ void run(FILE *fp, char *filename, bool tty) {
struct filedata f; struct filedata f;
f = readfile(fp, conf.isstdin); f = readfile(fp, conf.isstdin);
// any/all processing to be done
// TODO: maybe multithread?
conf.process = (tty && !f.binary);
if (conf.process) { // file display processing
loadlines(&f);
}
if (conf.extension != NULL) {
// TODO
}
struct winsize w;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1 || w.ws_col != 0) {
if (w.ws_row <= f.lc + 5) {
conf.pager = !conf.pager;
}
}
if (conf.pager) { if (conf.pager) {
st = popen("less", "w"); st = popen("less", "w");
err = st; err = st;
@ -94,6 +73,12 @@ void run(FILE *fp, char *filename, bool tty) {
printheadertop(filename, f.binary); printheadertop(filename, f.binary);
} }
// any/all processing to be done
conf.process = (tty && !f.binary);
if (conf.process) { // file display processing
loadlines(&f);
}
if (conf.process) { if (conf.process) {
int linecount = 1; int linecount = 1;
for (int i = 0; i < f.lc; i++) { for (int i = 0; i < f.lc; i++) {
@ -174,6 +159,8 @@ int main(int argc, char *argv[]) {
conf.headers = conf.headers && tty; conf.headers = conf.headers && tty;
printf("set extension to '%s'\n", conf.extension);
if (argc > 1) { if (argc > 1) {
tty = tty || conf.literal; tty = tty || conf.literal;