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 more syntaxes to language Julia #16

Merged
merged 6 commits into from
Jan 17, 2022
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions src/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,24 +130,37 @@ export const languages: {
close: '"'
},
{
open: "'",
close: "'"
singularitti marked this conversation as resolved.
Show resolved Hide resolved
open: "#=",
close: "=#"
singularitti marked this conversation as resolved.
Show resolved Hide resolved
},
{
open: "\\[",
close: "\\]"
},
{
open: "\\(",
close: "\\)"
}
],
inlineOpenTokens: [],
openTokens: [
"if",
"struct",
"abstract type",
"primitive type",
"begin",
"let",
"for",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singularitti Also, if non-generator-like for requires do or another token, you could change this to:

Suggested change
"for",
"for(?=.*do)",

This should now only match expressions like: for ... do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I am trying to use this pattern "^\s*for" (A for with only blank characters before it) to replace "for", but it does not seem to succeed. The below generator expression

[getfield(x, :a) for x in object.b.c],

is still treated as a for loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for
As an example, I only want the first for be matched.

Copy link
Contributor

@polvalente polvalente Sep 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with Julia. Why the for preceeded by @SoftScope shouldn't be matched? This might bring problems with the matching end for it.

Check if this token works well enough for for:

  • (?<=\\[[^\\]]*)for(?![^\\]]*\\]))

It uses negative lookahead and positive lookbehind to try and match those generators.
I don't know if it can handle nested or multiline generators.

Another option is adding [ and ] as open and close tokens for an ignore block. This is not ideal, but would avoid ugly breakage for the rest of the file

Copy link
Contributor Author

@singularitti singularitti Sep 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @polvalente, thank you for your reply. I am not an expert in regex, so I just wrote the simplest example. Yes, indeed, that will break the highlighting.

I cannot figure out a good regex to distinguish the for loops and generator expressions. Because Julia is so flexible that it allows a lot of ways to write a for loop. The only difference between them just seems to be for loops have an end. I will list some test examples below. I hope you can figure out a working way to distinguish them. Thank you!

Below are normal for loops so should be paired with ends.

# Those should be matched.
for i = 1:10
           s += i
       end

@softscope for i in 1:10
           s += i
       end

softscope(Main, :(for i = 1:10
           s += i
       end))

for i in 1:10; println(i); end

for i in [1, 2, 3]
	println(i)
end

for i in collect(1:10)
	println(i)
end

Below are generator expressions and are not paired with ends:

# Those should not be matched.
sum(1/n^2 for n=1:1000)

 map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4])

[(i,j) for i=1:3 for j=1:i if i+j == 4]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow. I think there is a problem with how I implemented ignore blocks. I'll refactor it in the coming weekend.

Basically, I didn't think to support nesting. As such, ((x) for) will be passed to the coloring function as for) (because the first closing paren will close the first open paren).

Luckily, I already have an idea on how to solve it (by using stacks).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#18

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind the weekend: #19
HAHA

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Cannot wait to have a try!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried this method. It seems that with the following test text:

sum(1/n^2 for n=1:1000)

map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4])

[(i,j) for i=1:3 for j=1:i if i+j == 4]

for i = 1:10
    s += i
end

@softscope for i in 1:10
    s += i
end

softscope(Main, :(for i = 1:10
    s += i
end))

for i in 1:10; println(i); end

for i in [1, 2, 3]
println(i)
end

for i in collect(1:10)
println(i)
end

image

The map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4]) is not working because there is one ) before the for.

This test now works:
work

"while",
"quote",
"do",
"module"
"module",
"function",
"macro",
"try"
],
closeTokens: ["end"],
neutralTokens: ["else", "elseif"]
neutralTokens: ["else", "elseif", "catch", "finally"]
},
shellscript: {
caseSensitive: true,
Expand Down