diff --git a/m/pager.go b/m/pager.go index 78f45ca4..0d73b1b8 100644 --- a/m/pager.go +++ b/m/pager.go @@ -12,8 +12,6 @@ import ( "github.com/walles/moar/twin" ) -// FIXME: Profile the pager while searching through a large file - type _PagerMode int const ( diff --git a/moar.go b/moar.go index 88cd012a..215403a4 100644 --- a/moar.go +++ b/moar.go @@ -134,6 +134,7 @@ func main() { printUsage(os.Stdout, flagSet, false) } printVersion := flagSet.Bool("version", false, "Prints the moar version number") + compat := flagSet.Bool("compat", false, "Compatibility mode, no mouse support and no alternate screen") debug := flagSet.Bool("debug", false, "Print debug logs after exiting") trace := flagSet.Bool("trace", false, "Print trace logs after exiting") styleOption := flagSet.String("style", "native", @@ -235,7 +236,7 @@ func main() { if stdinIsRedirected { // Display input pipe contents reader := m.NewReaderFromStream("", os.Stdin) - startPaging(reader) + startPaging(reader, *compat) return } @@ -245,13 +246,19 @@ func main() { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) os.Exit(1) } - startPaging(reader) + startPaging(reader, *compat) } -func startPaging(reader *m.Reader) { - screen, e := twin.NewScreen() - if e != nil { - panic(e) +func startPaging(reader *m.Reader, compat bool) { + var screen twin.Screen + var err error + if compat { + screen, err = twin.NewScreenCompat() + } else { + screen, err = twin.NewScreen() + } + if err != nil { + panic(err) } var loglines strings.Builder diff --git a/twin/screen.go b/twin/screen.go index 37d065c4..830d6875 100644 --- a/twin/screen.go +++ b/twin/screen.go @@ -59,6 +59,9 @@ type UnixScreen struct { ttyOut *os.File oldTtyOutMode uint32 //lint:ignore U1000 Windows only + + // See docs for NewScreenCompat() + compat bool } // Cell is a rune with a style to be written to a cell on screen @@ -89,11 +92,27 @@ var MOUSE_EVENT_REGEX = regexp.MustCompile("^\x1b\\[<([0-9]+);([0-9]+);([0-9]+)M // NewScreen() requires Close() to be called after you are done with your new // screen, most likely somewhere in your shutdown code. func NewScreen() (Screen, error) { + return newScreenInternal(false) +} + +// A compat screen works like less traditionally has, not using an alternate +// screen and not having any mouse support. +// +// Upside is that marking with your mouse and copying works without holding any +// modifiers, more info at https://github.com/walles/moar/issues/53. +// +// Kindly Close() the returned screen when done with it. +func NewScreenCompat() (Screen, error) { + return newScreenInternal(true) +} + +func newScreenInternal(compat bool) (Screen, error) { if !term.IsTerminal(int(os.Stdout.Fd())) { return nil, fmt.Errorf("stdout (fd=%d) must be a terminal for paging to work", os.Stdout.Fd()) } screen := UnixScreen{} + screen.compat = compat // The number "80" here is from manual testing on my MacBook: // @@ -111,8 +130,10 @@ func NewScreen() (Screen, error) { if err != nil { return nil, err } - screen.setAlternateScreenMode(true) - screen.enableMouseTracking(true) + if !screen.compat { + screen.setAlternateScreenMode(true) + screen.enableMouseTracking(true) + } screen.hideCursor(true) go screen.mainLoop() @@ -124,8 +145,10 @@ func NewScreen() (Screen, error) { // with the screen returned by NewScreen() func (screen *UnixScreen) Close() { screen.hideCursor(false) - screen.enableMouseTracking(false) - screen.setAlternateScreenMode(false) + if !screen.compat { + screen.enableMouseTracking(false) + screen.setAlternateScreenMode(false) + } err := screen.restoreTtyInTtyOut() if err != nil {