mirror of
https://github.com/zyedidia/micro.git
synced 2025-06-20 07:45:35 -04:00
Add better matchbrace
This commit is contained in:
parent
f39a916e5f
commit
d1e713ce08
@ -933,9 +933,14 @@ func (h *BufPane) paste(clip string) {
|
|||||||
func (h *BufPane) JumpToMatchingBrace() bool {
|
func (h *BufPane) JumpToMatchingBrace() bool {
|
||||||
for _, bp := range buffer.BracePairs {
|
for _, bp := range buffer.BracePairs {
|
||||||
r := h.Cursor.RuneUnder(h.Cursor.X)
|
r := h.Cursor.RuneUnder(h.Cursor.X)
|
||||||
if r == bp[0] || r == bp[1] {
|
rl := h.Cursor.RuneUnder(h.Cursor.X - 1)
|
||||||
matchingBrace := h.Buf.FindMatchingBrace(bp, h.Cursor.Loc)
|
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)
|
h.Cursor.GotoLoc(matchingBrace)
|
||||||
|
} else {
|
||||||
|
h.Cursor.GotoLoc(matchingBrace.Move(1, h.Buf))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,16 +651,30 @@ var BracePairs = [][2]rune{
|
|||||||
// It is given a brace type containing the open and closing character, (for example
|
// It is given a brace type containing the open and closing character, (for example
|
||||||
// '{' and '}') as well as the location to match from
|
// '{' and '}') as well as the location to match from
|
||||||
// TODO: maybe can be more efficient with utf8 package
|
// 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)))
|
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
|
var i int
|
||||||
if startChar == braceType[0] {
|
if startChar == braceType[0] || leftChar == braceType[0] {
|
||||||
for y := start.Y; y < b.LinesNum(); y++ {
|
for y := start.Y; y < b.LinesNum(); y++ {
|
||||||
l := []rune(string(b.LineBytes(y)))
|
l := []rune(string(b.LineBytes(y)))
|
||||||
xInit := 0
|
xInit := 0
|
||||||
if y == start.Y {
|
if y == start.Y {
|
||||||
|
if startChar == braceType[0] {
|
||||||
xInit = start.X
|
xInit = start.X
|
||||||
|
} else {
|
||||||
|
xInit = start.X - 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for x := xInit; x < len(l); x++ {
|
for x := xInit; x < len(l); x++ {
|
||||||
r := l[x]
|
r := l[x]
|
||||||
@ -669,24 +683,34 @@ func (b *Buffer) FindMatchingBrace(braceType [2]rune, start Loc) Loc {
|
|||||||
} else if r == braceType[1] {
|
} else if r == braceType[1] {
|
||||||
i--
|
i--
|
||||||
if i == 0 {
|
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-- {
|
for y := start.Y; y >= 0; y-- {
|
||||||
l := []rune(string(b.lines[y].data))
|
l := []rune(string(b.lines[y].data))
|
||||||
xInit := len(l) - 1
|
xInit := len(l) - 1
|
||||||
if y == start.Y {
|
if y == start.Y {
|
||||||
|
if leftChar == braceType[1] {
|
||||||
|
xInit = start.X - 1
|
||||||
|
} else {
|
||||||
xInit = start.X
|
xInit = start.X
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for x := xInit; x >= 0; x-- {
|
for x := xInit; x >= 0; x-- {
|
||||||
r := l[x]
|
r := l[x]
|
||||||
if r == braceType[0] {
|
if r == braceType[0] {
|
||||||
i--
|
i--
|
||||||
if i == 0 {
|
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] {
|
} else if r == braceType[1] {
|
||||||
i++
|
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
|
// Retab changes all tabs to spaces or vice versa
|
||||||
|
File diff suppressed because one or more lines are too long
@ -162,8 +162,7 @@ var defaultCommonSettings = map[string]interface{}{
|
|||||||
"ignorecase": false,
|
"ignorecase": false,
|
||||||
"indentchar": " ",
|
"indentchar": " ",
|
||||||
"keepautoindent": false,
|
"keepautoindent": false,
|
||||||
"matchbrace": false,
|
"matchbrace": true,
|
||||||
"matchbraceleft": false,
|
|
||||||
"mkparents": false,
|
"mkparents": false,
|
||||||
"readonly": false,
|
"readonly": false,
|
||||||
"rmtrailingws": false,
|
"rmtrailingws": false,
|
||||||
|
@ -381,6 +381,27 @@ func (w *BufWindow) displayBuffer() {
|
|||||||
b.Highlighter.HighlightMatches(b, w.StartLine, w.StartLine+bufHeight)
|
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
|
lineNumStyle := config.DefStyle
|
||||||
if style, ok := config.Colorscheme["line-number"]; ok {
|
if style, ok := config.Colorscheme["line-number"]; ok {
|
||||||
lineNumStyle = style
|
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)
|
screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, nil, style)
|
||||||
|
|
||||||
if showcursor {
|
if showcursor {
|
||||||
|
@ -115,15 +115,10 @@ Here are the options that you can set:
|
|||||||
|
|
||||||
default value: `false`
|
default value: `false`
|
||||||
|
|
||||||
* `matchbrace`: highlight matching braces for '()', '{}', '[]'
|
* `matchbrace`: underline matching braces for '()', '{}', '[]' when the cursor
|
||||||
|
is on a brace character.
|
||||||
|
|
||||||
default value: `false`
|
default value: `true`
|
||||||
|
|
||||||
* `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`
|
|
||||||
|
|
||||||
* `mkparents`: if a file is opened on a path that does not exist, the file cannot
|
* `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
|
be saved because the parent directories don't exist. This option lets micro
|
||||||
|
Loading…
Reference in New Issue
Block a user