Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions cmd/moor/moor.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,7 @@ func parseStyleOption(styleOption string) (*chroma.Style, error) {

func parseColorsOption(colorsOption string) (twin.ColorCount, error) {
if strings.ToLower(colorsOption) == "auto" {
colorsOption = "16M"
if os.Getenv("COLORTERM") != "truecolor" && strings.Contains(os.Getenv("TERM"), "256") {
// Covers "xterm-256color" as used by the macOS Terminal
colorsOption = "256"
}
return twin.DefaultColorCount(), nil
}

switch strings.ToUpper(colorsOption) {
Expand Down Expand Up @@ -397,7 +393,7 @@ func getVersion() string {
// Can return a nil pager on --help or --version, or if pumping to stdout.
func pagerFromArgs(
args []string,
newScreen func(mouseMode twin.MouseMode, terminalColorCount twin.ColorCount) (twin.Screen, error),
newScreen func(options twin.ScreenOptions) (twin.Screen, error),
stdinIsRedirected bool,
stdoutIsRedirected bool,
) (
Expand Down Expand Up @@ -438,6 +434,8 @@ func pagerFromArgs(
flagSet.Bool("no-reformat", true, "No effect, kept for compatibility. See --reformat")
quitIfOneScreen := flagSet.Bool("quit-if-one-screen", false, "Don't page if contents fits on one screen. Affected by --no-clear-on-exit-margin.")
noClearOnExit := flagSet.Bool("no-clear-on-exit", false, "Retain screen contents when exiting moor")
noAlternateScreen := flagSet.Bool("no-alternate-screen", false, "Don't use the alternate screen buffer (like less -X)")
flagSet.BoolVar(noAlternateScreen, "X", false, "Don't use the alternate screen buffer (like less -X)")
noClearOnExitMargin := flagSet.Int("no-clear-on-exit-margin", 1,
"Number of lines to leave for your shell prompt, defaults to 1")
statusBarStyle := flagSetFunc(flagSet, "statusbar", internal.STATUSBAR_STYLE_INVERSE,
Expand Down Expand Up @@ -619,7 +617,11 @@ func pagerFromArgs(

// We got the first byte, this means sudo is done (if it was used) and we
// can set up the UI.
screen, err := newScreen(*mouseMode, *terminalColorsCount)
screen, err := newScreen(twin.ScreenOptions{
MouseMode: *mouseMode,
ColorCount: *terminalColorsCount,
UseAlternateScreen: !*noAlternateScreen,
})
if err != nil {
// Ref: https://github.com/walles/moor/issues/149
log.Info("Failed to set up screen for paging, pumping to stdout instead: ", err)
Expand Down Expand Up @@ -710,7 +712,7 @@ func main() {

pager, screen, style, formatter, _logsRequested, err := pagerFromArgs(
os.Args,
twin.NewScreenWithMouseModeAndColorCount,
twin.NewScreenWithOptions,
stdinIsRedirected,
stdoutIsRedirected,
)
Expand Down
2 changes: 1 addition & 1 deletion cmd/moor/moor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestUnescapeManPn(t *testing.T) {
func TestPageOneInputFile(t *testing.T) {
pager, screen, _, formatter, _, err := pagerFromArgs(
[]string{"", "moor_test.go"},
func(_ twin.MouseMode, _ twin.ColorCount) (twin.Screen, error) {
func(_ twin.ScreenOptions) (twin.Screen, error) {
return twin.NewFakeScreen(80, 24), nil
},
false, // stdin is redirected
Expand Down
4 changes: 4 additions & 0 deletions moor.1
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ Guarantee selecting text with the mouse works but maybe not mouse scrolling.
Or guarantee mouse scrolling works but selecting text requiring extra effort.
Details here: https://github.com/walles/moor/blob/master/MOUSE.md
.TP
\fB\-\-no\-alternate\-screen\fR, \fB\-X\fR
Don't use the alternate screen buffer. This is useful for seeing prompts
written to the main terminal screen by concurrent processes.
.TP
\fB\-\-no\-clear\-on\-exit\fR
Retain screen contents when exiting moor.
Affected by \fB--no-clear-on-exit-margin\fP.
Expand Down
10 changes: 9 additions & 1 deletion pkg/moor/embed-api.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ type Options struct {
// The default is to always start the pager. If this is set to true, short
// input will just be printed, and no paging will happen.
QuitIfOneScreen bool

// The default is to use the alternate screen buffer. Set this to true to
// disable the alternate screen buffer.
NoAlternateScreen bool
}

// PageFromStream reads the contents of the given reader and presents it in a pager.
Expand Down Expand Up @@ -161,7 +165,11 @@ func pageFromReader(reader *internalReader.ReaderImpl, options Options) error {
pager.ShowLineNumbers = !options.NoLineNumbers
pager.QuitIfOneScreen = options.QuitIfOneScreen

screen, e := twin.NewScreen()
screen, e := twin.NewScreenWithOptions(twin.ScreenOptions{
MouseMode: twin.MouseModeAuto,
ColorCount: twin.DefaultColorCount(),
UseAlternateScreen: !options.NoAlternateScreen,
})
if e != nil {
// Screen setup failed
return e
Expand Down
39 changes: 31 additions & 8 deletions twin/screen.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ type lastRendered struct {
cells [][]StyledRune
}

type ScreenOptions struct {
MouseMode MouseMode
ColorCount ColorCount
UseAlternateScreen bool
}

type UnixScreen struct {
widthAccessFromSizeOnly int // Access from Size() method only
heightAccessFromSizeOnly int // Access from Size() method only
Expand Down Expand Up @@ -116,6 +122,7 @@ type UnixScreen struct {

terminalColorCount ColorCount
mouseMode MouseMode
useAlternateScreen bool
}

// Example event: "\x1b[<65;127;41M"
Expand All @@ -135,22 +142,34 @@ func NewScreen() (Screen, error) {
}

func NewScreenWithMouseMode(mouseMode MouseMode) (Screen, error) {
terminalColorCount := ColorCount24bit
return NewScreenWithMouseModeAndColorCount(mouseMode, DefaultColorCount())
}

func DefaultColorCount() ColorCount {
if os.Getenv("COLORTERM") != "truecolor" && strings.Contains(os.Getenv("TERM"), "256") {
// Covers "xterm-256color" as used by the macOS Terminal
terminalColorCount = ColorCount256
return ColorCount256
}
return NewScreenWithMouseModeAndColorCount(mouseMode, terminalColorCount)
return ColorCount24bit
}

func NewScreenWithMouseModeAndColorCount(mouseMode MouseMode, terminalColorCount ColorCount) (Screen, error) {
return NewScreenWithOptions(ScreenOptions{
MouseMode: mouseMode,
ColorCount: terminalColorCount,
UseAlternateScreen: true,
})
}

func NewScreenWithOptions(options ScreenOptions) (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{
terminalColorCount: terminalColorCount,
mouseMode: mouseMode,
terminalColorCount: options.ColorCount,
mouseMode: options.MouseMode,
useAlternateScreen: options.UseAlternateScreen,
}

// The number "80" here is from manual testing on my MacBook:
Expand All @@ -177,7 +196,7 @@ func NewScreenWithMouseModeAndColorCount(mouseMode MouseMode, terminalColorCount

go func() {
defer func() {
panicHandler("NewScreenWithMouseModeAndColorCount()/mainLoop()", recover(), debug.Stack())
panicHandler("NewScreenWithOptions()/mainLoop()", recover(), debug.Stack())
}()

screen.mainLoop()
Expand Down Expand Up @@ -271,7 +290,9 @@ func (screen *UnixScreen) enterAlternateScreenSession() {
screen.renderLock.Lock()
defer screen.renderLock.Unlock()

screen.setAlternateScreenModeLocked(true)
if screen.useAlternateScreen {
screen.setAlternateScreenModeLocked(true)
}
screen.enableMouseTrackingLocked(screen.shouldEnableMouseTracking())
screen.hideCursorLocked(true)

Expand All @@ -288,7 +309,9 @@ func (screen *UnixScreen) leaveAlternateScreenSession() {
screen.writeLocked("\x1b[m")
screen.hideCursorLocked(false)
screen.enableMouseTrackingLocked(false)
screen.setAlternateScreenModeLocked(false)
if screen.useAlternateScreen {
screen.setAlternateScreenModeLocked(false)
}
}

func (screen *UnixScreen) shouldEnableMouseTracking() bool {
Expand Down
Loading