# fit
Act like `less -S` for non-paged output: trim lines to fit in the
terminal.
It used to only read stdin. Now you can use it as a "cat" that fits
(ie, give it filenames to display).
## Background / motivation / "My journey to now"
I'm a big fan of `less -S` (trims lines to width of terminal) and in
vim/nvim `:set nowrap`. In fact, I should probably set a
leader shortcut in vim/nvim for toggling line wrapping since I use it so
much. Sometimes I just really don't want to see wrapped lines, I guess.
I had a shell script (called "fit") consisting of:
```bash
cut -c -$(tput cols)
```
That doesn't work in all cases. It was usually fine, but annoying when
I wanted it to work and it didn't. The problem is probably tabs and
utf8.
Handling utf8 is the "journey" I want to try to describe.
So, I "sort-of" understand the relationship of bytes to runes in go, and
the basics of dealing with that sort of thing. But when it came time to
find the functions I needed to use to deal with strings and trim them to
the terminal width, I had to go through several things before I found
one that (I think) works.
What I need is to trim a line so that it fits in the fixed width of the
terminal this command is being run in. Turns out that isn't the
simplest thing in the world!
As a slight aside, it seems like all of this should be available through
or handled by package unicode/utf8 in the standard library. But unless
I'm *really* missing something, it isn't there. And not even
utf8.RuneCountInString() gives me the answer that matters. I need to
fit any utf8-encoded string into a fixed number of (fixed width)
characters, but, for instance, utf8.RuneCountInString("🧡💛💚💙💜")
gives you 5, which okay, that *is* the count of runes in the string.
But I want to know how much *space* it takes up, which is 10 spaces.
Upon finding the thing that worked, it's obvious why RuneCountInString
doesn't work: I don't care about the rune count! I want to know how
many terminal columns ("spaces") a string takes up, and that isn't the
same as how many runes are in a string.
So, package unicode/utf8 didn't work for me, neither did package
golang.org/x/exp/utf8string (they both work the same, it seems: they
count runes... just like they say).
The answer, for me, was github.com/mattn/go-runewidth. The "aha" (or so
I hoped) was in the description of runewidth.StringWidth: "StringWidth
return width *as you can see*" (emphasis mine). So, all right! (And in
fact, see the file cmd/compareutf8/compareutf8.go to see it in action.)
Sticking with only using functions from that package (both for measuring
the width of lines (which I don't do any more; you can't do it if you
need to account for tabs) and for truncating/trimming them) is what
works for me. It seems that under the covers, github.com/rivo/uniseg is
probably doing the heavy lifting, and I'm not going to dig further into
that now (although I did find reference to package uniseg prior to
finding mattn's library).
(See end of this file for a full listing of the tabs that constituted
this "journey".)
Now to handle tabs... (Update: done.)
## License
MIT
## Appendix A: my journey, in tabs
utf8 - godocs.io
https://godocs.io/unicode/utf8
golang number of runes in a string at DuckDuckGo
https://duckduckgo.com/?q=golang+number+of+runes+in+a+string&ia=web
go - How to get the number of characters in a string - Stack Overflow
https://stackoverflow.com/questions/12668681/how-to-get-the-number-of-characters-in-a-string
rivo/uniseg: Unicode Text Segmentation, Word Wrapping, and String Width Calculation in Go
https://github.com/rivo/uniseg
uniseg - godocs.io
https://godocs.io/github.com/rivo/uniseg
go - Golang truncate strings with special characters without corrupting data - Stack Overflow
https://stackoverflow.com/questions/46415894/golang-truncate-strings-with-special-characters-without-corrupting-data
utf8string - godocs.io
https://godocs.io/golang.org/x/exp/utf8string
golang rune width at DuckDuckGo
https://duckduckgo.com/?q=golang+rune+width&ia=web
go-runewidth/runewidth.go at master · mattn/go-runewidth
https://github.com/mattn/go-runewidth/blob/master/runewidth.go#L193
runewidth - godocs.io
https://godocs.io/github.com/mattn/go-runewidth