@@ -1141,7 +1141,8 @@ var BracePairs = [][2]rune{
11411141 {'[' , ']' },
11421142}
11431143
1144- func (b * Buffer ) getSortedSyntaxIndices (lineN int ) []int {
1144+ // Returns the indices of syntax groups in ascending order
1145+ func (b * Buffer ) GetSortedSyntaxGroupIndices (lineN int ) []int {
11451146 keys := make ([]int , 0 , len (b .Match (lineN )))
11461147 for k := range b .Match (lineN ) {
11471148 keys = append (keys , k )
@@ -1151,9 +1152,13 @@ func (b *Buffer) getSortedSyntaxIndices(lineN int) []int {
11511152}
11521153
11531154// Returns the Group (syntax highlight group ID) at the specified location and a boolean
1154- // that indicates if a group is found or not
1155- func (b * Buffer ) GetGroupAtLoc (loc Loc ) (highlight.Group , bool ) {
1156- sortedIndices := b .getSortedSyntaxIndices (loc .Y )
1155+ // that indicates if a group is found or not.
1156+ // This optionally accepts sorted Group indices returned from GetSortedSyntaxGroupIndices()
1157+ // which can be reused on the same line.
1158+ func (b * Buffer ) GetGroupAtLoc (loc Loc , sortedIndices []int ) (highlight.Group , bool ) {
1159+ if sortedIndices == nil {
1160+ sortedIndices = b .GetSortedSyntaxGroupIndices (loc .Y )
1161+ }
11571162 i := sort .SearchInts (sortedIndices , loc .X )
11581163 if i == 0 || i == len (sortedIndices ) {
11591164 return 0 , false
@@ -1164,61 +1169,112 @@ func (b *Buffer) GetGroupAtLoc(loc Loc) (highlight.Group, bool) {
11641169 return b .Match (loc .Y )[sortedIndices [i - 1 ]], true
11651170}
11661171
1167- func (b * Buffer ) isLocInStringOrComment (loc Loc ) bool {
1168- g , gFound := b .GetGroupAtLoc (loc )
1172+ func (b * Buffer ) isLocInStringOrComment (loc Loc , sortedIndices [] int ) bool {
1173+ g , gFound := b .GetGroupAtLoc (loc , sortedIndices )
11691174 if gFound && (g .String () == "constant.string" || strings .Contains (g .String (), "comment" )) {
11701175 return true
11711176 }
11721177 return false
11731178}
11741179
1175- func (b * Buffer ) findMatchingBrace (braceType [2 ]rune , start Loc , char rune ) (Loc , bool ) {
1176- if b .isLocInStringOrComment (start ) {
1177- return start , false
1178- }
1180+ func (b * Buffer ) FindOpeningBrace (braceType [2 ]rune , start Loc ) (Loc , bool ) {
1181+ startChar := []rune (string (b .LineBytes (start .Y )))[start .X ]
11791182 var i int
1180- if char == braceType [0 ] {
1181- for y := start .Y ; y < b .LinesNum (); y ++ {
1182- l := []rune (string (b .LineBytes (y )))
1183- xInit := 0
1184- if y == start .Y {
1185- xInit = start .X
1186- }
1187- for x := xInit ; x < len (l ); x ++ {
1188- r := l [x ]
1189- if r == braceType [0 ] && ! b .isLocInStringOrComment (Loc {x , y }) {
1183+ if startChar == braceType [1 ] {
1184+ i = 0
1185+ } else {
1186+ i = 1
1187+ }
1188+ for y := start .Y ; y >= 0 ; y -- {
1189+ var sortedGroups []int
1190+ sortedGroupsPopulated := false
1191+ l := []rune (string (b .lines [y ].data ))
1192+ xInit := len (l ) - 1
1193+ if y == start .Y {
1194+ xInit = start .X
1195+ }
1196+ for x := xInit ; x >= 0 ; x -- {
1197+ r := l [x ]
1198+ if r == braceType [1 ] {
1199+ if ! sortedGroupsPopulated {
1200+ sortedGroups = b .GetSortedSyntaxGroupIndices (y )
1201+ sortedGroupsPopulated = true
1202+ }
1203+ if ! b .isLocInStringOrComment (Loc {x , y }, sortedGroups ) {
11901204 i ++
1191- } else if r == braceType [1 ] && ! b .isLocInStringOrComment (Loc {x , y }) {
1205+ }
1206+ } else if r == braceType [0 ]{
1207+ if ! sortedGroupsPopulated {
1208+ sortedGroups = b .GetSortedSyntaxGroupIndices (y )
1209+ sortedGroupsPopulated = true
1210+ }
1211+ if ! b .isLocInStringOrComment (Loc {x , y }, sortedGroups ) {
11921212 i --
1193- if i == 0 {
1194- return Loc { x , y }, true
1195- }
1213+ }
1214+ if i == 0 {
1215+ return Loc { x , y }, true
11961216 }
11971217 }
11981218 }
1199- } else if char == braceType [1 ] {
1200- for y := start .Y ; y >= 0 ; y -- {
1201- l := []rune (string (b .lines [y ].data ))
1202- xInit := len (l ) - 1
1203- if y == start .Y {
1204- xInit = start .X
1205- }
1206- for x := xInit ; x >= 0 ; x -- {
1207- r := l [x ]
1208- if r == braceType [1 ] && ! b .isLocInStringOrComment (Loc {x , y }){
1219+ }
1220+ return start , false
1221+ }
1222+
1223+ func (b * Buffer ) FindClosingBrace (braceType [2 ]rune , start Loc ) (Loc , bool ) {
1224+ startChar := []rune (string (b .LineBytes (start .Y )))[start .X ]
1225+ var i int
1226+ if startChar == braceType [0 ] {
1227+ i = 0
1228+ } else {
1229+ i = 1
1230+ }
1231+ for y := start .Y ; y < b .LinesNum (); y ++ {
1232+ var sortedGroups []int
1233+ sortedGroupsPopulated := false
1234+ l := []rune (string (b .LineBytes (y )))
1235+ xInit := 0
1236+ if y == start .Y {
1237+ xInit = start .X
1238+ }
1239+ for x := xInit ; x < len (l ); x ++ {
1240+ r := l [x ]
1241+ if r == braceType [0 ] {
1242+ if ! sortedGroupsPopulated {
1243+ sortedGroups = b .GetSortedSyntaxGroupIndices (y )
1244+ sortedGroupsPopulated = true
1245+ }
1246+ if ! b .isLocInStringOrComment (Loc {x , y }, sortedGroups ) {
12091247 i ++
1210- } else if r == braceType [0 ] && ! b .isLocInStringOrComment (Loc {x , y }){
1248+ }
1249+ } else if r == braceType [1 ] {
1250+ if ! sortedGroupsPopulated {
1251+ sortedGroups = b .GetSortedSyntaxGroupIndices (y )
1252+ sortedGroupsPopulated = true
1253+ }
1254+ if ! b .isLocInStringOrComment (Loc {x , y }, sortedGroups ) {
12111255 i --
1212- if i == 0 {
1213- return Loc { x , y }, true
1214- }
1256+ }
1257+ if i == 0 {
1258+ return Loc { x , y }, true
12151259 }
12161260 }
12171261 }
12181262 }
12191263 return start , false
12201264}
12211265
1266+ func (b * Buffer ) findMatchingBrace (braceType [2 ]rune , start Loc , char rune ) (Loc , bool ) {
1267+ if b .isLocInStringOrComment (start , nil ) {
1268+ return start , false
1269+ }
1270+ if char == braceType [0 ] {
1271+ return b .FindClosingBrace (braceType , start )
1272+ } else if char == braceType [1 ] {
1273+ return b .FindOpeningBrace (braceType , start )
1274+ }
1275+ return start , false
1276+ }
1277+
12221278// If there is a brace character (for example '{' or ']') at the given start location,
12231279// FindMatchingBrace returns the location of the matching brace for it (for example '}'
12241280// or '['). The second returned value is true if there was no matching brace found
0 commit comments