Add better matchbrace

This commit is contained in:
Zachary Yedidia 2019-08-04 15:11:09 -07:00
parent f39a916e5f
commit d1e713ce08
6 changed files with 73 additions and 23 deletions

View File

@ -933,9 +933,14 @@ func (h *BufPane) paste(clip string) {
func (h *BufPane) JumpToMatchingBrace() bool {
for _, bp := range buffer.BracePairs {
r := h.Cursor.RuneUnder(h.Cursor.X)
if r == bp[0] || r == bp[1] {
matchingBrace := h.Buf.FindMatchingBrace(bp, h.Cursor.Loc)
h.Cursor.GotoLoc(matchingBrace)
rl := h.Cursor.RuneUnder(h.Cursor.X - 1)
if r == bp[0] || r == bp[1] || rl == bp[0] || rl == bp[1] {
matchingBrace, left := h.Buf.FindMatchingBrace(bp, h.Cursor.Loc)
if left {
h.Cursor.GotoLoc(matchingBrace)
} else {
h.Cursor.GotoLoc(matchingBrace.Move(1, h.Buf))
}
}
}

View File

@ -651,16 +651,30 @@ var BracePairs = [][2]rune{
// It is given a brace type containing the open and closing character, (for example
// '{' and '}') as well as the location to match from
// TODO: maybe can be more efficient with utf8 package
func (b *Buffer) FindMatchingBrace(braceType [2]rune, start Loc) Loc {
// returns the location of the matching brace
// if the boolean returned is true then the original matching brace is one character left
// of the starting location
func (b *Buffer) FindMatchingBrace(braceType [2]rune, start Loc) (Loc, bool) {
curLine := []rune(string(b.LineBytes(start.Y)))
startChar := curLine[start.X]
startChar := ' '
if start.X >= 0 && start.X < len(curLine) {
startChar = curLine[start.X]
}
leftChar := ' '
if start.X-1 >= 0 && start.X-1 < len(curLine) {
leftChar = curLine[start.X-1]
}
var i int
if startChar == braceType[0] {
if startChar == braceType[0] || leftChar == braceType[0] {
for y := start.Y; y < b.LinesNum(); y++ {
l := []rune(string(b.LineBytes(y)))
xInit := 0
if y == start.Y {
xInit = start.X
if startChar == braceType[0] {
xInit = start.X
} else {
xInit = start.X - 1
}
}
for x := xInit; x < len(l); x++ {
r := l[x]
@ -669,24 +683,34 @@ func (b *Buffer) FindMatchingBrace(braceType [2]rune, start Loc) Loc {
} else if r == braceType[1] {
i--
if i == 0 {
return Loc{x, y}
if startChar == braceType[0] {
return Loc{x, y}, false
}
return Loc{x, y}, true
}
}
}
}
} else if startChar == braceType[1] {
} else if startChar == braceType[1] || leftChar == 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
if leftChar == braceType[1] {
xInit = start.X - 1
} else {
xInit = start.X
}
}
for x := xInit; x >= 0; x-- {
r := l[x]
if r == braceType[0] {
i--
if i == 0 {
return Loc{x, y}
if leftChar == braceType[1] {
return Loc{x, y}, true
}
return Loc{x, y}, false
}
} else if r == braceType[1] {
i++
@ -694,7 +718,7 @@ func (b *Buffer) FindMatchingBrace(braceType [2]rune, start Loc) Loc {
}
}
}
return start
return start, true
}
// Retab changes all tabs to spaces or vice versa

File diff suppressed because one or more lines are too long

View File

@ -162,8 +162,7 @@ var defaultCommonSettings = map[string]interface{}{
"ignorecase": false,
"indentchar": " ",
"keepautoindent": false,
"matchbrace": false,
"matchbraceleft": false,
"matchbrace": true,
"mkparents": false,
"readonly": false,
"rmtrailingws": false,

View File

@ -381,6 +381,27 @@ func (w *BufWindow) displayBuffer() {
b.Highlighter.HighlightMatches(b, w.StartLine, w.StartLine+bufHeight)
}
var matchingBraces []buffer.Loc
// bracePairs is defined in buffer.go
if b.Settings["matchbrace"].(bool) {
for _, bp := range buffer.BracePairs {
for _, c := range b.GetCursors() {
if c.HasSelection() {
continue
}
curX := c.X
curLoc := c.Loc
r := c.RuneUnder(curX)
rl := c.RuneUnder(curX - 1)
if r == bp[0] || r == bp[1] || rl == bp[0] || rl == bp[1] {
mb, _ := b.FindMatchingBrace(bp, curLoc)
matchingBraces = append(matchingBraces, mb)
}
}
}
}
lineNumStyle := config.DefStyle
if style, ok := config.Colorscheme["line-number"]; ok {
lineNumStyle = style
@ -477,6 +498,12 @@ func (w *BufWindow) displayBuffer() {
}
}
for _, mb := range matchingBraces {
if mb.X == bloc.X && mb.Y == bloc.Y {
style = style.Underline(true)
}
}
screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, nil, style)
if showcursor {

View File

@ -115,15 +115,10 @@ Here are the options that you can set:
default value: `false`
* `matchbrace`: highlight matching braces for '()', '{}', '[]'
* `matchbrace`: underline matching braces for '()', '{}', '[]' when the cursor
is on a brace character.
default value: `false`
* `matchbraceleft`: when matching a closing brace, should matching match the
brace directly under the cursor, or the character to the left? only matters
if `matchbrace` is true
default value: `false`
default value: `true`
* `mkparents`: if a file is opened on a path that does not exist, the file cannot
be saved because the parent directories don't exist. This option lets micro