summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2017-04-28 22:58:08 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2017-04-28 22:58:08 +0900
commitd34e4cf6984a139c12646d21771526e1e2a6f4f7 (patch)
treed3124713871b7c62c3b1bbfe1e8a3347d96f20f0 /src
parent6b592137b966299a8a1324ccb1ddf3d6aaa7bbc9 (diff)
Support CTRL-Z (SIGSTOP)
Diffstat (limited to 'src')
-rw-r--r--src/terminal.go49
-rw-r--r--src/terminal_unix.go8
-rw-r--r--src/terminal_windows.go8
-rw-r--r--src/tui/dummy.go12
-rw-r--r--src/tui/light.go38
-rw-r--r--src/tui/ncurses.go5
-rw-r--r--src/tui/tcell.go9
-rw-r--r--src/tui/tui.go4
8 files changed, 92 insertions, 41 deletions
diff --git a/src/terminal.go b/src/terminal.go
index 197ab6b6..2802edd9 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -59,6 +59,7 @@ type Terminal struct {
inlineInfo bool
prompt string
reverse bool
+ fullscreen bool
hscroll bool
hscrollOff int
wordRubout string
@@ -141,6 +142,7 @@ const (
reqList
reqJump
reqRefresh
+ reqReinit
reqRedraw
reqClose
reqPrintQuery
@@ -210,6 +212,7 @@ const (
actExecute
actExecuteSilent
actExecuteMulti // Deprecated
+ actSigStop
)
func toActions(types ...actionType) []action {
@@ -246,6 +249,9 @@ func defaultKeymap() map[int][]action {
keymap[tui.CtrlU] = toActions(actUnixLineDiscard)
keymap[tui.CtrlW] = toActions(actUnixWordRubout)
keymap[tui.CtrlY] = toActions(actYank)
+ if !util.IsWindows() {
+ keymap[tui.CtrlZ] = toActions(actSigStop)
+ }
keymap[tui.AltB] = toActions(actBackwardWord)
keymap[tui.SLeft] = toActions(actBackwardWord)
@@ -295,7 +301,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
strongAttr = tui.AttrRegular
}
var renderer tui.Renderer
- if opts.Height.size == 0 || opts.Height.percent && opts.Height.size == 100 {
+ fullscreen := opts.Height.size == 0 || opts.Height.percent && opts.Height.size == 100
+ if fullscreen {
if tui.HasFullscreenRenderer() {
renderer = tui.NewFullscreenRenderer(opts.Theme, opts.Black, opts.Mouse)
} else {
@@ -337,6 +344,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
inlineInfo: opts.InlineInfo,
prompt: opts.Prompt,
reverse: opts.Reverse,
+ fullscreen: fullscreen,
hscroll: opts.Hscroll,
hscrollOff: opts.HscrollOff,
wordRubout: wordRubout,
@@ -1170,6 +1178,12 @@ func replacePlaceholder(template string, stripAnsi bool, delimiter Delimiter, fo
})
}
+func (t *Terminal) redraw() {
+ t.tui.Clear()
+ t.tui.Refresh()
+ t.printAll()
+}
+
func (t *Terminal) executeCommand(template string, forcePlus bool, background bool) {
valid, list := t.buildPlusList(template, forcePlus)
if !valid {
@@ -1181,12 +1195,10 @@ func (t *Terminal) executeCommand(template string, forcePlus bool, background bo
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
- t.tui.Pause()
+ t.tui.Pause(true)
cmd.Run()
- if t.tui.Resume() {
- t.tui.Clear()
- t.printAll()
- }
+ t.tui.Resume(true)
+ t.redraw()
t.refresh()
} else {
cmd.Run()
@@ -1244,6 +1256,15 @@ func (t *Terminal) Loop() {
t.reqBox.Set(reqQuit, nil)
}()
+ contChan := make(chan os.Signal, 1)
+ notifyOnCont(contChan)
+ go func() {
+ for {
+ <-contChan
+ t.reqBox.Set(reqReinit, nil)
+ }
+ }()
+
resizeChan := make(chan os.Signal, 1)
notifyOnResize(resizeChan) // Non-portable
go func() {
@@ -1352,10 +1373,11 @@ func (t *Terminal) Loop() {
t.printHeader()
case reqRefresh:
t.suppress = false
+ case reqReinit:
+ t.tui.Resume(t.fullscreen)
+ t.redraw()
case reqRedraw:
- t.tui.Clear()
- t.tui.Refresh()
- t.printAll()
+ t.redraw()
case reqClose:
t.tui.Close()
if t.output() {
@@ -1654,6 +1676,15 @@ func (t *Terminal) Loop() {
t.input = []rune(t.history.next())
t.cx = len(t.input)
}
+ case actSigStop:
+ p, err := os.FindProcess(os.Getpid())
+ if err == nil {
+ t.tui.Clear()
+ t.tui.Pause(t.fullscreen)
+ notifyStop(p)
+ t.mutex.Unlock()
+ return false
+ }
case actMouse:
me := event.MouseEvent
mx, my := me.X, me.Y
diff --git a/src/terminal_unix.go b/src/terminal_unix.go
index 6284c22d..2ae8175a 100644
--- a/src/terminal_unix.go
+++ b/src/terminal_unix.go
@@ -11,3 +11,11 @@ import (
func notifyOnResize(resizeChan chan<- os.Signal) {
signal.Notify(resizeChan, syscall.SIGWINCH)
}
+
+func notifyStop(p *os.Process) {
+ p.Signal(syscall.SIGSTOP)
+}
+
+func notifyOnCont(resizeChan chan<- os.Signal) {
+ signal.Notify(resizeChan, syscall.SIGCONT)
+}
diff --git a/src/terminal_windows.go b/src/terminal_windows.go
index 5512bbaf..9de7ae45 100644
--- a/src/terminal_windows.go
+++ b/src/terminal_windows.go
@@ -9,3 +9,11 @@ import (
func notifyOnResize(resizeChan chan<- os.Signal) {
// TODO
}
+
+func notifyStop(p *os.Process) {
+ // NOOP
+}
+
+func notifyOnCont(resizeChan chan<- os.Signal) {
+ // NOOP
+}
diff --git a/src/tui/dummy.go b/src/tui/dummy.go
index 60a23fb6..c96ce8eb 100644
--- a/src/tui/dummy.go
+++ b/src/tui/dummy.go
@@ -25,13 +25,13 @@ const (
Reverse = Attr(1 << 6)
)
-func (r *FullscreenRenderer) Init() {}
-func (r *FullscreenRenderer) Pause() {}
-func (r *FullscreenRenderer) Clear() {}
-func (r *FullscreenRenderer) Refresh() {}
-func (r *FullscreenRenderer) Close() {}
+func (r *FullscreenRenderer) Init() {}
+func (r *FullscreenRenderer) Pause(bool) {}
+func (r *FullscreenRenderer) Resume(bool) {}
+func (r *FullscreenRenderer) Clear() {}
+func (r *FullscreenRenderer) Refresh() {}
+func (r *FullscreenRenderer) Close() {}
-func (r *FullscreenRenderer) Resume() bool { return false }
func (r *FullscreenRenderer) DoesAutoWrap() bool { return false }
func (r *FullscreenRenderer) IsOptimized() bool { return false }
func (r *FullscreenRenderer) GetChar() Event { return Event{} }
diff --git a/src/tui/light.go b/src/tui/light.go
index 7819050c..be6950c8 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -522,27 +522,35 @@ func (r *LightRenderer) rmcup() {
r.csi("?1049l")
}
-func (r *LightRenderer) Pause() {
+func (r *LightRenderer) Pause(clear bool) {
terminal.Restore(r.fd(), r.origState)
- if r.fullscreen {
- r.rmcup()
- } else {
- r.smcup()
- r.csi("H")
+ if clear {
+ if r.fullscreen {
+ r.rmcup()
+ } else {
+ r.smcup()
+ r.csi("H")
+ }
+ r.flush()
}
- r.flush()
}
-func (r *LightRenderer) Resume() bool {
+func (r *LightRenderer) Resume(clear bool) {
terminal.MakeRaw(r.fd())
- if r.fullscreen {
- r.smcup()
- } else {
- r.rmcup()
+ if clear {
+ if r.fullscreen {
+ r.smcup()
+ } else {
+ r.rmcup()
+ }
+ r.flush()
+ } else if !r.fullscreen && r.mouse {
+ // NOTE: Resume(false) is only called on SIGCONT after SIGSTOP.
+ // And It's highly likely that the offset we obtained at the beginning will
+ // no longer be correct, so we simply disable mouse input.
+ r.csi("?1000l")
+ r.mouse = false
}
- r.flush()
- // Should redraw
- return true
}
func (r *LightRenderer) Clear() {
diff --git a/src/tui/ncurses.go b/src/tui/ncurses.go
index ba3a1cfb..3263c397 100644
--- a/src/tui/ncurses.go
+++ b/src/tui/ncurses.go
@@ -176,12 +176,11 @@ func initPairs(theme *ColorTheme) {
}
}
-func (r *FullscreenRenderer) Pause() {
+func (r *FullscreenRenderer) Pause(bool) {
C.endwin()
}
-func (r *FullscreenRenderer) Resume() bool {
- return false
+func (r *FullscreenRenderer) Resume(bool) {
}
func (r *FullscreenRenderer) Close() {
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
index bda5d082..3a8c7655 100644
--- a/src/tui/tcell.go
+++ b/src/tui/tcell.go
@@ -282,7 +282,7 @@ func (r *FullscreenRenderer) GetChar() Event {
return Event{keyfn('z'), 0, nil}
case tcell.KeyCtrlSpace:
return Event{CtrlSpace, 0, nil}
- case tcell.KeyBackspace, tcell.KeyBackspace2:
+ case tcell.KeyBackspace2:
if alt {
return Event{AltBS, 0, nil}
}
@@ -308,8 +308,6 @@ func (r *FullscreenRenderer) GetChar() Event {
case tcell.KeyPgDn:
return Event{PgDn, 0, nil}
- case tcell.KeyTab:
- return Event{Tab, 0, nil}
case tcell.KeyBacktab:
return Event{BTab, 0, nil}
@@ -366,13 +364,12 @@ func (r *FullscreenRenderer) GetChar() Event {
return Event{Invalid, 0, nil}
}
-func (r *FullscreenRenderer) Pause() {
+func (r *FullscreenRenderer) Pause(bool) {
_screen.Fini()
}
-func (r *FullscreenRenderer) Resume() bool {
+func (r *FullscreenRenderer) Resume(bool) {
r.initScreen()
- return true
}
func (r *FullscreenRenderer) Close() {
diff --git a/src/tui/tui.go b/src/tui/tui.go
index d360c4ec..c638b35a 100644
--- a/src/tui/tui.go
+++ b/src/tui/tui.go
@@ -206,8 +206,8 @@ const (
type Renderer interface {
Init()
- Pause()
- Resume() bool
+ Pause(clear bool)
+ Resume(clear bool)
Clear()
RefreshWindows(windows []Window)
Refresh()