Skip to content

Commit

Permalink
Add matchbraceleft option (#3432)
Browse files Browse the repository at this point in the history
Add `matchbraceleft` option to allow disabling the default behavior
matching not just the brace under cursor but also the brace to the left
of it (which is arguably convenient, but also ambiguous and
non-intuitive). With `matchbraceleft` disabled, micro will only match
the brace character that is precisely under the cursor, and also when
jumping to the matching brace, will always move cursor precisely to the
matching brace character, not to the character next to it.

Nota bene: historical journey:

- There was already a `matchbraceleft` option introduced in commit
  ea6a87d, when this feature (matching brace to the left) was
  introduced first time. That time it was matching _only_ the brace
  to the left, _instead_ of the brace under the cursor, and was
  disabled by default.

- Later this feature was removed during the big refactoring of micro.

- Then this feature was reintroduced again in commit d1e713c, in
  its present form (i.e. combined brace matching both under the cursor
  and to the left, simulating I-beam cursor behavior), and it was
  introduced unconditionally, without an option to disable it.

- Since then, multiple users complained about this feature and asked
  for an option to disable it, so now we are reintroducing it as an
  option again (this time enabled by default though).
  • Loading branch information
dmaluka committed Aug 18, 2024
1 parent f88ac6d commit fd3a002
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
10 changes: 7 additions & 3 deletions internal/action/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1472,10 +1472,14 @@ func (h *BufPane) paste(clip string) {
func (h *BufPane) JumpToMatchingBrace() bool {
matchingBrace, left, found := h.Buf.FindMatchingBrace(h.Cursor.Loc)
if found {
if left {
h.Cursor.GotoLoc(matchingBrace)
if h.Buf.Settings["matchbraceleft"].(bool) {
if left {
h.Cursor.GotoLoc(matchingBrace)
} else {
h.Cursor.GotoLoc(matchingBrace.Move(1, h.Buf))
}
} else {
h.Cursor.GotoLoc(matchingBrace.Move(1, h.Buf))
h.Cursor.GotoLoc(matchingBrace)
}
h.Relocate()
return true
Expand Down
24 changes: 13 additions & 11 deletions internal/buffer/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -1193,17 +1193,19 @@ func (b *Buffer) FindMatchingBrace(start Loc) (Loc, bool, bool) {
}
}

// failed to find matching brace for the given location, so try to find matching
// brace for the location one character left of it
if start.X-1 >= 0 && start.X-1 < len(curLine) {
leftChar := curLine[start.X-1]
left := Loc{start.X - 1, start.Y}

for _, bp := range BracePairs {
if leftChar == bp[0] || leftChar == bp[1] {
mb, found := b.findMatchingBrace(bp, left, leftChar)
if found {
return mb, true, true
if b.Settings["matchbraceleft"].(bool) {
// failed to find matching brace for the given location, so try to find matching
// brace for the location one character left of it
if start.X-1 >= 0 && start.X-1 < len(curLine) {
leftChar := curLine[start.X-1]
left := Loc{start.X - 1, start.Y}

for _, bp := range BracePairs {
if leftChar == bp[0] || leftChar == bp[1] {
mb, found := b.findMatchingBrace(bp, left, leftChar)
if found {
return mb, true, true
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions internal/config/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ var defaultCommonSettings = map[string]interface{}{
"indentchar": " ",
"keepautoindent": false,
"matchbrace": true,
"matchbraceleft": true,
"matchbracestyle": "underline",
"mkparents": false,
"permbackup": false,
Expand Down
15 changes: 14 additions & 1 deletion runtime/help/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,19 @@ Here are the available options:
default value: `false`

* `matchbrace`: show matching braces for '()', '{}', '[]' when the cursor
is on a brace character or next to it.
is on a brace character or (if `matchbraceleft` is enabled) next to it.

default value: `true`

* `matchbraceleft`: simulate I-beam cursor behavior (cursor located not on a
character but "between" characters): when showing matching braces, if there
is no brace character directly under the cursor, match the brace character
to the left of the cursor instead. Also when jumping to the matching brace,
move the cursor either to the matching brace character or to the character
next to it, depending on whether the initial cursor position was on the
brace character or next to it (i.e. "inside" or "outside" the braces).
With `matchbraceleft` disabled, micro will only match the brace directly
under the cursor and will only jump to precisely to the matching brace.

default value: `true`

Expand Down Expand Up @@ -526,6 +538,7 @@ so that you can see what the formatting should look like.
"linter": true,
"literate": true,
"matchbrace": true,
"matchbraceleft": true,
"matchbracestyle": "underline",
"mkparents": false,
"mouse": true,
Expand Down

0 comments on commit fd3a002

Please sign in to comment.