Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Matchit support for the C family of languages #488

Merged
merged 7 commits into from Apr 7, 2022

Conversation

myzeiri
Copy link
Contributor

@myzeiri myzeiri commented Apr 5, 2022

Following up on #343, this PR adds Matchit support for the C family of languages. The plugin now supports jumps on C-style preprocessor directives (found in C, C++, C#, ObjC), Makefiles, and CMake files.

I also refactored the code to be simpler and to make language configuration easier. Sorry for the large diff though! The changes are split into distinct commits with more detailed notes in the commit messages.
To sum up, I:

  • Simplified the search code in findClosingPair() and findOpeningPair()
  • Refactored parsePatternAtOffset() to return both the pattern start and end offsets
    • This is was necessary to support the else if conditional in Makefiles
  • Created the LanguagePatterns class to make language configuration easy
    • The new languages in this PR were configured just by calling that class's constructor

Thank you in advance for your time.

findClosingPair() always moves forward and findOpeningPair() always
moves backwards. That fact lets us simplify both implementations.

Using a stack of Pairs to track the match starts and ends is unnecessary 
since we know ahead of time whether the jump needs to go to the start or
end of the target pair.

findOpeningPair() can be further simplified since it doesn't need to
check the isInOpPending flag -- the distinction between operator pending
mode and regular jumps only matters when moving forward in the buffer.
The ending offset of the initial match isn't enough information for some
language features. For example, if the cursor is on "i" in the "else if"
of a Makefile, the previous implementation would jump to the "else" on a
reverse jump instead of treating "else if" as a single structure.

parsePatternAtOffset() needs to return both the match start and end for
us to correctly handle such a distinction.
The new LanguagePatterns class lets us easily configure the patterns for
a language in a similar way to the original plugin. Most language
features can be configured by passing strings to the alternate
constructor. And the overloaded + operator makes combining patterns easy.

findMatchingPair() was refactored to work with the new class.

In addition, the concept of prefixes was removed. The cursor should jump
if it's anywhere inside or before an extended pair (excluding the
default pairs). Instead of appending a prefix to each regex, we simply
check in findMatchingPair() what the closest pair to the cursor is. The
original plugin behaves the same way.

We prefer matches containing the cursor over matches after the cursor.
If the cursor in inside multiple patterns, we pick the smaller one. And
a default pair after the cursor is preferred over any extended pairs
after the cursor.
@AlexPl292 AlexPl292 self-assigned this Apr 7, 2022
@AlexPl292 AlexPl292 merged commit 8ab3664 into JetBrains:master Apr 7, 2022
@AlexPl292
Copy link
Member

Hi, this is a great work. Thank you for the new languages support!
The test coverage is just awesome.

@myzeiri myzeiri deleted the matchit-enhancements branch April 7, 2022 14:09
@myzeiri
Copy link
Contributor Author

myzeiri commented Apr 7, 2022

Thanks, Alex!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants