mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-17 06:17:12 +09:00
Add gutter message drawing and better cursor locating
This commit is contained in:
@@ -45,14 +45,16 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
|
||||
softwrap := buf.Settings["softwrap"].(bool)
|
||||
indentchar := []rune(buf.Settings["indentchar"].(string))[0]
|
||||
|
||||
if len(c.lines) != height {
|
||||
c.lines = make([][]*Char, height)
|
||||
}
|
||||
c.lines = make([][]*Char, 0)
|
||||
|
||||
viewLine := 0
|
||||
lineN := top
|
||||
|
||||
for viewLine < height {
|
||||
if lineN >= len(buf.lines) {
|
||||
break
|
||||
}
|
||||
|
||||
lineStr := string(buf.lines[lineN])
|
||||
line := []rune(lineStr)
|
||||
|
||||
@@ -62,9 +64,7 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
|
||||
// We'll either draw the length of the line, or the width of the screen
|
||||
// whichever is smaller
|
||||
lineLength := min(StringWidth(lineStr, tabsize), width)
|
||||
if len(c.lines[viewLine]) != lineLength {
|
||||
c.lines[viewLine] = make([]*Char, lineLength)
|
||||
}
|
||||
c.lines = append(c.lines, make([]*Char, lineLength))
|
||||
|
||||
wrap := false
|
||||
// We only need to wrap if the length of the line is greater than the width of the terminal screen
|
||||
|
||||
@@ -45,15 +45,78 @@ func (v *View) DisplayView() {
|
||||
v.cellview.Draw(v.Buf, top, height, left, width)
|
||||
|
||||
screenX := v.x
|
||||
for lineN, line := range v.cellview.lines {
|
||||
realLineN := top - 1
|
||||
for visualLineN, line := range v.cellview.lines {
|
||||
var firstChar *Char
|
||||
if len(line) > 0 {
|
||||
firstChar = line[0]
|
||||
}
|
||||
|
||||
var softwrapped bool
|
||||
if firstChar != nil {
|
||||
if firstChar.realLoc.Y == realLineN {
|
||||
softwrapped = true
|
||||
}
|
||||
realLineN = firstChar.realLoc.Y
|
||||
} else {
|
||||
realLineN++
|
||||
}
|
||||
|
||||
screenX = v.x
|
||||
curLineN := v.Topline + lineN
|
||||
|
||||
if v.x != 0 {
|
||||
// Draw the split divider
|
||||
screen.SetContent(screenX, lineN, '|', nil, defStyle.Reverse(true))
|
||||
screen.SetContent(screenX, visualLineN, '|', nil, defStyle.Reverse(true))
|
||||
screenX++
|
||||
}
|
||||
|
||||
// If there are gutter messages we need to display the '>>' symbol here
|
||||
if hasGutterMessages {
|
||||
// msgOnLine stores whether or not there is a gutter message on this line in particular
|
||||
msgOnLine := false
|
||||
for k := range v.messages {
|
||||
for _, msg := range v.messages[k] {
|
||||
if msg.lineNum == realLineN {
|
||||
msgOnLine = true
|
||||
gutterStyle := defStyle
|
||||
switch msg.kind {
|
||||
case GutterInfo:
|
||||
if style, ok := colorscheme["gutter-info"]; ok {
|
||||
gutterStyle = style
|
||||
}
|
||||
case GutterWarning:
|
||||
if style, ok := colorscheme["gutter-warning"]; ok {
|
||||
gutterStyle = style
|
||||
}
|
||||
case GutterError:
|
||||
if style, ok := colorscheme["gutter-error"]; ok {
|
||||
gutterStyle = style
|
||||
}
|
||||
}
|
||||
v.drawCell(screenX, visualLineN, '>', nil, gutterStyle)
|
||||
screenX++
|
||||
v.drawCell(screenX, visualLineN, '>', nil, gutterStyle)
|
||||
screenX++
|
||||
if v.Cursor.Y == realLineN && !messenger.hasPrompt {
|
||||
messenger.Message(msg.msg)
|
||||
messenger.gutterMessage = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there is no message on this line we just display an empty offset
|
||||
if !msgOnLine {
|
||||
v.drawCell(screenX, visualLineN, ' ', nil, defStyle)
|
||||
screenX++
|
||||
v.drawCell(screenX, visualLineN, ' ', nil, defStyle)
|
||||
screenX++
|
||||
if v.Cursor.Y == realLineN && messenger.gutterMessage {
|
||||
messenger.Reset()
|
||||
messenger.gutterMessage = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lineNumStyle := defStyle
|
||||
if v.Buf.Settings["ruler"] == true {
|
||||
// Write the line number
|
||||
@@ -61,26 +124,34 @@ func (v *View) DisplayView() {
|
||||
lineNumStyle = style
|
||||
}
|
||||
if style, ok := colorscheme["current-line-number"]; ok {
|
||||
if curLineN == v.Cursor.Y && tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() {
|
||||
if realLineN == v.Cursor.Y && tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() {
|
||||
lineNumStyle = style
|
||||
}
|
||||
}
|
||||
|
||||
lineNum := strconv.Itoa(curLineN + 1)
|
||||
lineNum := strconv.Itoa(realLineN + 1)
|
||||
|
||||
// Write the spaces before the line number if necessary
|
||||
for i := 0; i < maxLineNumLength-len(lineNum); i++ {
|
||||
screen.SetContent(screenX, lineN, ' ', nil, lineNumStyle)
|
||||
screen.SetContent(screenX, visualLineN, ' ', nil, lineNumStyle)
|
||||
screenX++
|
||||
}
|
||||
// Write the actual line number
|
||||
for _, ch := range lineNum {
|
||||
screen.SetContent(screenX, lineN, ch, nil, lineNumStyle)
|
||||
screenX++
|
||||
if softwrapped && visualLineN != 0 {
|
||||
// Pad without the line number because it was written on the visual line before
|
||||
for range lineNum {
|
||||
screen.SetContent(screenX, visualLineN, ' ', nil, lineNumStyle)
|
||||
screenX++
|
||||
}
|
||||
} else {
|
||||
// Write the actual line number
|
||||
for _, ch := range lineNum {
|
||||
screen.SetContent(screenX, visualLineN, ch, nil, lineNumStyle)
|
||||
screenX++
|
||||
}
|
||||
}
|
||||
|
||||
// Write the extra space
|
||||
screen.SetContent(screenX, lineN, ' ', nil, lineNumStyle)
|
||||
screen.SetContent(screenX, visualLineN, ' ', nil, lineNumStyle)
|
||||
screenX++
|
||||
}
|
||||
|
||||
@@ -105,8 +176,8 @@ func (v *View) DisplayView() {
|
||||
}
|
||||
} else if len(line) == 0 {
|
||||
if tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() &&
|
||||
v.Cursor.Y == curLineN {
|
||||
screen.ShowCursor(xOffset, lineN)
|
||||
v.Cursor.Y == realLineN {
|
||||
screen.ShowCursor(xOffset, visualLineN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user