mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 09:46:56 +08:00
terminal: use exact window size for pager (#3249)
Instead of using a fixed 100x30 window size query the operating system for the exact size, also fixes a bug where the last line before calling the pager is repeated twice.
This commit is contained in:
committed by
GitHub
parent
58fc3931e8
commit
2be9cf1fab
@ -100,6 +100,8 @@ type pagingWriter struct {
|
||||
pager string
|
||||
lastnl bool
|
||||
cancel func()
|
||||
|
||||
lines, columns int
|
||||
}
|
||||
|
||||
type pagingWriterMode uint8
|
||||
@ -108,9 +110,6 @@ const (
|
||||
pagingWriterNormal pagingWriterMode = iota
|
||||
pagingWriterMaybe
|
||||
pagingWriterPaging
|
||||
|
||||
pagingWriterMaxLines = 30
|
||||
pagingWriterColsPerLine = 100
|
||||
)
|
||||
|
||||
func (w *pagingWriter) Write(p []byte) (nn int, err error) {
|
||||
@ -141,7 +140,7 @@ func (w *pagingWriter) Write(p []byte) (nn int, err error) {
|
||||
w.cmdStdin.Write(w.buf)
|
||||
w.buf = nil
|
||||
w.mode = pagingWriterPaging
|
||||
return w.cmdStdin.Write(p)
|
||||
return len(p), nil
|
||||
} else {
|
||||
if len(p) > 0 {
|
||||
w.lastnl = p[len(p)-1] == '\n'
|
||||
@ -202,17 +201,17 @@ func (w *pagingWriter) PageMaybe(cancel func()) {
|
||||
}
|
||||
w.lastnl = true
|
||||
w.cancel = cancel
|
||||
w.getWindowSize()
|
||||
}
|
||||
|
||||
func (w *pagingWriter) largeOutput() bool {
|
||||
if len(w.buf) > pagingWriterMaxLines*pagingWriterColsPerLine {
|
||||
return true
|
||||
}
|
||||
nl := 0
|
||||
lines := 0
|
||||
lineStart := 0
|
||||
for i := range w.buf {
|
||||
if w.buf[i] == '\n' {
|
||||
nl++
|
||||
if nl > pagingWriterMaxLines {
|
||||
if i-lineStart > w.columns || w.buf[i] == '\n' {
|
||||
lineStart = i
|
||||
lines++
|
||||
if lines > w.lines {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
25
pkg/terminal/out_unix.go
Normal file
25
pkg/terminal/out_unix.go
Normal file
@ -0,0 +1,25 @@
|
||||
//go:build linux || darwin || freebsd
|
||||
// +build linux darwin freebsd
|
||||
|
||||
package terminal
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type winSize struct {
|
||||
row, col uint16
|
||||
xpixel, ypixel uint16
|
||||
}
|
||||
|
||||
func (w *pagingWriter) getWindowSize() {
|
||||
var ws winSize
|
||||
ok, _, _ := syscall.Syscall(syscall.SYS_IOCTL, uintptr(syscall.Stdout), syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&ws)))
|
||||
if int(ok) < 0 {
|
||||
w.mode = pagingWriterNormal
|
||||
return
|
||||
}
|
||||
w.lines = int(ws.row)
|
||||
w.columns = int(ws.col)
|
||||
}
|
||||
44
pkg/terminal/out_windows.go
Normal file
44
pkg/terminal/out_windows.go
Normal file
@ -0,0 +1,44 @@
|
||||
package terminal
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetStdHandle = kernel32.NewProc("GetStdHandle")
|
||||
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
)
|
||||
|
||||
type coord struct {
|
||||
x, y int16
|
||||
}
|
||||
|
||||
type smallRect struct {
|
||||
left, top, right, bottom int16
|
||||
}
|
||||
|
||||
type consoleScreenBufferInfo struct {
|
||||
dwSize coord
|
||||
dwCursorPosition coord
|
||||
wAttributes int16
|
||||
srWindow smallRect
|
||||
dwMaximumWindowSize coord
|
||||
}
|
||||
|
||||
func (w *pagingWriter) getWindowSize() {
|
||||
hout, _, err := procGetStdHandle.Call(uintptr(uint32(-12 & 0xFFFFFFFF))) // stdout handle
|
||||
if err != syscall.Errno(0) {
|
||||
w.mode = pagingWriterNormal
|
||||
return
|
||||
}
|
||||
var sbi consoleScreenBufferInfo
|
||||
_, _, err = procGetConsoleScreenBufferInfo.Call(uintptr(hout), uintptr(unsafe.Pointer(&sbi)))
|
||||
if err != syscall.Errno(0) {
|
||||
w.mode = pagingWriterNormal
|
||||
return
|
||||
}
|
||||
w.columns = int(sbi.srWindow.right - sbi.srWindow.left + 1)
|
||||
w.lines = int(sbi.srWindow.bottom - sbi.srWindow.top + 1)
|
||||
}
|
||||
Reference in New Issue
Block a user