]> git.lizzy.rs Git - micro.git/commitdiff
Finish support for a fake cursor v2.0.0-rc2
authorZachary Yedidia <zyedidia@gmail.com>
Thu, 2 Jan 2020 03:40:51 +0000 (22:40 -0500)
committerZachary Yedidia <zyedidia@gmail.com>
Thu, 2 Jan 2020 03:40:51 +0000 (22:40 -0500)
internal/display/bufwindow.go
internal/display/infowindow.go
internal/display/statusline.go
internal/display/tabwindow.go
internal/display/termwindow.go
internal/display/uiwindow.go
internal/screen/screen.go
internal/util/util.go

index 0b4391ae09c88e9e4eefa111ee9db814f14e1e15..66ed3be726d41f815462598eb8568fc5ee806627 100644 (file)
@@ -102,7 +102,7 @@ func (w *BufWindow) getStartInfo(n, lineN int) ([]byte, int, int, *tcell.Style)
 func (w *BufWindow) Clear() {
        for y := 0; y < w.Height; y++ {
                for x := 0; x < w.Width; x++ {
-                       screen.Screen.SetContent(w.X+x, w.Y+y, ' ', nil, config.DefStyle)
+                       screen.SetContent(w.X+x, w.Y+y, ' ', nil, config.DefStyle)
                }
        }
 }
@@ -298,9 +298,9 @@ func (w *BufWindow) drawGutter(vloc *buffer.Loc, bloc *buffer.Loc) {
                        break
                }
        }
-       screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, s)
+       screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, s)
        vloc.X++
-       screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, s)
+       screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, s)
        vloc.X++
 }
 
@@ -309,21 +309,21 @@ func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxL
 
        // Write the spaces before the line number if necessary
        for i := 0; i < maxLineNumLength-len(lineNum); i++ {
-               screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
+               screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
                vloc.X++
        }
        // Write the actual line number
        for _, ch := range lineNum {
                if softwrapped {
-                       screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
+                       screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
                } else {
-                       screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ch, nil, lineNumStyle)
+                       screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ch, nil, lineNumStyle)
                }
                vloc.X++
        }
 
        // Write the extra space
-       screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
+       screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, ' ', nil, lineNumStyle)
        vloc.X++
 }
 
@@ -342,7 +342,7 @@ func (w *BufWindow) showCursor(x, y int, main bool) {
                if main {
                        screen.ShowCursor(x, y)
                } else {
-                       screen.ShowFakeCursor(x, y)
+                       screen.ShowFakeCursorMulti(x, y)
                }
        }
 }
@@ -513,7 +513,7 @@ func (w *BufWindow) displayBuffer() {
                                        }
                                }
 
-                               screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, nil, style)
+                               screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, nil, style)
 
                                if showcursor {
                                        for _, c := range cursors {
@@ -591,7 +591,7 @@ func (w *BufWindow) displayBuffer() {
                                        curStyle = style.Background(fg)
                                }
                        }
-                       screen.Screen.SetContent(i+w.X, vloc.Y+w.Y, ' ', nil, curStyle)
+                       screen.SetContent(i+w.X, vloc.Y+w.Y, ' ', nil, curStyle)
                }
 
                draw(' ', curStyle, true)
@@ -617,7 +617,7 @@ func (w *BufWindow) displayStatusLine() {
        } else if w.Y+w.Height != infoY {
                w.drawStatus = true
                for x := w.X; x < w.X+w.Width; x++ {
-                       screen.Screen.SetContent(x, w.Y+w.Height-1, '-', nil, config.DefStyle.Reverse(true))
+                       screen.SetContent(x, w.Y+w.Height-1, '-', nil, config.DefStyle.Reverse(true))
                }
        } else {
                w.drawStatus = false
@@ -637,7 +637,7 @@ func (w *BufWindow) displayScrollBar() {
                }
                barstart := w.Y + int(float64(w.StartLine)/float64(w.Buf.LinesNum())*float64(w.Height))
                for y := barstart; y < util.Min(barstart+barsize, w.Y+bufHeight); y++ {
-                       screen.Screen.SetContent(scrollX, y, '|', nil, config.DefStyle.Reverse(true))
+                       screen.SetContent(scrollX, y, '|', nil, config.DefStyle.Reverse(true))
                }
        }
 }
