]> git.lizzy.rs Git - micro.git/blob - cmd/micro/terminal.go
Clean up terminal a bit and wait before closing
[micro.git] / cmd / micro / terminal.go
1 package main
2
3 import (
4         "os/exec"
5         "strconv"
6
7         "github.com/zyedidia/tcell"
8         "github.com/zyedidia/terminal"
9 )
10
11 const (
12         VTIdle    = iota // Waiting for a new command
13         VTRunning        // Currently running a command
14         VTDone           // Finished running a command
15 )
16
17 // A Terminal holds information for the terminal emulator
18 type Terminal struct {
19         state  terminal.State
20         term   *terminal.VT
21         title  string
22         status int
23 }
24
25 // Start begins a new command in this terminal with a given view
26 func (t *Terminal) Start(execCmd []string, view *View) error {
27         if len(execCmd) <= 0 {
28                 return nil
29         }
30
31         cmd := exec.Command(execCmd[0], execCmd[1:]...)
32         term, _, err := terminal.Start(&t.state, cmd)
33         if err != nil {
34                 return err
35         }
36         t.term = term
37         t.status = VTRunning
38         t.title = execCmd[0] + ":" + strconv.Itoa(cmd.Process.Pid)
39
40         go func() {
41                 for {
42                         err := term.Parse()
43                         if err != nil {
44                                 break
45                         }
46                         updateterm <- true
47                 }
48                 closeterm <- view.Num
49         }()
50
51         return nil
52 }
53
54 // Resize informs the terminal of a resize event
55 func (t *Terminal) Resize(width, height int) {
56         t.term.Resize(width, height)
57 }
58
59 // Stop stops execution of the terminal and sets the status
60 // to VTDone
61 func (t *Terminal) Stop() {
62         t.term.File().Close()
63         t.term.Close()
64         t.status = VTDone
65 }
66
67 // Close sets the status to VTIdle indicating that the terminal
68 // is ready for a new command to execute
69 func (t *Terminal) Close() {
70         t.status = VTIdle
71 }
72
73 // WriteString writes a given string to this terminal's pty
74 func (t *Terminal) WriteString(str string) {
75         t.term.File().WriteString(str)
76 }
77
78 // Display displays this terminal in a view
79 func (t *Terminal) Display(v *View) {
80         divider := 0
81         if v.x != 0 {
82                 divider = 1
83                 dividerStyle := defStyle
84                 if style, ok := colorscheme["divider"]; ok {
85                         dividerStyle = style
86                 }
87                 for i := 0; i < v.Height; i++ {
88                         screen.SetContent(v.x, v.y+i, '|', nil, dividerStyle.Reverse(true))
89                 }
90         }
91         t.state.Lock()
92         defer t.state.Unlock()
93
94         for y := 0; y < v.Height; y++ {
95                 for x := 0; x < v.Width; x++ {
96
97                         c, f, b := t.state.Cell(x, y)
98
99                         fg, bg := int(f), int(b)
100                         if f == terminal.DefaultFG {
101                                 fg = int(tcell.ColorDefault)
102                         }
103                         if b == terminal.DefaultBG {
104                                 bg = int(tcell.ColorDefault)
105                         }
106                         st := tcell.StyleDefault.Foreground(GetColor256(int(fg))).Background(GetColor256(int(bg)))
107
108                         screen.SetContent(v.x+x+divider, v.y+y, c, nil, st)
109                 }
110         }
111         if t.state.CursorVisible() && tabs[curTab].CurView == v.Num {
112                 curx, cury := t.state.Cursor()
113                 screen.ShowCursor(curx+v.x+divider, cury+v.y)
114         }
115 }