I believe Regex will not help you here - in this case, it will probably be slower, since it still has to go through the code char by char.
However, there is a "simple" solution - create a tree of all the code blocks in the code, and update it as needed when the user changes the code (ideally, not on every keypress, but if done well, even that is an option). Then you no longer have to find the next bracket every time you move the cursor - you know in which code block you are (simple lookup by index), and you know immediately where the starting and ending bracket of the code is.
The approach assumes that updating the block indices is easy - and really, it kind of is; if the block is before the cursor as it updates, don't change it. If it's after the cursor, add numberOfCharsInserted
to all the indices. Simple and fast. It becomes tricky as you add and remove new blocks of code, but that gives Visual Studio trouble as well :))
Another interesting solution might be a variant of "space partitioning". Split the code into sections you can easily index (for example, a binary tree or a hash table). If you remember the number of opening and closing brackets in each of these sections, you can quite quickly determine where the bracket you're looking for is located, and based on the section granularity, you can significantly reduce the are you have to search.
There's a lot of ways to optimize searching, but at some point, you simply have to go through the file from start to end. Based on typical use-cases, you have to choose the proper way. In this case, I believe simply remembering the indices of all brackets in the file will be by far the easiest solution, and it's pretty fast (How many characters are brackets out of the code? Adding 1
to a hundred indices is a lot faster than searching through a thousand chars. And you only have to do it while changing the code!). Although you did say LISP, didn't you? That could be a lot of brackets! :D