index 45dc2c6569fb76a8bc4560ab6a5f5d9872e8c846..afc08f1d77e562e99436fafd1ef479ae418a6670 100644 (file)
@@ -74,7 +74,7 @@ func (i *InfoWindow) LocFromVisual(vloc buffer.Loc) buffer.Loc {
 
 func (i *InfoWindow) Clear() {
        for x := 0; x < i.Width; x++ {
-               screen.Screen.SetContent(x, i.Y, ' ', nil, i.defStyle())
+               screen.SetContent(x, i.Y, ' ', nil, i.defStyle())
        }
 }
 
@@ -111,7 +111,7 @@ func (i *InfoWindow) displayBuffer() {
                                if j > 0 {
                                        c = ' '
                                }
-                               screen.Screen.SetContent(vlocX, i.Y, c, nil, style)
+                               screen.SetContent(vlocX, i.Y, c, nil, style)
                        }
                        vlocX++
                }
@@ -167,9 +167,9 @@ func (i *InfoWindow) displayKeyMenu() {
        for y := 0; y < len(keydisplay); y++ {
                for x := 0; x < i.Width; x++ {
                        if x < len(keydisplay[y]) {
-                               screen.Screen.SetContent(x, i.Y-len(keydisplay)+y, rune(keydisplay[y][x]), nil, i.defStyle())
+                               screen.SetContent(x, i.Y-len(keydisplay)+y, rune(keydisplay[y][x]), nil, i.defStyle())
                        } else {
-                               screen.Screen.SetContent(x, i.Y-len(keydisplay)+y, ' ', nil, i.defStyle())
+                               screen.SetContent(x, i.Y-len(keydisplay)+y, ' ', nil, i.defStyle())
                        }
                }
        }
@@ -194,7 +194,7 @@ func (i *InfoWindow) Display() {
 
                display := i.Msg
                for _, c := range display {
-                       screen.Screen.SetContent(x, i.Y, c, nil, style)
+                       screen.SetContent(x, i.Y, c, nil, style)
                        x += runewidth.RuneWidth(c)
                }
 
@@ -219,13 +219,13 @@ func (i *InfoWindow) Display() {
                                style = style.Reverse(true)
                        }
                        for _, r := range s {
-                               screen.Screen.SetContent(x, i.Y-keymenuOffset-1, r, nil, style)
+                               screen.SetContent(x, i.Y-keymenuOffset-1, r, nil, style)
                                x++
                                if x >= i.Width {
                                        return
                                }
                        }
-                       screen.Screen.SetContent(x, i.Y-keymenuOffset-1, ' ', nil, statusLineStyle)
+                       screen.SetContent(x, i.Y-keymenuOffset-1, ' ', nil, statusLineStyle)
                        x++
                        if x >= i.Width {
                                return
@@ -233,7 +233,7 @@ func (i *InfoWindow) Display() {
                }
 
                for x < i.Width {
-                       screen.Screen.SetContent(x, i.Y-keymenuOffset-1, ' ', nil, statusLineStyle)
+                       screen.SetContent(x, i.Y-keymenuOffset-1, ' ', nil, statusLineStyle)
                        x++
                }
        }
index 0f40355fb0dd9c289830c3a9a5ccf2756e0b9c91..c139c8c6ab46f16af930fecc62b8f8632319a5a0 100644 (file)
@@ -118,13 +118,13 @@ func (s *StatusLine) Display() {
                                style = style.Reverse(true)
                        }
                        for _, r := range sug {
-                               screen.Screen.SetContent(x, y-keymenuOffset, r, nil, style)
+                               screen.SetContent(x, y-keymenuOffset, r, nil, style)
                                x++
                                if x >= s.win.Width {
                                        return
                                }
                        }
-                       screen.Screen.SetContent(x, y-keymenuOffset, ' ', nil, statusLineStyle)
+                       screen.SetContent(x, y-keymenuOffset, ' ', nil, statusLineStyle)
                        x++
                        if x >= s.win.Width {
                                return
@@ -132,7 +132,7 @@ func (s *StatusLine) Display() {
                }
 
                for x < s.win.Width {
-                       screen.Screen.SetContent(x, y-keymenuOffset, ' ', nil, statusLineStyle)
+                       screen.SetContent(x, y-keymenuOffset, ' ', nil, statusLineStyle)
                        x++
                }
                return
@@ -184,7 +184,7 @@ func (s *StatusLine) Display() {
                                        c = ' '
                                        x++
                                }
-                               screen.Screen.SetContent(winX+x, y, c, nil, statusLineStyle)
+                               screen.SetContent(winX+x, y, c, nil, statusLineStyle)
                        }
                } else if x >= s.win.Width-rightLen && x < rightLen+s.win.Width-rightLen {
                        r, size := utf8.DecodeRune(rightText)
@@ -196,10 +196,10 @@ func (s *StatusLine) Display() {
                                        c = ' '
                                        x++
                                }
-                               screen.Screen.SetContent(winX+x, y, c, nil, statusLineStyle)
+                               screen.SetContent(winX+x, y, c, nil, statusLineStyle)
                        }
                } else {
-                       screen.Screen.SetContent(winX+x, y, ' ', nil, statusLineStyle)
+                       screen.SetContent(winX+x, y, ' ', nil, statusLineStyle)
                }
        }
 }
