1
1
mirror of https://github.com/walles/moar.git synced 2024-09-21 00:49:59 +03:00
Commit Graph

406 Commits

Author SHA1 Message Date
Johan Walles
d36cb1c561 Fix an off-by-one error in a test
Change-Id: I425bc33a611ba96b4d95676b6231e7bc46a87463
2019-11-19 16:58:01 +01:00
Johan Walles
0fc6ee65f5 Fix long-lines-reading bug
Change-Id: Ic93d70cef771527c212cdf02b40e41a0f9e0b350
2019-11-19 16:55:49 +01:00
Johan Walles
9a2ab6df98 Add test for reading long lines
Change-Id: Ib24518c681f1ffc93192a985cd573fa37006d1f8
2019-11-19 16:53:17 +01:00
Johan Walles
d5a0b7df63 Use a bufio.Reader to read the input stream
Because the scanner cannot handle too long lines.

Change-Id: I45f1777537795772ae741816ba095a4939ce4f67
2019-11-19 16:27:14 +01:00
Johan Walles
b25cfc692e Make start of line identifiable
Change-Id: I1fa4b4fa5b25ec58b418a53dbb4d38b6f473d172
2019-11-19 16:21:58 +01:00
Johan Walles
8dd45b7b1c Clarify where an error printout is coming from
Change-Id: Ic263afa23e647fcf8a62c45bf80969d6c85f9436
2019-11-19 15:46:04 +01:00
Johan Walles
0ccbd6a2b3 Deal with broken commit messages
Our git commit messages have been screwed up by VSCode 1.40.1, probably
in conjunction with using Git in Swedish.
diff --git release.sh release.sh
index 1cc1f6c..1b6805c 100755
--- release.sh
+++ release.sh
@@ -30,7 +30,7 @@ echo

 # FIXME: Make this part of the editable tagging message
 echo "Changes since last release:"
-git log --first-parent --pretty="format:* %s" "$LAST_VERSION"..HEAD | cat
+git log --first-parent --pretty="format:* %s" "$LAST_VERSION"..HEAD | sed 's/ diff.*//'
 echo
 echo

Change-Id: Iedaecf17a69c8cfe22f29714907e599ff2b86689
2019-11-19 15:36:21 +01:00
Johan Walles
aaa25b74f3 Add sample file with a long line
This file breaks the test suite.

Change-Id: I510e1ddf98dadb02d1848702e9e83aaacf0f6e78
2019-11-19 15:33:50 +01:00
Johan Walles
d96bb923a1 Print bug reporting info on log messages
diff --git moar.go moar.go
index 46b2898..906b310 100644
--- moar.go
+++ moar.go
@@ -58,6 +58,23 @@ func _PrintUsage(output io.Writer) {
 	}
 }

+// PrintProblemsHeader prints bug reporting information to stderr
+func PrintProblemsHeader() {
+	fmt.Fprintln(os.Stderr, "Please post the following report at <https://github.com/walles/moar/issues>,")
+	fmt.Fprintln(os.Stderr, "or e-mail it to johan.walles@gmail.com.")
+	fmt.Fprintln(os.Stderr)
+	fmt.Fprintln(os.Stderr, "Version:", versionString)
+	fmt.Fprintln(os.Stderr, "LANG   :", os.Getenv("LANG"))
+	fmt.Fprintln(os.Stderr, "TERM   :", os.Getenv("TERM"))
+	fmt.Fprintln(os.Stderr)
+	fmt.Fprintln(os.Stderr, "GOOS    :", runtime.GOOS)
+	fmt.Fprintln(os.Stderr, "GOARCH  :", runtime.GOARCH)
+	fmt.Fprintln(os.Stderr, "Compiler:", runtime.Compiler)
+	fmt.Fprintln(os.Stderr, "NumCPU  :", runtime.NumCPU())
+
+	fmt.Fprintln(os.Stderr)
+}
+
 func main() {
 	// FIXME: If we get a CTRL-C, get terminal back into a useful state before terminating

@@ -67,21 +84,7 @@ func main() {
 			return
 		}

-		// On any panic or warnings, also print system info and how to report bugs
-		fmt.Fprintln(os.Stderr, "Please post the following crash report at <https://github.com/walles/moar/issues>,")
-		fmt.Fprintln(os.Stderr, "or e-mail it to johan.walles@gmail.com.")
-		fmt.Fprintln(os.Stderr)
-		fmt.Fprintln(os.Stderr, "Version:", versionString)
-		fmt.Fprintln(os.Stderr, "LANG   :", os.Getenv("LANG"))
-		fmt.Fprintln(os.Stderr, "TERM   :", os.Getenv("TERM"))
-		fmt.Fprintln(os.Stderr)
-		fmt.Fprintln(os.Stderr, "GOOS    :", runtime.GOOS)
-		fmt.Fprintln(os.Stderr, "GOARCH  :", runtime.GOARCH)
-		fmt.Fprintln(os.Stderr, "Compiler:", runtime.Compiler)
-		fmt.Fprintln(os.Stderr, "NumCPU  :", runtime.NumCPU())
-
-		fmt.Fprintln(os.Stderr)
-
+		PrintProblemsHeader()
 		panic(err)
 	}()

@@ -161,6 +164,8 @@ func _StartPaging(reader *m.Reader) {
 		}

 		if len(loglines.String()) > 0 {
+			PrintProblemsHeader()
+
 			// FIXME: Don't print duplicate log messages more than once,
 			// maybe invent our own logger for this?
 			fmt.Fprintf(os.Stderr, "%s", loglines.String())

Change-Id: If41c17e98daf9f05909ab7e3c31dc84e946cbbf5
2019-11-19 15:33:00 +01:00
Johan Walles
2df60227cf Tell user about Reader errors
diff --git m/pager.go m/pager.go
index 51a007a..070e39d 100644
--- m/pager.go
+++ m/pager.go
@@ -763,5 +763,7 @@ func (p *Pager) StartPaging(logger *log.Logger, screen tcell.Screen) {
 		p._Redraw(logger, spinner)
 	}

-	// FIXME: Log p.reader.err if it's non-nil
+	if p.reader.err != nil {
+		logger.Printf("Reader reported an error: %s", p.reader.err.Error())
+	}
 }

Change-Id: Ia848d1daced793c39ebd4518fa144627a2598ecd
2019-11-19 15:18:40 +01:00
Johan Walles
08d3fbfaa8 Add some timeouts
diff --git m/reader.go m/reader.go
index 339de9c..2427094 100644
--- m/reader.go
+++ m/reader.go
@@ -12,6 +12,7 @@ import (
 	"regexp"
 	"strings"
 	"sync"
+	"time"
 )

 // Reader reads a file into an array of strings.
@@ -54,9 +55,18 @@ func _ReadStream(stream io.Reader, reader *Reader, fromFilter *exec.Cmd) {
 			return
 		}

-		// FIXME: Can Wait()ing here stall? Should we release the lock while Wait()ing?
+		// Give the filter a little time to go away
+		timer := time.AfterFunc(2*time.Second, func() {
+			fromFilter.Process.Kill()
+		})
+
 		err := fromFilter.Wait()
+		timer.Stop()
+
 		if reader.err == nil {
+			// NOTE: This could mean that our Wait()ing on the filter above
+			// timed out.
+			//
 			// FIXME: Add filter stderr contents to the error reported here
 			reader.err = err
 		}
diff --git test.sh test.sh
index 677c5db..6d0b6b9 100755
--- test.sh
+++ test.sh
@@ -3,7 +3,7 @@
 set -e -o pipefail

 # Unit tests first
-go test github.com/walles/moar/m
+go test -timeout 20s github.com/walles/moar/m

 # Ensure we can cross compile
 # NOTE: Make sure this list matches the one in release.sh

