fit

command module
v0.0.0-...-1a9128c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 10, 2023 License: MIT Imports: 9 Imported by: 0

README

# fit

Act like `less -S` for non-paged output: trim lines to fit in the
terminal.

## 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

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL