mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 17:56:45 +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
|
pager string
|
||||||
lastnl bool
|
lastnl bool
|
||||||
cancel func()
|
cancel func()
|
||||||
|
|
||||||
|
lines, columns int
|
||||||
}
|
}
|
||||||
|
|
||||||
type pagingWriterMode uint8
|
type pagingWriterMode uint8
|
||||||
@ -108,9 +110,6 @@ const (
|
|||||||
pagingWriterNormal pagingWriterMode = iota
|
pagingWriterNormal pagingWriterMode = iota
|
||||||
pagingWriterMaybe
|
pagingWriterMaybe
|
||||||
pagingWriterPaging
|
pagingWriterPaging
|
||||||
|
|
||||||
pagingWriterMaxLines = 30
|
|
||||||
pagingWriterColsPerLine = 100
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *pagingWriter) Write(p []byte) (nn int, err error) {
|
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.cmdStdin.Write(w.buf)
|
||||||
w.buf = nil
|
w.buf = nil
|
||||||
w.mode = pagingWriterPaging
|
w.mode = pagingWriterPaging
|
||||||
return w.cmdStdin.Write(p)
|
return len(p), nil
|
||||||
} else {
|
} else {
|
||||||
if len(p) > 0 {
|
if len(p) > 0 {
|
||||||
w.lastnl = p[len(p)-1] == '\n'
|
w.lastnl = p[len(p)-1] == '\n'
|
||||||
@ -202,17 +201,17 @@ func (w *pagingWriter) PageMaybe(cancel func()) {
|
|||||||
}
|
}
|
||||||
w.lastnl = true
|
w.lastnl = true
|
||||||
w.cancel = cancel
|
w.cancel = cancel
|
||||||
|
w.getWindowSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *pagingWriter) largeOutput() bool {
|
func (w *pagingWriter) largeOutput() bool {
|
||||||
if len(w.buf) > pagingWriterMaxLines*pagingWriterColsPerLine {
|
lines := 0
|
||||||
return true
|
lineStart := 0
|
||||||
}
|
|
||||||
nl := 0
|
|
||||||
for i := range w.buf {
|
for i := range w.buf {
|
||||||
if w.buf[i] == '\n' {
|
if i-lineStart > w.columns || w.buf[i] == '\n' {
|
||||||
nl++
|
lineStart = i
|
||||||
if nl > pagingWriterMaxLines {
|
lines++
|
||||||
|
if lines > w.lines {
|
||||||
return true
|
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