]> git.lizzy.rs Git - micro.git/blobdiff - internal/screen/screen.go
Merge pull request #1324 from konsumer/master
[micro.git] / internal / screen / screen.go
index 1e149be7201311af328f3922456dd50efb2ddaab..f9ab1bd8878dd6a7ca29140aaf3e98f2139ea24d 100644 (file)
@@ -6,7 +6,7 @@ import (
        "sync"
 
        "github.com/zyedidia/micro/internal/config"
-       "github.com/zyedidia/micro/pkg/terminfo"
+       "github.com/zyedidia/micro/internal/util"
        "github.com/zyedidia/tcell"
 )
 
@@ -17,21 +17,85 @@ import (
 // screen. TODO: maybe we should worry about polling and drawing at the
 // same time too.
 var Screen tcell.Screen
+
+// The lock is necessary since the screen is polled on a separate thread
 var lock sync.Mutex
+
+// DrawChan is a channel that will cause the screen to redraw when
+// written to even if no event user event has occurred
 var DrawChan chan bool
 
+// Lock locks the screen lock
 func Lock() {
        lock.Lock()
 }
 
+// Unlock unlocks the screen lock
 func Unlock() {
        lock.Unlock()
 }
 
+// Redraw schedules a redraw with the draw channel
 func Redraw() {
        DrawChan <- true
 }
 
+type screenCell struct {
+       x, y  int
+       r     rune
+       combc []rune
+       style tcell.Style
+}
+
+var lastCursor screenCell
+
+// ShowFakeCursor displays a cursor at the given position by modifying the
+// style of the given column instead of actually using the terminal cursor
+// This can be useful in certain terminals such as the windows console where
+// modifying the cursor location is slow and frequent modifications cause flashing
+// This keeps track of the most recent fake cursor location and resets it when
+// a new fake cursor location is specified
+func ShowFakeCursor(x, y int) {
+       r, combc, style, _ := Screen.GetContent(x, y)
+       Screen.SetContent(lastCursor.x, lastCursor.y, lastCursor.r, lastCursor.combc, lastCursor.style)
+       Screen.SetContent(x, y, r, combc, config.DefStyle.Reverse(true))
+
+       lastCursor.x, lastCursor.y = x, y
+       lastCursor.r = r
+       lastCursor.combc = combc
+       lastCursor.style = style
+}
+
+// ShowFakeCursorMulti is the same as ShowFakeCursor except it does not
+// reset previous locations of the cursor
+// Fake cursors are also necessary to display multiple cursors
+func ShowFakeCursorMulti(x, y int) {
+       r, _, _, _ := Screen.GetContent(x, y)
+       Screen.SetContent(x, y, r, nil, config.DefStyle.Reverse(true))
+}
+
+// ShowCursor puts the cursor at the given location using a fake cursor
+// if enabled or using the terminal cursor otherwise
+// By default only the windows console will use a fake cursor
+func ShowCursor(x, y int) {
+       if util.FakeCursor {
+               ShowFakeCursor(x, y)
+       } else {
+               Screen.ShowCursor(x, y)
+       }
+}
+
+// SetContent sets a cell at a point on the screen and makes sure that it is
+// synced with the last cursor location
+func SetContent(x, y int, mainc rune, combc []rune, style tcell.Style) {
+       Screen.SetContent(x, y, mainc, combc, style)
+       if util.FakeCursor && lastCursor.x == x && lastCursor.y == y {
+               lastCursor.r = mainc
+               lastCursor.style = style
+               lastCursor.combc = combc
+       }
+}
+
 // TempFini shuts the screen down temporarily
 func TempFini() bool {
        screenWasNil := Screen == nil
@@ -59,52 +123,24 @@ func Init() {
        // Should we enable true color?
        truecolor := os.Getenv("MICRO_TRUECOLOR") == "1"
 
-       tcelldb := os.Getenv("TCELLDB")
-       os.Setenv("TCELLDB", config.ConfigDir+"/.tcelldb")
-
-       // In order to enable true color, we have to set the TERM to `xterm-truecolor` when
-       // initializing tcell, but after that, we can set the TERM back to whatever it was
-       oldTerm := os.Getenv("TERM")
-       if truecolor {
-               os.Setenv("TERM", "xterm-truecolor")
+       if !truecolor {
+               os.Setenv("TCELL_TRUECOLOR", "disable")
        }
 
        // Initilize tcell
        var err error
        Screen, err = tcell.NewScreen()
        if err != nil {
-               if err == tcell.ErrTermNotFound {
-                       err = terminfo.WriteDB(config.ConfigDir + "/.tcelldb")
-                       if err != nil {
-                               fmt.Println(err)
-                               fmt.Println("Fatal: Micro could not create terminal database file", config.ConfigDir+"/.tcelldb")
-                               os.Exit(1)
-                       }
-                       Screen, err = tcell.NewScreen()
-                       if err != nil {
-                               fmt.Println(err)
-                               fmt.Println("Fatal: Micro could not initialize a Screen.")
-                               os.Exit(1)
-                       }
-               } else {
-                       fmt.Println(err)
-                       fmt.Println("Fatal: Micro could not initialize a Screen.")
-                       os.Exit(1)
-               }
+               fmt.Println(err)
+               fmt.Println("Fatal: Micro could not initialize a Screen.")
+               os.Exit(1)
        }
        if err = Screen.Init(); err != nil {
                fmt.Println(err)
                os.Exit(1)
        }
 
-       // Now we can put the TERM back to what it was before
-       if truecolor {
-               os.Setenv("TERM", oldTerm)
-       }
-
        if config.GetGlobalOption("mouse").(bool) {
                Screen.EnableMouse()
        }
-
-       os.Setenv("TCELLDB", tcelldb)
 }