readline/utils_unix.go

112 lines
2.2 KiB
Go
Raw Normal View History

// +build aix darwin dragonfly freebsd linux,!appengine netbsd openbsd os400 solaris
2015-09-27 06:41:05 +03:00
package readline
import (
"io"
2016-03-13 13:32:48 +03:00
"os"
"os/signal"
"sync"
2015-09-27 06:41:05 +03:00
"syscall"
)
type winsize struct {
Row uint16
Col uint16
Xpixel uint16
Ypixel uint16
}
// SuspendMe use to send suspend signal to myself, when we in the raw mode.
// For OSX it need to send to parent's pid
// For Linux it need to send to myself
func SuspendMe() {
p, _ := os.FindProcess(os.Getppid())
p.Signal(syscall.SIGTSTP)
p, _ = os.FindProcess(os.Getpid())
p.Signal(syscall.SIGTSTP)
}
2015-09-27 06:41:05 +03:00
// get width of the terminal
func getWidth(stdoutFd int) int {
cols, _, err := GetSize(stdoutFd)
if err != nil {
return -1
2015-09-27 06:41:05 +03:00
}
return cols
2015-09-27 06:41:05 +03:00
}
2016-03-13 13:32:48 +03:00
func GetScreenWidth() int {
w := getWidth(syscall.Stdout)
if w < 0 {
w = getWidth(syscall.Stderr)
}
return w
2016-03-13 13:32:48 +03:00
}
A Pager to list completion candidates if they don't fit on one page. Main Features: - If there are too many candidates returned by the completer, completemode and completeselectmode did not work properly. Similar to the bash completion pager, list candidates and offer "--More--" on the end of each page. User can select " ", "y" or "Y" to keep listing or "q", "Q", "n", "N" to stop listing. When paging completes, we also exit out of completion mode. - Added aggregate completion when entering completeselectmode where the candiddates dwindle down sharing a larger common prefix. This makes typing a little faster than having to select. More bash-like behaviour. Other Fixes: - Fix various crashes where candidates are too wide for the width of the screen and causes division by zero. - Fix crash with wide (Asian characters) in completion. - Streamline redrawing as CompleteRefresh was called too often. - Fix crashes around ctrl-a and ctrl-b in select mode when candidates don't fit on a line - Fix prev/next candidates in select mode when candidates don't fit on a line - Fix crash when ctrl-k was pressed in select mode. This caused us to exitselectmode which cleaned up all the data but left us in complete mode such that if CompleteRefresh was callled directly, the data was not initialized. - Fix complete and select mode redraw issues when candidates did not fit on one line. - Fix cursor position issues after CompleteRefresh especially if the prompt and buffer also went over 1 line. - Fix redraw issue where exiting completion mode using certain key presses leaves candidates on the screen. Fixes for Windows: - Use window size for visible height/width instead of buffer size - Adjust for Window's EOL behaviour. Notes: - Added Height info to different structures as the decision to page or not required height information. - Added OnSizeChange(). Didn't know if I could get rid of the OnWidthChange()? Would be nice to remove the Width stuff and just have Size (width + height info).
2022-06-28 08:49:19 +03:00
// getWidthHeight of the terminal using given file descriptor
func getWidthHeight(stdoutFd int) (width int, height int) {
width, height, err := GetSize(stdoutFd)
if err != nil {
return -1, -1
}
return
}
// GetScreenSize returns the width/height of the terminal or -1,-1 or error
func GetScreenSize() (width int, height int) {
width, height = getWidthHeight(syscall.Stdout)
if width < 0 {
width, height = getWidthHeight(syscall.Stderr)
}
return
}
// Ask the terminal for the current cursor position. The terminal will then
// write the position back to us via termainal stdin asynchronously.
func SendCursorPosition(t *Terminal) {
t.Write([]byte("\033[6n"))
}
// ClearScreen clears the console screen
func ClearScreen(w io.Writer) (int, error) {
return w.Write([]byte("\033[H"))
}
2016-03-13 13:32:48 +03:00
func DefaultIsTerminal() bool {
return IsTerminal(syscall.Stdin) && (IsTerminal(syscall.Stdout) || IsTerminal(syscall.Stderr))
2016-03-13 13:32:48 +03:00
}
func GetStdin() int {
return syscall.Stdin
}
// -----------------------------------------------------------------------------
var (
A Pager to list completion candidates if they don't fit on one page. Main Features: - If there are too many candidates returned by the completer, completemode and completeselectmode did not work properly. Similar to the bash completion pager, list candidates and offer "--More--" on the end of each page. User can select " ", "y" or "Y" to keep listing or "q", "Q", "n", "N" to stop listing. When paging completes, we also exit out of completion mode. - Added aggregate completion when entering completeselectmode where the candiddates dwindle down sharing a larger common prefix. This makes typing a little faster than having to select. More bash-like behaviour. Other Fixes: - Fix various crashes where candidates are too wide for the width of the screen and causes division by zero. - Fix crash with wide (Asian characters) in completion. - Streamline redrawing as CompleteRefresh was called too often. - Fix crashes around ctrl-a and ctrl-b in select mode when candidates don't fit on a line - Fix prev/next candidates in select mode when candidates don't fit on a line - Fix crash when ctrl-k was pressed in select mode. This caused us to exitselectmode which cleaned up all the data but left us in complete mode such that if CompleteRefresh was callled directly, the data was not initialized. - Fix complete and select mode redraw issues when candidates did not fit on one line. - Fix cursor position issues after CompleteRefresh especially if the prompt and buffer also went over 1 line. - Fix redraw issue where exiting completion mode using certain key presses leaves candidates on the screen. Fixes for Windows: - Use window size for visible height/width instead of buffer size - Adjust for Window's EOL behaviour. Notes: - Added Height info to different structures as the decision to page or not required height information. - Added OnSizeChange(). Didn't know if I could get rid of the OnWidthChange()? Would be nice to remove the Width stuff and just have Size (width + height info).
2022-06-28 08:49:19 +03:00
sizeChange sync.Once
sizeChangeCallback func()
2016-03-13 13:32:48 +03:00
)
func DefaultOnWidthChanged(f func()) {
A Pager to list completion candidates if they don't fit on one page. Main Features: - If there are too many candidates returned by the completer, completemode and completeselectmode did not work properly. Similar to the bash completion pager, list candidates and offer "--More--" on the end of each page. User can select " ", "y" or "Y" to keep listing or "q", "Q", "n", "N" to stop listing. When paging completes, we also exit out of completion mode. - Added aggregate completion when entering completeselectmode where the candiddates dwindle down sharing a larger common prefix. This makes typing a little faster than having to select. More bash-like behaviour. Other Fixes: - Fix various crashes where candidates are too wide for the width of the screen and causes division by zero. - Fix crash with wide (Asian characters) in completion. - Streamline redrawing as CompleteRefresh was called too often. - Fix crashes around ctrl-a and ctrl-b in select mode when candidates don't fit on a line - Fix prev/next candidates in select mode when candidates don't fit on a line - Fix crash when ctrl-k was pressed in select mode. This caused us to exitselectmode which cleaned up all the data but left us in complete mode such that if CompleteRefresh was callled directly, the data was not initialized. - Fix complete and select mode redraw issues when candidates did not fit on one line. - Fix cursor position issues after CompleteRefresh especially if the prompt and buffer also went over 1 line. - Fix redraw issue where exiting completion mode using certain key presses leaves candidates on the screen. Fixes for Windows: - Use window size for visible height/width instead of buffer size - Adjust for Window's EOL behaviour. Notes: - Added Height info to different structures as the decision to page or not required height information. - Added OnSizeChange(). Didn't know if I could get rid of the OnWidthChange()? Would be nice to remove the Width stuff and just have Size (width + height info).
2022-06-28 08:49:19 +03:00
DefaultOnSizeChanged(f)
}
func DefaultOnSizeChanged(f func()) {
sizeChangeCallback = f
sizeChange.Do(func() {
2016-03-13 13:32:48 +03:00
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGWINCH)
go func() {
for {
_, ok := <-ch
if !ok {
break
}
A Pager to list completion candidates if they don't fit on one page. Main Features: - If there are too many candidates returned by the completer, completemode and completeselectmode did not work properly. Similar to the bash completion pager, list candidates and offer "--More--" on the end of each page. User can select " ", "y" or "Y" to keep listing or "q", "Q", "n", "N" to stop listing. When paging completes, we also exit out of completion mode. - Added aggregate completion when entering completeselectmode where the candiddates dwindle down sharing a larger common prefix. This makes typing a little faster than having to select. More bash-like behaviour. Other Fixes: - Fix various crashes where candidates are too wide for the width of the screen and causes division by zero. - Fix crash with wide (Asian characters) in completion. - Streamline redrawing as CompleteRefresh was called too often. - Fix crashes around ctrl-a and ctrl-b in select mode when candidates don't fit on a line - Fix prev/next candidates in select mode when candidates don't fit on a line - Fix crash when ctrl-k was pressed in select mode. This caused us to exitselectmode which cleaned up all the data but left us in complete mode such that if CompleteRefresh was callled directly, the data was not initialized. - Fix complete and select mode redraw issues when candidates did not fit on one line. - Fix cursor position issues after CompleteRefresh especially if the prompt and buffer also went over 1 line. - Fix redraw issue where exiting completion mode using certain key presses leaves candidates on the screen. Fixes for Windows: - Use window size for visible height/width instead of buffer size - Adjust for Window's EOL behaviour. Notes: - Added Height info to different structures as the decision to page or not required height information. - Added OnSizeChange(). Didn't know if I could get rid of the OnWidthChange()? Would be nice to remove the Width stuff and just have Size (width + height info).
2022-06-28 08:49:19 +03:00
sizeChangeCallback()
2016-03-13 13:32:48 +03:00
}
}()
})
}