Change-Id: I3847aaa0942588c2d4129c7b2967d1d10aa95035
2019-11-19 15:08:22 +01:00
Johan Walles
b781d09a72 Add another test case
diff --git m/reader_test.go m/reader_test.go
index 176192b..bed1e33 100644
--- m/reader_test.go
+++ m/reader_test.go
@@ -30,6 +30,12 @@ func _TestGetLineCount(t *testing.T, reader *Reader) {
 	if err != nil {
 		t.Error("Error counting lines of", *reader.name, err)
 	}
+
+	if strings.HasSuffix(*reader.name, "/line-without-newline.txt") {
+		// "wc -l" thinks this file contains zero lines
+		fileLineCount = 1
+	}
+
 	if reader.GetLineCount() != fileLineCount {
 		t.Errorf("Got %d lines but expected %d: <%s>",
 			reader.GetLineCount(), fileLineCount, *reader.name)
diff --git sample-files/line-without-newline.txt sample-files/line-without-newline.txt
new file mode 100644
index 0000000..2260c57
--- /dev/null
+++ sample-files/line-without-newline.txt
@@ -0,0 +1 @@
+This file contains no newlines
\ No newline at end of file

Change-Id: Ic2801ce3477a7afd4537d340385c884c5f2b7438
2019-11-19 14:47:44 +01:00
Johan Walles
8d9155061a Merge branch 'walles/linenumbers'
Fixes #17

Change-Id: Iad01483b26128f2b782c19ee6092b73cfea7d962
2019-11-19 12:00:12 +01:00
Johan Walles
db048012fa Add line numbers to screenshot
diff --git screenshot.png screenshot.png
index 1a30f30..4ce4774 100644
Binary files screenshot.png and screenshot.png differ

Change-Id: I3bfeba25afcec9f7ce105d180989c78b56c3cfa6
2019-11-19 11:58:52 +01:00
Johan Walles
d3233845a6 Fix test failures
diff --git m/pager_test.go m/pager_test.go
index 5911cbc..ba18470 100644
--- m/pager_test.go
+++ m/pager_test.go
@@ -99,6 +99,7 @@ func TestBrokenUtf8(t *testing.T) {
 func _StartPaging(t *testing.T, reader *Reader) []tcell.SimCell {
 	screen := tcell.NewSimulationScreen("UTF-8")
 	pager := NewPager(reader)
+	pager.showLineNumbers = false
 	pager.Quit()

 	var loglines strings.Builder
@@ -267,12 +268,12 @@ func assertTokenRangesEqual(t *testing.T, actual []Token, expected []Token) {
 }

 func TestCreateScreenLineBase(t *testing.T) {
-	line := _CreateScreenLine(nil, 0, 0, 3, "", nil)
+	line := _CreateScreenLine(nil, 0, 3, "", nil)
 	assert.Assert(t, len(line) == 0)
 }

 func TestCreateScreenLineOverflowRight(t *testing.T) {
-	line := _CreateScreenLine(nil, 0, 0, 3, "012345", nil)
+	line := _CreateScreenLine(nil, 0, 3, "012345", nil)
 	assertTokenRangesEqual(t, line, []Token{
 		_CreateExpectedCell('0', tcell.StyleDefault),
 		_CreateExpectedCell('1', tcell.StyleDefault),
@@ -281,7 +282,7 @@ func TestCreateScreenLineOverflowRight(t *testing.T) {
 }

 func TestCreateScreenLineUnderflowLeft(t *testing.T) {
-	line := _CreateScreenLine(nil, 0, 1, 3, "012", nil)
+	line := _CreateScreenLine(nil, 1, 3, "012", nil)
 	assertTokenRangesEqual(t, line, []Token{
 		_CreateExpectedCell('<', tcell.StyleDefault.Reverse(true)),
 		_CreateExpectedCell('1', tcell.StyleDefault),
@@ -295,7 +296,7 @@ func TestCreateScreenLineSearchHit(t *testing.T) {
 		panic(err)
 	}

-	line := _CreateScreenLine(nil, 0, 0, 3, "abc", pattern)
+	line := _CreateScreenLine(nil, 0, 3, "abc", pattern)
 	assertTokenRangesEqual(t, line, []Token{
 		_CreateExpectedCell('a', tcell.StyleDefault),
 		_CreateExpectedCell('b', tcell.StyleDefault.Reverse(true)),
@@ -309,7 +310,7 @@ func TestCreateScreenLineUtf8SearchHit(t *testing.T) {
 		panic(err)
 	}

-	line := _CreateScreenLine(nil, 0, 0, 3, "åäö", pattern)
+	line := _CreateScreenLine(nil, 0, 3, "åäö", pattern)
 	assertTokenRangesEqual(t, line, []Token{
 		_CreateExpectedCell('å', tcell.StyleDefault),
 		_CreateExpectedCell('ä', tcell.StyleDefault.Reverse(true)),
@@ -320,7 +321,7 @@ func TestCreateScreenLineUtf8SearchHit(t *testing.T) {
 func TestCreateScreenLineScrolledUtf8SearchHit(t *testing.T) {
 	pattern := regexp.MustCompile("ä")

-	line := _CreateScreenLine(nil, 0, 1, 4, "ååäö", pattern)
+	line := _CreateScreenLine(nil, 1, 4, "ååäö", pattern)

 	assertTokenRangesEqual(t, line, []Token{
 		_CreateExpectedCell('<', tcell.StyleDefault.Reverse(true)),
@@ -333,7 +334,7 @@ func TestCreateScreenLineScrolledUtf8SearchHit(t *testing.T) {
 func TestCreateScreenLineScrolled2Utf8SearchHit(t *testing.T) {
 	pattern := regexp.MustCompile("ä")

-	line := _CreateScreenLine(nil, 0, 2, 4, "åååäö", pattern)
+	line := _CreateScreenLine(nil, 2, 4, "åååäö", pattern)

 	assertTokenRangesEqual(t, line, []Token{
 		_CreateExpectedCell('<', tcell.StyleDefault.Reverse(true)),

Change-Id: Ib85633c6d191a54ab8d34dcc29850bfb127eb0d3
2019-11-19 11:49:37 +01:00
Johan Walles
2e931b400c Scroll left / right to show / hide line numbers
diff --git m/pager.go m/pager.go
index 0e22e83..51a007a 100644
--- m/pager.go
+++ m/pager.go
@@ -504,6 +504,16 @@ func (p *Pager) _OnSearchKey(logger *log.Logger, key tcell.Key) {
 }

 func (p *Pager) _MoveRight(delta int) {
+	if p.showLineNumbers && delta > 0 {
+		p.showLineNumbers = false
+		return
+	}
+
+	if p.leftColumnZeroBased == 0 && delta < 0 {
+		p.showLineNumbers = true
+		return
+	}
+
 	result := p.leftColumnZeroBased + delta
 	if result < 0 {
 		p.leftColumnZeroBased = 0

Change-Id: I69040ac8da06e50b866fdb6b678a0ae54fe0a84f
2019-11-19 11:41:56 +01:00
Johan Walles
7de5025257 Extract sideways scrolling into its own method
diff --git m/pager.go m/pager.go
index ec81976..0e22e83 100644
--- m/pager.go
+++ m/pager.go
@@ -41,7 +41,7 @@ type Pager struct {
 	isShowingHelp bool
 	preHelpState  *_PreHelpState

-	lineNumbersWanted bool
+	showLineNumbers bool
 }

 type _PreHelpState struct {
@@ -101,7 +101,7 @@ func NewPager(r *Reader) *Pager {
 		reader:            r,
 		quit:              false,
 		firstLineOneBased: 1,
-		lineNumbersWanted: true,
+		showLineNumbers:   true,
 	}
 }

@@ -211,7 +211,7 @@ func (p *Pager) _AddLines(logger *log.Logger, spinner string) {
 	lastLineOneBased := lines.firstLineOneBased + len(lines.lines) - 1
 	maxPrefixLength := len(strconv.Itoa(lastLineOneBased)) + 1

-	if !p.lineNumbersWanted {
+	if !p.showLineNumbers {
 		maxPrefixLength = 0
 	}

@@ -503,6 +503,15 @@ func (p *Pager) _OnSearchKey(logger *log.Logger, key tcell.Key) {
 	}
 }

+func (p *Pager) _MoveRight(delta int) {
+	result := p.leftColumnZeroBased + delta
+	if result < 0 {
+		p.leftColumnZeroBased = 0
+	} else {
+		p.leftColumnZeroBased = result
+	}
+}
+
 func (p *Pager) _OnKey(logger *log.Logger, key tcell.Key) {
 	if p.mode == _Searching {
 		p._OnSearchKey(logger, key)
@@ -528,13 +537,10 @@ func (p *Pager) _OnKey(logger *log.Logger, key tcell.Key) {
 		p.firstLineOneBased++

 	case tcell.KeyRight:
-		p.leftColumnZeroBased += 16
+		p._MoveRight(16)

 	case tcell.KeyLeft:
-		p.leftColumnZeroBased -= 16
-		if p.leftColumnZeroBased < 0 {
-			p.leftColumnZeroBased = 0
-		}
+		p._MoveRight(-16)

 	case tcell.KeyHome:
 		p.firstLineOneBased = 1
@@ -718,13 +724,10 @@ func (p *Pager) StartPaging(logger *log.Logger, screen tcell.Screen) {
 				p.firstLineOneBased++

 			case tcell.WheelRight:
-				p.leftColumnZeroBased += 16
+				p._MoveRight(16)

 			case tcell.WheelLeft:
-				p.leftColumnZeroBased -= 16
-				if p.leftColumnZeroBased < 0 {
-					p.leftColumnZeroBased = 0
-				}
+				p._MoveRight(-16)
 			}

 		case *tcell.EventResize:

Change-Id: I5925876d42ec3cd7b8486bb96eb47b81c6855032
2019-11-19 11:38:41 +01:00
Johan Walles
47b34c3351 Make line number configurable through code
diff --git m/pager.go m/pager.go
index 2133057..ec81976 100644
--- m/pager.go
+++ m/pager.go
@@ -40,6 +40,8 @@ type Pager struct {

 	isShowingHelp bool
 	preHelpState  *_PreHelpState
+
+	lineNumbersWanted bool
 }

 type _PreHelpState struct {
@@ -60,6 +62,7 @@ Quitting
 Moving around
 -------------
 * Arrow keys
+* Left / right can be used to hide / show line numbers
 * PageUp / 'b' and PageDown / 'f'
 * Half page 'u'p / 'd'own
 * Home and End for start / end of the document
@@ -98,6 +101,7 @@ func NewPager(r *Reader) *Pager {
 		reader:            r,
 		quit:              false,
 		firstLineOneBased: 1,
+		lineNumbersWanted: true,
 	}
 }

@@ -106,7 +110,7 @@ func (p *Pager) _AddLine(logger *log.Logger, fileLineNumber *int, maxPrefixLengt

 	prefixLength := 0
 	lineNumberString := ""
-	if fileLineNumber != nil {
+	if maxPrefixLength > 0 && fileLineNumber != nil {
 		prefixLength = maxPrefixLength
 		lineNumberString = fmt.Sprintf("%*d ", prefixLength-1, *fileLineNumber)
 	}
@@ -207,6 +211,10 @@ func (p *Pager) _AddLines(logger *log.Logger, spinner string) {
 	lastLineOneBased := lines.firstLineOneBased + len(lines.lines) - 1
 	maxPrefixLength := len(strconv.Itoa(lastLineOneBased)) + 1

+	if !p.lineNumbersWanted {
+		maxPrefixLength = 0
+	}
+
 	screenLineNumber := 0
 	for i, line := range lines.lines {
 		lineNumber := p.firstLineOneBased + i

Change-Id: I79cd0d46e8590cfdcd9e0ee942eeb0098676d25d
2019-11-19 11:28:28 +01:00
Johan Walles
a14f756d99 Adaptive width of the line numbers column
diff --git m/pager.go m/pager.go
index 0c7c3a2..2133057 100644
--- m/pager.go
+++ m/pager.go
@@ -5,6 +5,7 @@ import (
 	"log"
 	"os"
 	"regexp"
+	"strconv"
 	"time"
 	"unicode"
 	"unicode/utf8"
@@ -100,13 +101,13 @@ func NewPager(r *Reader) *Pager {
 	}
 }

-func (p *Pager) _AddLine(logger *log.Logger, fileLineNumber *int, screenLineNumber int, line string) {
+func (p *Pager) _AddLine(logger *log.Logger, fileLineNumber *int, maxPrefixLength int, screenLineNumber int, line string) {
 	screenWidth, _ := p.screen.Size()

 	prefixLength := 0
 	lineNumberString := ""
 	if fileLineNumber != nil {
-		prefixLength = 3
+		prefixLength = maxPrefixLength
 		lineNumberString = fmt.Sprintf("%*d ", prefixLength-1, *fileLineNumber)
 	}

@@ -200,10 +201,16 @@ func (p *Pager) _AddLines(logger *log.Logger, spinner string) {
 	// display starts scrolling visibly.
 	p.firstLineOneBased = lines.firstLineOneBased

+	// Count the length of the last line number
+	//
+	// Offsets figured out through trial-and-error...
+	lastLineOneBased := lines.firstLineOneBased + len(lines.lines) - 1
+	maxPrefixLength := len(strconv.Itoa(lastLineOneBased)) + 1
+
 	screenLineNumber := 0
 	for i, line := range lines.lines {
 		lineNumber := p.firstLineOneBased + i
-		p._AddLine(logger, &lineNumber, screenLineNumber, line)
+		p._AddLine(logger, &lineNumber, maxPrefixLength, screenLineNumber, line)
 		screenLineNumber++
 	}

@@ -212,7 +219,7 @@ func (p *Pager) _AddLines(logger *log.Logger, spinner string) {
 		// This happens when we're done
 		eofSpinner = "---"
 	}
-	p._AddLine(logger, nil, screenLineNumber, _EofMarkerFormat+eofSpinner)
+	p._AddLine(logger, nil, 0, screenLineNumber, _EofMarkerFormat+eofSpinner)

 	switch p.mode {
 	case _Searching:

Change-Id: I7ab67a61048557fd11cd9a044dbae5c13264f492
2019-11-19 11:24:01 +01:00
Johan Walles
fd286d4004 Mandatory line numbers, badly formatted
diff --git m/pager.go m/pager.go
index 2c2736b..0c7c3a2 100644
--- m/pager.go
+++ m/pager.go
@@ -22,6 +22,9 @@ const (
 	_NotFound  _PagerMode = 2
 )

+// Styling of line numbers
+var _NumberStyle = tcell.StyleDefault.Dim(true)
+
 // Pager is the main on-screen pager
 type Pager struct {
 	reader              *Reader
@@ -97,17 +100,32 @@ func NewPager(r *Reader) *Pager {
 	}
 }

-func (p *Pager) _AddLine(logger *log.Logger, lineNumber int, line string) {
-	width, _ := p.screen.Size()
-	tokens := _CreateScreenLine(logger, lineNumber, p.leftColumnZeroBased, width, line, p.searchPattern)
+func (p *Pager) _AddLine(logger *log.Logger, fileLineNumber *int, screenLineNumber int, line string) {
+	screenWidth, _ := p.screen.Size()
+
+	prefixLength := 0
+	lineNumberString := ""
+	if fileLineNumber != nil {
+		prefixLength = 3
+		lineNumberString = fmt.Sprintf("%*d ", prefixLength-1, *fileLineNumber)
+	}
+
+	for column, digit := range lineNumberString {
+		if column >= prefixLength {
+			break
+		}
+
+		p.screen.SetContent(column, screenLineNumber, digit, nil, _NumberStyle)
+	}
+
+	tokens := _CreateScreenLine(logger, p.leftColumnZeroBased, screenWidth-prefixLength, line, p.searchPattern)
 	for column, token := range tokens {
-		p.screen.SetContent(column, lineNumber, token.Rune, nil, token.Style)
+		p.screen.SetContent(column+prefixLength, screenLineNumber, token.Rune, nil, token.Style)
 	}
 }

 func _CreateScreenLine(
 	logger *log.Logger,
-	lineNumber int,
 	stringIndexAtColumnZero int,
 	screenColumnsCount int,
 	line string,
@@ -183,8 +201,9 @@ func (p *Pager) _AddLines(logger *log.Logger, spinner string) {
 	p.firstLineOneBased = lines.firstLineOneBased

 	screenLineNumber := 0
-	for _, line := range lines.lines {
-		p._AddLine(logger, screenLineNumber, line)
+	for i, line := range lines.lines {
+		lineNumber := p.firstLineOneBased + i
+		p._AddLine(logger, &lineNumber, screenLineNumber, line)
 		screenLineNumber++
 	}

@@ -193,7 +212,7 @@ func (p *Pager) _AddLines(logger *log.Logger, spinner string) {
 		// This happens when we're done
 		eofSpinner = "---"
 	}
-	p._AddLine(logger, screenLineNumber, _EofMarkerFormat+eofSpinner)
+	p._AddLine(logger, nil, screenLineNumber, _EofMarkerFormat+eofSpinner)

 	switch p.mode {
 	case _Searching:

Change-Id: I2cafedb3e8a87c88564982f42819b16e911c6a1b
2019-11-19 11:12:23 +01:00
Johan Walles
8d37e9cfe8 Sideways mouse wheel scrolling
diff --git m/pager.go m/pager.go
index 16e91e7..2c2736b 100644
--- m/pager.go
+++ m/pager.go
@@ -682,6 +682,15 @@ func (p *Pager) StartPaging(logger *log.Logger, screen tcell.Screen) {
 			case tcell.WheelDown:
 				// Clipping is done in _AddLines()
 				p.firstLineOneBased++
+
+			case tcell.WheelRight:
+				p.leftColumnZeroBased += 16
+
+			case tcell.WheelLeft:
+				p.leftColumnZeroBased -= 16
+				if p.leftColumnZeroBased < 0 {
+					p.leftColumnZeroBased = 0
+				}
 			}

 		case *tcell.EventResize:

Change-Id: Ibe36c3d88392dda1f4d6e7be182cf5ea5d168703
2019-11-14 07:46:54 +01:00
Johan Walles
7fcf99b006 Handle mouse events
Fixes #16
diff --git m/pager.go m/pager.go
index b7cce09..16e91e7 100644
--- m/pager.go
+++ m/pager.go
@@ -611,6 +611,7 @@ func (p *Pager) StartPaging(logger *log.Logger, screen tcell.Screen) {
 	}

 	p.screen = screen
+	screen.EnableMouse()
 	screen.Show()
 	p._Redraw(logger, "")

@@ -672,6 +673,17 @@ func (p *Pager) StartPaging(logger *log.Logger, screen tcell.Screen) {
 				p._OnKey(logger, ev.Key())
 			}

+		case *tcell.EventMouse:
+			switch ev.Buttons() {
+			case tcell.WheelUp:
+				// Clipping is done in _AddLines()
+				p.firstLineOneBased--
+
+			case tcell.WheelDown:
+				// Clipping is done in _AddLines()
+				p.firstLineOneBased++
+			}
+
 		case *tcell.EventResize:
 			// We'll be implicitly redrawn just by taking another lap in the loop

Change-Id: I3c9971077de9a720b90d6d91960f7f33a3a089e3
2019-11-14 07:45:15 +01:00
Johan Walles
dd00a9fc5c Release script tuning
diff --git release.sh release.sh
index 27f20bc..1cc1f6c 100755
--- release.sh
+++ release.sh
@@ -31,6 +31,8 @@ echo
 # FIXME: Make this part of the editable tagging message
 echo "Changes since last release:"
 git log --first-parent --pretty="format:* %s" "$LAST_VERSION"..HEAD | cat
+echo
+echo

 # Make an annotated tag for this release
 git tag --annotate "$VERSION"

Change-Id: I37a2f3630d50aaa5bbacda02345f008510ec802a
2019-11-13 16:26:08 +01:00
Johan Walles
b0cf8bc4c8 Fix a crash on 32 bit systems
Fixes #18
diff --git m/pager.go m/pager.go
index 178c828..b7cce09 100644
--- m/pager.go
+++ m/pager.go
@@ -3,7 +3,6 @@ package m
 import (
 	"fmt"
 	"log"
-	"math"
 	"os"
 	"regexp"
 	"time"
@@ -507,7 +506,7 @@ func (p *Pager) _OnKey(logger *log.Logger, key tcell.Key) {
 		p.firstLineOneBased = 1

 	case tcell.KeyEnd:
-		p.firstLineOneBased = math.MaxInt32
+		p.firstLineOneBased = p.reader.GetLineCount()

 	case tcell.KeyPgDn:
 		_, height := p.screen.Size()
@@ -565,7 +564,7 @@ func (p *Pager) _OnRune(logger *log.Logger, char rune) {
 		p.firstLineOneBased = 1

 	case '>', 'G':
-		p.firstLineOneBased = math.MaxInt32
+		p.firstLineOneBased = p.reader.GetLineCount()

 	case 'f', ' ':
 		_, height := p.screen.Size()

Change-Id: I17712d93322703ae3fa5b54a5a07169ddd1357c4
2019-11-13 16:17:26 +01:00
Johan Walles
8a8f583157 Release script tuning
diff --git release.sh release.sh
index 8082ca7..27f20bc 100755
--- release.sh
+++ release.sh
@@ -30,7 +30,7 @@ echo

 # FIXME: Make this part of the editable tagging message
 echo "Changes since last release:"
-git log --first-parent --pretty="format:* %s" "$LAST_VERSION"..HEAD
+git log --first-parent --pretty="format:* %s" "$LAST_VERSION"..HEAD | cat

 # Make an annotated tag for this release
 git tag --annotate "$VERSION"

Change-Id: I45923ffe0d35067ac2885cdbf3de50f33c5404c7
2019-11-07 09:23:53 +01:00
Johan Walles
eefbbd2a0e Merge branch 'walles/test-line-creation'
This fixes highlighting in the presence of unicode chars.
2019-11-06 21:44:07 +01:00
Johan Walles
9fcc235430 README: Unicode search hits done 2019-11-06 21:42:20 +01:00
Johan Walles
ad4c545df0 Add another match ranges test 2019-11-06 21:40:14 +01:00
Johan Walles
ea3dcf3ca5 Fix a crash 2019-11-06 21:38:39 +01:00
Johan Walles
fb3b6abbe7 Pass the tests
But crash the app.

Do:
* ./moar.sh sample-files/long-and-wide.txt
* Search (/) for "monkey"
2019-11-06 20:30:59 +01:00
Johan Walles
494032278b Fix some failing tests 2019-11-06 18:50:34 +01:00
Johan Walles
df1702ac21 Test that match ranges are by rune not by byte 2019-11-06 06:50:53 +01:00
Johan Walles
109f40e7ed Prettify 2019-11-05 21:30:04 +01:00
Johan Walles
81fe99f366 WIP: Test search highlights 2019-11-05 21:20:06 +01:00
Johan Walles
ab0e62123b WIP: Line rendering tests
Implement search hits tests as well.
2019-11-05 21:09:45 +01:00
Johan Walles
8e08e729c4 Fix environment depending test failure 2019-11-05 08:32:06 +01:00
Johan Walles
742401ec82 Fix crash removing unicode char from search string
Fixes #12
2019-11-02 12:19:04 +01:00
Johan Walles
f1f11f6805 release.sh usability fix 2019-10-30 22:08:37 +01:00
Johan Walles
6b42190343 Merge branch 'walles/less-termcap'
Fixes #14
2019-10-30 21:00:50 +01:00
Johan Walles
70eb01e5ed Update docs 2019-10-30 21:00:11 +01:00
Johan Walles
6334be7dcc Adapt to LESS_TERMCAP_md and LESS_TERMCAP_us
Fixes #14
2019-10-30 20:29:29 +01:00
Johan Walles
a7cba8bb16 Move man page formats into variables 2019-10-30 20:13:28 +01:00
Johan Walles
a4ec70fea3 Add man page formatting tests 2019-10-30 18:47:49 +01:00
Johan Walles
ad0f174651 Make loading spinner more obvious 2019-10-29 22:05:42 +01:00
Johan Walles
1ed285d13b Merge branch 'walles/moar-colors'
Adds eight and twenty four bits color support.
2019-10-29 06:09:25 +01:00
Johan Walles
7405293e25 Add sample file for color handling
From #14
2019-10-28 21:54:57 +01:00
Johan Walles
04cd520d0e Fix the last color handling tests 2019-10-28 21:46:18 +01:00
Johan Walles
1dda4b1a87 Handle 24 bit color 2019-10-28 20:30:04 +01:00
Johan Walles
94774e121a Report final error message 2019-10-28 20:21:39 +01:00
Johan Walles
8b9e85958c Handle 8 bit colors 2019-10-28 20:18:07 +01:00