Skip to content

Commit e1432da

Browse files
author
Mike Pountney
committed
Fixes #8 - Allow breaking out of the UI to run external commands (eg vim)
This isn't perfect, but it does work acceptably. By turning off event handlers (using empty func() as the handler for an event) and by readding echo and opost to the tty, we get a functional terminal. (NB: the stty isn't strictly necessary for vim, but does cause a problem if you enter vim and then get to a shell from inside it. So screw it, make it work for interactive shell too via :shell command.)
1 parent 48910ef commit e1432da

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

command_bar_fragment.go

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ func handleCommand(command string) {
7070
if len(command) > 10 {
7171
handleCommentCommand(string(command[9:]))
7272
}
73+
case action == "shell":
74+
runShell()
7375
case action == "search" || action == "search-open" || action == "so":
7476
handleSearchOpen(args)
7577
case action == "search-all" || action == "sa":

run.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ Query Options:
233233
}
234234
defer ui.Close()
235235

236-
registerKeyboardHandlers()
236+
registerEventHandlers()
237237

238238
helpPage = new(HelpPage)
239239
commandBar = new(CommandBar)

ui_controls.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
ui "github.com/gizak/termui"
77
)
88

9-
func registerKeyboardHandlers() {
9+
func registerEventHandlers() {
1010
ui.Handle("/sys/kbd/", func(ev ui.Event) {
1111
handleAnyKey(ev)
1212
})
@@ -18,6 +18,12 @@ func registerKeyboardHandlers() {
1818
})
1919
}
2020

21+
func deregisterEventHandlers() {
22+
ui.Handle("/sys/kbd/", func(ev ui.Event) {})
23+
ui.Handle("/sys/kbd/C-c", func(ev ui.Event) {})
24+
ui.Handle("/sys/wnd/resize", func(ev ui.Event) {})
25+
}
26+
2127
func handleLabelViewKey() {
2228
switch page := currentPage.(type) {
2329
case *TicketListPage:

utils.go

+37-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io/ioutil"
77
"os"
8+
"os/exec"
89
"regexp"
910
"strings"
1011

@@ -38,13 +39,43 @@ func countLabelsFromQueryData(data interface{}) map[string]int {
3839
return counts
3940
}
4041

42+
func RunExternalCommand(fn func() error) error {
43+
log.Debugf("ShellOut() called with %q", fn)
44+
deregisterEventHandlers()
45+
ui.Clear()
46+
stty := exec.Command("stty", "-f", "/dev/tty", "echo", "opost")
47+
_ = stty.Run()
48+
err := fn() // magic happens
49+
stty = exec.Command("stty", "-f", "/dev/tty", "-echo", "-opost")
50+
_ = stty.Run()
51+
registerEventHandlers()
52+
if err != nil {
53+
return err
54+
}
55+
return nil
56+
}
57+
58+
func runShell() {
59+
_ = RunExternalCommand(
60+
func() error {
61+
cmd := exec.Command("bash")
62+
cmd.Stdout, cmd.Stderr, cmd.Stdin = os.Stdout, os.Stderr, os.Stdin
63+
return cmd.Run()
64+
})
65+
}
66+
4167
func runJiraCmdEdit(ticketId string) {
42-
opts := getJiraOpts()
43-
c := jira.New(opts)
44-
ui.Close()
45-
c.CmdEdit(ticketId)
46-
log.Notice("Regrettably, need to exit after edit. See https://github.com/mikepea/go-jira-ui/issues/8")
47-
os.Exit(0)
68+
_ = RunExternalCommand(
69+
func() error {
70+
opts := getJiraOpts()
71+
c := jira.New(opts)
72+
return c.CmdEdit(ticketId)
73+
})
74+
switch c := currentPage.(type) {
75+
case Refresher:
76+
c.Refresh()
77+
}
78+
changePage()
4879
}
4980

5081
func runJiraCmdCommentNoEditor(ticketId string, comment string) {

0 commit comments

Comments
 (0)