Skip to content
New issue

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

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

Already on GitHub? # to your account

Support for Julia language #2

Closed
phgz opened this issue Jan 23, 2022 · 11 comments
Closed

Support for Julia language #2

phgz opened this issue Jan 23, 2022 · 11 comments
Labels
good first issue Good for newcomers

Comments

@phgz
Copy link

phgz commented Jan 23, 2022

Hi,

This seems a great plugin. Could it be implemented for Julia as well? The syntax is very similar to the Ruby one.

Thank you!

@RRethy
Copy link
Owner

RRethy commented Jan 23, 2022

I'm open to having Julia support added, but since it's not a language I've ever used I wouldn't implement it myself and instead would be willing to help guide someone with Julia experience to implement it. I'll give some details below on how to add support.

Adding support is as simple as added a single tree-sitter query file, see https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries for query syntax. Make a file queries/julia/endwise.scm, this is where the queries will go. There will be generally two queries for each thing which can have an end node added to it: when the parsing fails, and when the parsing succeeds. To get a better understanding of this, let's take a look at Lua which has a decently simple grammar.

In Lua, we have the following queries, https://github.com/RRethy/nvim-treesitter-endwise/blob/master/queries/lua/endwise.scm. Let's focus on the function definition queries, of which there are two:

((ERROR ("function" . (_)? . (parameters) @cursor) @indent) (#endwise! "end"))

The first query with ERROR is simple and will match the following:

function foo()<cursor>

Since we are working with syntax trees that have an error in them, we will expect the parser to be in a weird state and not be able to parse this code into a function_definition node, instead it gets parsed as a sequence of tokens and nodes and placed into the generic ERROR node to signify that the parser couldn't make sense of this sequence of tokens. In this example, we have a "function" followed by an (identifier) followed by (parameters). We also have two captures, @cursor to mark where we expect the users cursor to be in the query match, and @indent to signify what kind of indentation the end node should have when we place it. Lastly, we also have the #endwise! directive which is how we can configure the end node, if we made it foo then the text that gets inserted would be that.

Let's now take a look at the second query:

((function_definition parameters: (_) @cursor) @endable @indent (#endwise! "end"))

This one is a bit more complicated but it's a side effect of tree-sitter generating parsers which follow maximal-munch. Let's take a look at a piece of code:

function foo()
  function bar()<cursor>
end

If we look at this, we know that the end token is for the foo function, but the parser will parse it as part of the bar function which means the bar function will have a valid parse tree even though it shouldn't. To get around this, we can use the @indent in conjunction with the @endable capture group, if the last child of the node captured by @endable has a different indentation than the node captured by @indent, and if an ancestor node in the syntax tree has an error, then we can assume that the end node is actually meant to be a part of a different node. As such, we insert an end node with matching indentation.

To help you with writing queries, try writing some Julia code which you would expect to have an end node added, then run :TSPlayground and inspect the syntax tree (pressing a in the playground shows anonymous nodes). You can also add tests in tests/endwise/julia.rb that follow tests/endwise/lua.rb to verify your queries work. The consist of a few lines prefixed by a - with a to mark the initial cursor position, followed by lines prefixed by a + to show the expected end state of the text. You can run these tests with ruby ./tests/runner.rb <keyword> where <keyword> is something to match the provided description (or empty to match all tests).

@RRethy RRethy added the good first issue Good for newcomers label Jan 25, 2022
@phgz
Copy link
Author

phgz commented Jan 26, 2022

Thank you much for the detailed guidelines. I am myself still learning the language, so it will be a good challenge. I am however quite occupied these days, so i will not be able to give it a grasp in the coming days, but as soon as I do, I will start working on it.

As you say, I think it will be straightforward since the syntax is so similar to ruby and lua.

I will try to make a PR when it is ready 😄.

@RRethy
Copy link
Owner

RRethy commented Jan 26, 2022

I think @jasonrhansen has started work on adding Julia support FWIW (https://github.com/jasonrhansen/nvim-treesitter-endwise/tree/julia).

@phgz
Copy link
Author

phgz commented Jan 26, 2022

Oh, I just saw that! Well awesome then.

@RRethy
Copy link
Owner

RRethy commented Jan 29, 2022

Can you review the Julia PR linked to go through the use-cases.

@phgz
Copy link
Author

phgz commented Jan 29, 2022

I will be able to check it after next week (exams).

Sorry for the delay!

@RRethy
Copy link
Owner

RRethy commented Feb 12, 2022

Have you had a chance to take a look through the PR?

@phgz
Copy link
Author

phgz commented Feb 12, 2022

Yes, it seems OK!

The only thing I don't understand is why, when I'm here

for i in 1:5
    |
end

and press ENTER, then it triggers another end.

@RRethy
Copy link
Owner

RRethy commented Feb 12, 2022

Can you comment that on the PR as part of a PR review.

@RRethy
Copy link
Owner

RRethy commented Mar 13, 2022

Bumping this, can you provide a PR review on that PR raising the issues you found.

@RRethy
Copy link
Owner

RRethy commented Mar 14, 2022

#4 (comment)

@RRethy RRethy closed this as completed Mar 14, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants