8 "github.com/zyedidia/micro/internal/config"
9 "github.com/zyedidia/micro/internal/util"
10 "github.com/zyedidia/tcell"
13 // Screen is the tcell screen we use to draw to the terminal
14 // Synchronization is used because we poll the screen on a separate
15 // thread and sometimes the screen is shut down by the main thread
16 // (for example on TermMessage) so we don't want to poll a nil/shutdown
17 // screen. TODO: maybe we should worry about polling and drawing at the
19 var Screen tcell.Screen
21 // The lock is necessary since the screen is polled on a separate thread
24 // DrawChan is a channel that will cause the screen to redraw when
25 // written to even if no event user event has occurred
26 var DrawChan chan bool
28 // Lock locks the screen lock
33 // Unlock unlocks the screen lock
38 // Redraw schedules a redraw with the draw channel
43 type screenCell struct {
50 var lastCursor screenCell
52 // ShowFakeCursor displays a cursor at the given position by modifying the
53 // style of the given column instead of actually using the terminal cursor
54 // This can be useful in certain terminals such as the windows console where
55 // modifying the cursor location is slow and frequent modifications cause flashing
56 // This keeps track of the most recent fake cursor location and resets it when
57 // a new fake cursor location is specified
58 func ShowFakeCursor(x, y int) {
59 r, combc, style, _ := Screen.GetContent(x, y)
60 Screen.SetContent(lastCursor.x, lastCursor.y, lastCursor.r, lastCursor.combc, lastCursor.style)
61 Screen.SetContent(x, y, r, combc, config.DefStyle.Reverse(true))
63 lastCursor.x, lastCursor.y = x, y
65 lastCursor.combc = combc
66 lastCursor.style = style
69 // ShowFakeCursorMulti is the same as ShowFakeCursor except it does not
70 // reset previous locations of the cursor
71 // Fake cursors are also necessary to display multiple cursors
72 func ShowFakeCursorMulti(x, y int) {
73 r, _, _, _ := Screen.GetContent(x, y)
74 Screen.SetContent(x, y, r, nil, config.DefStyle.Reverse(true))
77 // ShowCursor puts the cursor at the given location using a fake cursor
78 // if enabled or using the terminal cursor otherwise
79 // By default only the windows console will use a fake cursor
80 func ShowCursor(x, y int) {
84 Screen.ShowCursor(x, y)
88 // SetContent sets a cell at a point on the screen and makes sure that it is
89 // synced with the last cursor location
90 func SetContent(x, y int, mainc rune, combc []rune, style tcell.Style) {
91 Screen.SetContent(x, y, mainc, combc, style)
92 if util.FakeCursor && lastCursor.x == x && lastCursor.y == y {
94 lastCursor.style = style
95 lastCursor.combc = combc
99 // TempFini shuts the screen down temporarily
100 func TempFini() bool {
101 screenWasNil := Screen == nil
111 // TempStart restarts the screen after it was temporarily disabled
112 func TempStart(screenWasNil bool) {
119 // Init creates and initializes the tcell screen
121 DrawChan = make(chan bool, 8)
123 // Should we enable true color?
124 truecolor := os.Getenv("MICRO_TRUECOLOR") == "1"
127 os.Setenv("TCELL_TRUECOLOR", "disable")
132 Screen, err = tcell.NewScreen()
135 fmt.Println("Fatal: Micro could not initialize a Screen.")
138 if err = Screen.Init(); err != nil {
143 if config.GetGlobalOption("mouse").(bool) {