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:
parent
6330e255d1
commit
7e3a73f053
21
m/numberFormatter.go
Normal file
21
m/numberFormatter.go
Normal 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
18
m/numberFormatter_test.go
Normal 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))
|
||||
}
|
14
m/pager.go
14
m/pager.go
@ -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
|
||||
//
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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%")
|
||||
|
Loading…
Reference in New Issue
Block a user