index 3d25a42caa646b54e927e46049dd7c953727473f..d32ea6e1c6614c0d6355cc587f898bd1d0411446 100644 (file)
@@ -91,13 +91,13 @@ func (w *TabWindow) Display() {
                                        c = ' '
                                }
                                if x == w.width-1 && !done {
-                                       screen.Screen.SetContent(w.width-1, w.Y, '>', nil, config.DefStyle.Reverse(true))
+                                       screen.SetContent(w.width-1, w.Y, '>', nil, config.DefStyle.Reverse(true))
                                        x++
                                        break
                                } else if x == 0 && w.hscroll > 0 {
-                                       screen.Screen.SetContent(0, w.Y, '<', nil, config.DefStyle.Reverse(true))
+                                       screen.SetContent(0, w.Y, '<', nil, config.DefStyle.Reverse(true))
                                } else if x >= 0 && x < w.width {
-                                       screen.Screen.SetContent(x, w.Y, c, nil, config.DefStyle.Reverse(true))
+                                       screen.SetContent(x, w.Y, c, nil, config.DefStyle.Reverse(true))
                                }
                                x++
                        }
index 23ae1dbeb6789b39e016deea73919432705132f0..c7d82ecbc9eaf929e4eafdf6eda2ec863804fd86 100644 (file)
@@ -51,7 +51,7 @@ func (w *TermWindow) LocFromVisual(vloc buffer.Loc) buffer.Loc {
 func (w *TermWindow) Clear() {
        for y := 0; y < w.Height; y++ {
                for x := 0; x < w.Width; x++ {
-                       screen.Screen.SetContent(w.X+x, w.Y+y, ' ', nil, config.DefStyle)
+                       screen.SetContent(w.X+x, w.Y+y, ' ', nil, config.DefStyle)
                }
        }
 }
@@ -88,7 +88,7 @@ func (w *TermWindow) Display() {
                                st = st.Reverse(true)
                        }
 
-                       screen.Screen.SetContent(w.X+x, w.Y+y, c, nil, st)
+                       screen.SetContent(w.X+x, w.Y+y, c, nil, st)
                }
        }
        if config.GetGlobalOption("statusline").(bool) {
@@ -103,9 +103,9 @@ func (w *TermWindow) Display() {
                        if x < textLen {
                                r, size := utf8.DecodeRune(text)
                                text = text[size:]
-                               screen.Screen.SetContent(w.X+x, w.Y+w.Height, r, nil, statusLineStyle)
+                               screen.SetContent(w.X+x, w.Y+w.Height, r, nil, statusLineStyle)
                        } else {
-                               screen.Screen.SetContent(w.X+x, w.Y+w.Height, ' ', nil, statusLineStyle)
+                               screen.SetContent(w.X+x, w.Y+w.Height, ' ', nil, statusLineStyle)
                        }
                }
        }
index bb273ecc2c6e530d288a04c26bf569cb27bfda81..ff59718f2961be25ac07a7b9ff583a4c934b9d8a 100644 (file)
@@ -28,7 +28,7 @@ func (w *UIWindow) drawNode(n *views.Node) {
                if c.IsLeaf() && c.Kind == views.STVert {
                        if i != len(cs)-1 {
                                for h := 0; h < c.H; h++ {
-                                       screen.Screen.SetContent(c.X+c.W, c.Y+h, '|', nil, dividerStyle.Reverse(true))
+                                       screen.SetContent(c.X+c.W, c.Y+h, '|', nil, dividerStyle.Reverse(true))
                                }
                        }
                } else {
index cca9036d6c0e35534b958f191fdbbf5e96e667d3..f9ab1bd8878dd6a7ca29140aaf3e98f2139ea24d 100644 (file)
@@ -17,26 +17,66 @@ 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)
@@ -45,6 +85,17 @@ func ShowCursor(x, y int) {
        }
 }
 
+// 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
index 9bc3f7e1f6df1f9ad51584db839968a3127dd1e7..c3624bab8bf7eadbc6e762208b5e21cdfbb749e6 100644 (file)
@@ -33,7 +33,7 @@ var (
        Debug = "ON"
        // FakeCursor is used to disable the terminal cursor and have micro
        // draw its own (enabled for windows consoles where the cursor is slow)
-       FakeCursor = true
+       FakeCursor = false
 )
 
 func init() {