Add brace highlighting

Use the 'matchbrace' option which is off by default.

Ref #853
This commit is contained in:
Zachary Yedidia 2018-01-07 15:50:08 -05:00
parent 0b47502e62
commit 86c08bd747
3 changed files with 74 additions and 1 deletions

View file

@ -630,3 +630,58 @@ func (b *Buffer) clearCursors() {
b.UpdateCursors()
b.Cursor.ResetSelection()
}
var bracePairs = [][2]rune{
[2]rune{'(', ')'},
[2]rune{'{', '}'},
[2]rune{'[', ']'},
}
// FindMatchingBrace returns the location in the buffer of the matching bracket
// It is given a brace type containing the open and closing character, (for example
// '{' and '}') as well as the location to match from
func (b *Buffer) FindMatchingBrace(braceType [2]rune, start Loc) Loc {
curLine := []rune(string(b.lines[start.Y].data))
startChar := curLine[start.X]
var i int
if startChar == braceType[0] {
for y := start.Y; y < b.NumLines; y++ {
l := []rune(string(b.lines[y].data))
xInit := 0
if y == start.Y {
xInit = start.X
}
for x := xInit; x < len(l); x++ {
r := l[x]
if r == braceType[0] {
i++
} else if r == braceType[1] {
i--
if i == 0 {
return Loc{x, y}
}
}
}
}
} else if startChar == braceType[1] {
for y := start.Y; y >= 0; y-- {
l := []rune(string(b.lines[y].data))
xInit := len(l) - 1
if y == start.Y {
xInit = start.X
}
for x := xInit; x >= 0; x-- {
r := l[x]
if r == braceType[0] {
i--
if i == 0 {
return Loc{x, y}
}
} else if r == braceType[1] {
i++
}
}
}
}
return start
}

View file

@ -69,6 +69,17 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
return
}
matchingBrace := Loc{-1, -1}
// bracePairs is defined in buffer.go
if buf.Settings["matchbrace"].(bool) {
for _, bp := range bracePairs {
r := buf.Cursor.RuneUnder(buf.Cursor.X)
if r == bp[0] || r == bp[1] {
matchingBrace = buf.FindMatchingBrace(bp, buf.Cursor.Loc)
}
}
}
tabsize := int(buf.Settings["tabsize"].(float64))
softwrap := buf.Settings["softwrap"].(bool)
indentrunes := []rune(buf.Settings["indentchar"].(string))
@ -137,7 +148,12 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
char := line[colN]
if viewCol >= 0 {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle, 1}
st := curStyle
if colN == matchingBrace.X && lineN == matchingBrace.Y {
messenger.Message(matchingBrace)
st = curStyle.Reverse(true)
}
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, st, 1}
}
if char == '\t' {
charWidth := tabsize - (viewCol+left)%tabsize

View file

@ -214,6 +214,7 @@ func DefaultGlobalSettings() map[string]interface{} {
"infobar": true,
"keepautoindent": false,
"keymenu": false,
"matchbrace": false,
"mouse": true,
"pluginchannels": []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"},
"pluginrepos": []string{},
@ -255,6 +256,7 @@ func DefaultLocalSettings() map[string]interface{} {
"ignorecase": false,
"indentchar": " ",
"keepautoindent": false,
"matchbrace": false,
"rmtrailingws": false,
"ruler": true,
"savecursor": false,