1
1
mirror of https://github.com/walles/moar.git synced 2024-09-11 12:15:43 +03:00

Three-group line numbers

Both the numbers in the left column of the file display, and the line
numbers shown in the page footer.

Fixes #6.
This commit is contained in:
Johan Walles 2021-05-21 19:29:22 +02:00
parent 6330e255d1
commit 7e3a73f053
5 changed files with 53 additions and 10 deletions

21
m/numberFormatter.go Normal file
View File

@ -0,0 +1,21 @@
package m
import "fmt"
// Formats a number into a string with _ between each three-group of digits
func formatNumber(number uint) string {
result := ""
chars := []rune(fmt.Sprint(number))
addCount := 0
for i := len(chars) - 1; i >= 0; i-- {
char := chars[i]
if len(result) > 0 && addCount%3 == 0 {
result = "_" + result
}
result = string(char) + result
addCount++
}
return result
}

18
m/numberFormatter_test.go Normal file
View File

@ -0,0 +1,18 @@
package m
import (
"testing"
"gotest.tools/assert"
)
func TestNumberFormatting(t *testing.T) {
assert.Equal(t, "1", formatNumber(1))
assert.Equal(t, "10", formatNumber(10))
assert.Equal(t, "100", formatNumber(100))
assert.Equal(t, "1_000", formatNumber(1000))
assert.Equal(t, "10_000", formatNumber(10000))
assert.Equal(t, "100_000", formatNumber(100000))
assert.Equal(t, "1_000_000", formatNumber(1000000))
assert.Equal(t, "10_000_000", formatNumber(10000000))
}

View File

@ -3,7 +3,6 @@ package m
import (
"fmt"
"regexp"
"strconv"
"time"
"unicode"
"unicode/utf8"
@ -29,7 +28,7 @@ type eventSpinnerUpdate struct {
type eventMoreLinesAvailable struct{}
// Styling of line numbers
var _NumberStyle = twin.StyleDefault.WithAttr(twin.AttrDim)
var _numberStyle = twin.StyleDefault.WithAttr(twin.AttrDim)
// Pager is the main on-screen pager
type Pager struct {
@ -122,7 +121,12 @@ func (p *Pager) _AddLine(fileLineNumber *int, numberPrefixLength int, screenLine
lineNumberString := ""
if numberPrefixLength > 0 && fileLineNumber != nil {
lineNumberString = fmt.Sprintf("%*d ", numberPrefixLength-1, *fileLineNumber)
lineNumberString = formatNumber(uint(*fileLineNumber))
if len(lineNumberString) > numberPrefixLength {
panic(fmt.Errorf(
"lineNumberString <%s> longer than numberPrefixLength %d",
lineNumberString, numberPrefixLength))
}
} else {
numberPrefixLength = 0
}
@ -132,7 +136,7 @@ func (p *Pager) _AddLine(fileLineNumber *int, numberPrefixLength int, screenLine
break
}
p.screen.SetCell(column, screenLineNumber, twin.NewCell(digit, _NumberStyle))
p.screen.SetCell(column, screenLineNumber, twin.NewCell(digit, _numberStyle))
}
tokens := createScreenLine(p.leftColumnZeroBased, screenWidth-numberPrefixLength, line, p.searchPattern)
@ -220,7 +224,7 @@ func (p *Pager) _AddLines(spinner string) {
//
// Offsets figured out through trial-and-error...
lastLineOneBased := lines.firstLineOneBased + len(lines.lines) - 1
numberPrefixLength := len(strconv.Itoa(lastLineOneBased)) + 1
numberPrefixLength := len(formatNumber(uint(lastLineOneBased))) + 1
if numberPrefixLength < 4 {
// 4 = space for 3 digits followed by one whitespace
//

View File

@ -456,11 +456,11 @@ func (r *Reader) _CreateStatusUnlocked(firstLineOneBased int, lastLineOneBased i
percent := int(100 * float64(lastLineOneBased) / float64(len(r.lines)))
return fmt.Sprintf("%s%d-%d/%d %d%%",
return fmt.Sprintf("%s%s-%s/%s %d%%",
prefix,
firstLineOneBased,
lastLineOneBased,
len(r.lines),
formatNumber(uint(firstLineOneBased)),
formatNumber(uint(lastLineOneBased)),
formatNumber(uint(len(r.lines))),
percent)
}

View File

@ -261,7 +261,7 @@ func testStatusText(t *testing.T, fromLine int, toLine int, totalLines int, expe
func TestStatusText(t *testing.T) {
testStatusText(t, 1, 10, 20, "1-10/20 50%")
testStatusText(t, 1, 5, 5, "1-5/5 100%")
testStatusText(t, 998, 999, 1000, "998-999/1000 99%")
testStatusText(t, 998, 999, 1000, "998-999/1_000 99%")
testStatusText(t, 0, 0, 0, "<empty>")
testStatusText(t, 1, 1, 1, "1-1/1 100%")