Create julia lexer and tags parser (#2584)

* Create julia parser, ctags and lexilla

* add ctags test file
This commit is contained in:
getzze 2021-07-20 05:05:49 +01:00 committed by GitHub
parent f94d7ea6aa
commit 90c6096ed6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 3576 additions and 0 deletions

View File

@ -31,6 +31,7 @@ parsers = \
parsers/geany_html.c \
parsers/geany_jscript.c \
parsers/geany_json.c \
parsers/geany_julia.c \
parsers/geany_lcpp.c \
parsers/geany_lcpp.h \
parsers/geany_lua.c \

1554
ctags/parsers/geany_julia.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,7 @@ filetypes_dist = \
filedefs/filetypes.html \
filedefs/filetypes.java \
filedefs/filetypes.javascript \
filedefs/filetypes.julia \
filedefs/filetypes.JSON.conf \
filedefs/filetypes.latex \
filedefs/filetypes.lisp \

View File

@ -132,11 +132,13 @@ comment_doc_keyword_error=comment_doc,italic
number=0x007f00
number_1=number
number_2=number_1
number_3=0x808000
type=0x0000d0;;true;false
class=type
function=0x000080
parameter=function
annotation=0x8080ff;;true;false
keyword=0x00007f;;true;false
keyword_1=keyword
@ -163,6 +165,7 @@ preprocessor=0x007f7f
regex=number_1
operator=0x301010
decorator=string_1,bold
macro=preprocessor,bold
other=0x404080
tag=type

View File

@ -0,0 +1,81 @@
# filetypes.julia
#
# For complete documentation of this file, please see Geany's main documentation
#
# Keywords from pygment lexer (http://pygments.org/)
# and from vim parser (https://github.com/JuliaEditorSupport/julia-vim/)
#
[styling]
default=default
comment=comment
number=number_3
keyword1=keyword_1
keyword2=keyword_2
keyword3=number_3
keyword4=identifier_1
char=string_1
operator=operator
bracket=operator
identifier=identifier_1
string=string_2
symbol=string_1
macro=macro
stringinterp=default
docstring=string_2
stringliteral=string_2,bold
command=default,italic
commandliteral=default,italic,bold
typeoperator=annotation
typeannotation=keyword_2
lexerror=error
[keywords]
# all items must be in one line
# primary should contain at least the reserved keyword (for, if, begin, end, ...)
primary=baremodule begin break catch const continue do else elseif end export finally for function global if import let local macro module quote return struct try using while abstract mutable primitive type where in isa as
secondary=Main Base Core Any AbstractArray AbstractRange LinRange OrdinalRange AbstractUnitRange UnitRange StepRange StepRangeLen BitArray CartesianIndices DenseArray Array LinearIndices PermutedDimsArray SubArray AbstractChannel Channel AbstractChar Char AbstractDict Dict IdDict WeakKeyDict AbstractDisplay TextDisplay AbstractSet BitSet Set AbstractString String SubString SubstitutionString Cstring Cwstring Enum Exception ArgumentError AssertionError BoundsError CapturedException CompositeException DimensionMismatch DivideError DomainError EOFError ErrorException InexactError InterruptException InvalidStateException KeyError MethodError MissingException OutOfMemoryError OverflowError ProcessFailedException ReadOnlyMemoryError SegmentationFault StackOverflowError StringIndexError SystemError TaskFailedException TypeError UndefKeywordError UndefRefError UndefVarError ExponentialBackOff Expr GlobalRef HTML IO IOStream IndexStyle IndexCartesian IndexLinear LineNumberNode MIME Method MethodSummary Missing Module NamedTuple Nothing Number Complex Real AbstractFloat BigFloat Float16 Float32 Float64 AbstractIrrational Irrational Integer Bool Signed BigInt Int Int128 Int16 Int32 Int64 Int8 Unsigned UInt UInt128 UInt16 UInt32 UInt64 UInt8 Rational Pair QuoteNode RawFD Ref Ptr Regex RegexMatch RoundingMode Some Symbol Task Text Timer Tuple Type DataType Union UnionAll TypeVar UndefInitializer Val Vararg VecElement VersionNumber WeakRef AbstractVector DenseVector StridedVector AbstractMatrix DenseMatrix StridedMatrix AbstractVecOrMat DenseVecOrMat StridedVecOrMat
tertiary=true false missing Inf NaN pi stdin stdout stderr devnull nothing undef ARGS ENV ENDIAN_BOM LOAD_PATH VERSION PROGRAM_FILE DEPOT_PATH
functions=
[lexer_properties]
# Fold multiline triple-doublequote strings, usually used to document a function or type above the definition.
fold.julia.docstring=1
# Set this property to 0 to disable syntax based folding.
fold.julia.syntax.based=1
# This option enables highlighting of the type identifier after `::`.
lexer.julia.highlight.typeannotation=0
# This option enables highlighting of syntax error int character or number definition.
lexer.julia.highlight.lexerror=0
[settings]
lexer_filetype=Julia
tag_parser=Julia
# default extension used when saving files
extension=jl
# MIME type
mime_type=text/x-julia
# single comments, like # in this file
comment_single=#
# multiline comments
comment_open=#=
comment_close==#
[indentation]
width=4
# 0 is spaces, 1 is tabs, 2 is tab & spaces
type=0
[build-menu]
# %f will be replaced by the complete filename
# %e will be replaced by the filename without extension
# (use only one of it at one time)
compiler=
run_cmd=julia "%f"

View File

@ -43,6 +43,7 @@ HTML=*.htm;*.html;*.shtml;*.hta;*.htd;*.htt;*.cfm;*.tpl;
Java=*.java;*.jsp;
Javascript=*.js;
JSON=*.json;
Julia=*.jl;
Kotlin=*.kt;*.kts;
LaTeX=*.tex;*.sty;*.idx;*.ltx;*.latex;*.aux;
Lisp=*.lisp;

View File

@ -25,6 +25,7 @@ lexers/LexForth.cxx \
lexers/LexFortran.cxx \
lexers/LexHTML.cxx \
lexers/LexHaskell.cxx \
lexers/LexJulia.cxx \
lexers/LexLaTeX.cxx \
lexers/LexLisp.cxx \
lexers/LexLua.cxx \

View File

@ -144,6 +144,7 @@
#define SCLEX_DATAFLEX 129
#define SCLEX_HOLLYWOOD 130
#define SCLEX_RAKU 131
#define SCLEX_JULIA 133
#define SCLEX_LPEG 999
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
@ -932,6 +933,28 @@
#define SCE_ERLANG_MODULES 23
#define SCE_ERLANG_MODULES_ATT 24
#define SCE_ERLANG_UNKNOWN 31
#define SCE_JULIA_DEFAULT 0
#define SCE_JULIA_COMMENT 1
#define SCE_JULIA_NUMBER 2
#define SCE_JULIA_KEYWORD1 3
#define SCE_JULIA_KEYWORD2 4
#define SCE_JULIA_KEYWORD3 5
#define SCE_JULIA_CHAR 6
#define SCE_JULIA_OPERATOR 7
#define SCE_JULIA_BRACKET 8
#define SCE_JULIA_IDENTIFIER 9
#define SCE_JULIA_STRING 10
#define SCE_JULIA_SYMBOL 11
#define SCE_JULIA_MACRO 12
#define SCE_JULIA_STRINGINTERP 13
#define SCE_JULIA_DOCSTRING 14
#define SCE_JULIA_STRINGLITERAL 15
#define SCE_JULIA_COMMAND 16
#define SCE_JULIA_COMMANDLITERAL 17
#define SCE_JULIA_TYPEANNOT 18
#define SCE_JULIA_LEXERROR 19
#define SCE_JULIA_KEYWORD4 20
#define SCE_JULIA_TYPEOPERATOR 21
#define SCE_MSSQL_DEFAULT 0
#define SCE_MSSQL_COMMENT 1
#define SCE_MSSQL_LINE_COMMENT 2

View File

@ -3255,6 +3255,7 @@ val SCLEX_X12=128
val SCLEX_DATAFLEX=129
val SCLEX_HOLLYWOOD=130
val SCLEX_RAKU=131
val SCLEX_JULIA=133
val SCLEX_LPEG=999
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
@ -4162,6 +4163,30 @@ val SCE_ERLANG_MODULES_ATT=24
val SCE_ERLANG_UNKNOWN=31
# Lexical states for SCLEX_OCTAVE are identical to MatLab
lex Octave=SCLEX_OCTAVE SCE_MATLAB_
# Lexical states for SCLEX_JULIA
lex Julia=SCLEX_JULIA SCE_JULIA_
val SCE_JULIA_DEFAULT=0
val SCE_JULIA_COMMENT=1
val SCE_JULIA_NUMBER=2
val SCE_JULIA_KEYWORD1=3
val SCE_JULIA_KEYWORD2=4
val SCE_JULIA_KEYWORD3=5
val SCE_JULIA_CHAR=6
val SCE_JULIA_OPERATOR=7
val SCE_JULIA_BRACKET=8
val SCE_JULIA_IDENTIFIER=9
val SCE_JULIA_STRING=10
val SCE_JULIA_SYMBOL=11
val SCE_JULIA_MACRO=12
val SCE_JULIA_STRINGINTERP=13
val SCE_JULIA_DOCSTRING=14
val SCE_JULIA_STRINGLITERAL=15
val SCE_JULIA_COMMAND=16
val SCE_JULIA_COMMANDLITERAL=17
val SCE_JULIA_TYPEANNOT=18
val SCE_JULIA_LEXERROR=19
val SCE_JULIA_KEYWORD4=20
val SCE_JULIA_TYPEOPERATOR=21
# Lexical states for SCLEX_MSSQL
lex MSSQL=SCLEX_MSSQL SCE_MSSQL_
val SCE_MSSQL_DEFAULT=0

View File

@ -0,0 +1,36 @@
diff --git a/lexilla/lexers/LexJulia.cxx b/geany/scintilla/lexers/LexJulia.cxx
index 6730074..ccf947d 100644
--- a/lexilla/lexers/LexJulia.cxx
+++ b/geany/scintilla/lexers/LexJulia.cxx
@@ -39,7 +39,8 @@
#include "DefaultLexer.h"
using namespace Scintilla;
-using namespace Lexilla;
+// Geany still uses Scintilla v3.5
+//using namespace Lexilla;
static const int MAX_JULIA_IDENT_CHARS = 1023;
@@ -138,7 +139,9 @@ public:
delete this;
}
int SCI_METHOD Version() const override {
- return lvRelease5;
+ // Geany still uses Scintilla v3.5
+ //return lvRelease5;
+ return lvIdentity;
}
const char * SCI_METHOD PropertyNames() override {
return osJulia.PropertyNames();
@@ -163,7 +166,9 @@ public:
return 0;
}
- static ILexer5 *LexerFactoryJulia() {
+ // Geany still uses Scintilla v3.5
+ //static ILexer5 *LexerFactoryJulia() {
+ static ILexer *LexerFactoryJulia() {
return new LexerJulia();
}
};

File diff suppressed because it is too large Load Diff

View File

@ -80,6 +80,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmFreeBasic);
LINK_LEXER(lmHaskell);
LINK_LEXER(lmHTML);
LINK_LEXER(lmJulia);
LINK_LEXER(lmLatex);
LINK_LEXER(lmLISP);
LINK_LEXER(lmLua);

View File

@ -187,6 +187,7 @@ static void init_builtin_filetypes(void)
FT_INIT( GO, GO, "Go", NULL, SOURCE_FILE, COMPILED );
FT_INIT( ZEPHIR, ZEPHIR, "Zephir", NULL, SOURCE_FILE, COMPILED );
FT_INIT( SMALLTALK, NONE, "Smalltalk", NULL, SOURCE_FILE, SCRIPT );
FT_INIT( JULIA, JULIA, "Julia", NULL, SOURCE_FILE, SCRIPT );
}

View File

@ -107,6 +107,7 @@ typedef enum
GEANY_FILETYPES_ZEPHIR,
GEANY_FILETYPES_BIBTEX,
GEANY_FILETYPES_SMALLTALK,
GEANY_FILETYPES_JULIA,
/* ^ append items here */
GEANY_MAX_BUILT_IN_FILETYPES /* Don't use this, use filetypes_array->len instead */
}

View File

@ -1026,6 +1026,7 @@ void highlighting_init_styles(guint filetype_idx, GKeyFile *config, GKeyFile *co
init_styleset_case(HTML);
init_styleset_case(JAVA);
init_styleset_case(JS);
init_styleset_case(JULIA);
init_styleset_case(LATEX);
init_styleset_case(LUA);
init_styleset_case(MAKE);
@ -1115,6 +1116,7 @@ void highlighting_set_styles(ScintillaObject *sci, GeanyFiletype *ft)
styleset_case(HTML);
styleset_case(JAVA);
styleset_case(JS);
styleset_case(JULIA);
styleset_case(LATEX);
styleset_case(LUA);
styleset_case(MAKE);
@ -1514,6 +1516,13 @@ gboolean highlighting_is_string_style(gint lexer, gint style)
return (style == SCE_MATLAB_STRING ||
style == SCE_MATLAB_DOUBLEQUOTESTRING);
case SCLEX_JULIA:
return (style == SCE_JULIA_CHAR ||
style == SCE_JULIA_STRING ||
style == SCE_JULIA_DOCSTRING ||
style == SCE_JULIA_COMMAND ||
style == SCE_JULIA_STRINGINTERP);
case SCLEX_XML:
case SCLEX_HTML:
case SCLEX_PHPSCRIPT:
@ -1718,6 +1727,9 @@ gboolean highlighting_is_comment_style(gint lexer, gint style)
case SCLEX_OCTAVE:
return (style == SCE_MATLAB_COMMENT);
case SCLEX_JULIA:
return (style == SCE_JULIA_COMMENT);
case SCLEX_LUA:
return (style == SCE_LUA_COMMENT ||
style == SCE_LUA_COMMENTLINE ||

View File

@ -883,6 +883,42 @@ static const HLKeyword highlighting_keywords_JS[] =
};
#define highlighting_properties_JS highlighting_properties_C
/* Julia */
#define highlighting_lexer_JULIA SCLEX_JULIA
static const HLStyle highlighting_styles_JULIA[] =
{
{ SCE_JULIA_DEFAULT, "default", FALSE },
{ SCE_JULIA_COMMENT, "comment", FALSE },
{ SCE_JULIA_NUMBER, "number", FALSE },
{ SCE_JULIA_KEYWORD1, "keyword1", FALSE },
{ SCE_JULIA_KEYWORD2, "keyword2", FALSE },
{ SCE_JULIA_KEYWORD3, "keyword3", FALSE },
{ SCE_JULIA_CHAR, "char", FALSE },
{ SCE_JULIA_OPERATOR, "operator", FALSE },
{ SCE_JULIA_BRACKET, "bracket", FALSE },
{ SCE_JULIA_IDENTIFIER, "identifier", FALSE },
{ SCE_JULIA_STRING, "string", FALSE },
{ SCE_JULIA_SYMBOL, "symbol", FALSE },
{ SCE_JULIA_MACRO, "macro", FALSE },
{ SCE_JULIA_STRINGINTERP, "stringinterp", FALSE },
{ SCE_JULIA_DOCSTRING, "docstring", FALSE },
{ SCE_JULIA_STRINGLITERAL, "stringliteral", FALSE },
{ SCE_JULIA_COMMAND, "command", FALSE },
{ SCE_JULIA_COMMANDLITERAL, "commandliteral", FALSE },
{ SCE_JULIA_TYPEANNOT, "typeannotation", FALSE },
{ SCE_JULIA_LEXERROR, "lexerror", FALSE },
{ SCE_JULIA_KEYWORD4, "keyword4", FALSE },
{ SCE_JULIA_TYPEOPERATOR, "typeoperator", FALSE },
};
static const HLKeyword highlighting_keywords_JULIA[] =
{
{ 0, "primary", FALSE },
{ 1, "secondary", FALSE },
{ 2, "tertiary", FALSE },
{ 3, "functions", FALSE }
};
#define highlighting_properties_JULIA EMPTY_PROPERTIES
/* LaTeX */
#define highlighting_lexer_LATEX SCLEX_LATEX

View File

@ -619,6 +619,20 @@ static void add_top_level_items(GeanyDocument *doc)
NULL);
break;
}
case GEANY_FILETYPES_JULIA:
{
tag_list_add_groups(tag_store,
&(tv_iters.tag_variable), _("Constants"), ICON_VAR,
&(tv_iters.tag_namespace), _("Modules"), ICON_NAMESPACE,
&(tv_iters.tag_function), _("Functions"), ICON_METHOD,
&(tv_iters.tag_member), _("Fields"), ICON_MEMBER,
&(tv_iters.tag_macro), _("Macros"), ICON_MACRO,
&(tv_iters.tag_struct), _("Structures"), ICON_STRUCT,
&(tv_iters.tag_type), _("Types"), ICON_CLASS,
&(tv_iters.tag_externvar), _("Unknowns"), ICON_OTHER,
NULL);
break;
}
case GEANY_FILETYPES_HTML:
{
tag_list_add_groups(tag_store,

View File

@ -528,6 +528,19 @@ static TMParserMapEntry map_POWERSHELL[] = {
{'v', tm_tag_variable_t},
};
static TMParserMapEntry map_JULIA[] = {
{'c', tm_tag_variable_t},
{'f', tm_tag_function_t},
{'g', tm_tag_member_t},
{'m', tm_tag_macro_t},
{'n', tm_tag_namespace_t},
{'s', tm_tag_struct_t},
{'t', tm_tag_typedef_t},
/* defined as externvar to get those excluded as forward type in symbols.c:goto_tag()
* so we can jump to the real implementation (if known) instead of to the import statement */
{'x', tm_tag_externvar_t},
};
typedef struct
{
@ -591,6 +604,7 @@ static TMParserMap parser_map[] = {
MAP_ENTRY(JSON),
MAP_ENTRY(ZEPHIR),
MAP_ENTRY(POWERSHELL),
MAP_ENTRY(JULIA),
};
/* make sure the parser map is consistent and complete */
G_STATIC_ASSERT(G_N_ELEMENTS(parser_map) == TM_PARSER_COUNT);

View File

@ -109,6 +109,7 @@ enum
TM_PARSER_JSON,
TM_PARSER_ZEPHIR,
TM_PARSER_POWERSHELL,
TM_PARSER_JULIA,
TM_PARSER_BIBTEX,
TM_PARSER_COUNT
};

View File

@ -65,6 +65,7 @@
JsonParser, \
ZephirParser, \
PowerShellParser, \
JuliaParser, \
BibtexParser
#endif

View File

@ -0,0 +1,500 @@
#= Julia syntax highlighting test.
Modified from https://github.com/JuliaEditorSupport/julia-syntax-test-cases
This file derives from https://gist.github.com/Wilfred/f1aca44c61ed6e1df603
whose author is [@Wilfred](https://github.com/Wilfred). @Wilfred has put it in
the public domain:
https://gist.github.com/Wilfred/f1aca44c61ed6e1df603#gistcomment-2948526
Changes from the original are governed by the license of the repository in
which this file is found.
This file is designed to test various corner cases of Julia
syntax highlighting.
=#
baremodule Mod1
# Nothing here
end
module Mod2
# Here neither
end
## Simple function definitions.
# Expected: `function` should be highlighted, as should `foo_bar!`.
function foo_bar!(x,y)
x + y + 1
end
# Expected: `foo_bar!` should be highlighted.
foo_bar!(x,y) = x + y
# Expected: `foo` should be highlighted.
Baz.foo(x) = 1
# Expected: `foo` should be highlighted.
foo(x::(Int,)) = 1
# Expected: `foo` should be highlighted.
foo(x, y=length(x))
## Function definitions in namespaces.
# Expected: `bar` should be highlighted.
function Foo.bar(x, y)
x + 1
end
## Function definitions with type variables.
# Expected: `elsize` should be highlighted.
elsize(::AbstractArray{T}) where {T} = sizeof(T)
function elsize(::AbstractArray{T}) where T
sizeof(T)
end
## Nested brackets in function definitions.
# Expected: `cell` should be highlighted.
cell(dims::(Integer...)) = Array(Any, convert((Int...), dims))
# TODO: find an example with a nested type expression.
## Macro usage
# Expected: `@hello_world!` should be highlighted.
@hello_world! foo
# Expected: highlight `myfun`
@inline myfun() = println("myfun")
## Builtin functions.
# Expected: `throw`, `error` and `super` should not be highlighted. There are
# too many built-in functions for this to be useful.
# https://github.com/JuliaLang/julia/commit/134867c69096fcb52afa5d5a7433892b5127e981
# https://github.com/JuliaLang/julia/pull/7963#issuecomment-52586261
throw(foo)
error("foo", bar, "baz")
super(Int)
## Strings
# Expected: highlight the string.
x = "foo \"bar\" baz"
# Expected: highlight the whole string.
x = "foo
bar"
# Expected: highlight the whole triple-quoted string.
x = """hello "world" foobar"""
y = """foo\\"""
z = """bar\""""
w = """"bar"""
# Expected: highlight `$user`
x = "hello $user"
# Expected: don't highlight `$user`
x = "hello \$user"
# Expected: highlight `$val`
x = """(a="$val")"""
# Expected: treat r as part of the string, so `r"a"` is highlighted.
x = r"0.1"
# Expected: treat ismx as part of the string, so `r"a"ismx` is highlighted.
x = r"a"ismx
# Expected: highlight `r"""a "b" c"""`
x = r"""a "b" c"""
# Expected: treat v as part of the string, so `v"0.1"` is highlighted.
x = v"0.1"
# Expected: treat b as part of the string, so `b"a"` is highlighted.
x = b"a"
# Bonus points:
# Expected: highlight the interpolation brackets `$(` and `)`
x = "hello $(user * user)"
# Bonus points:
# Expected: highlight regexp metacharacters `[` and `]`
x = r"[abc]"
# Bonus points:
# Expected: highlight escape sequences `\xff` and `\u2200`
x = b"DATA\xff\u2200"
# Bonus points:
# Expected: don't highlight `$user`
x = raw"hello $user"
## Characters
# Expected: highlight the character.
x = 'a'
y = '\u0'
z = '\U10ffff'
w = '\x41'
a = ' '
b = '"'
c = '''
d = '\''
e = '\\'
# Expected: don't highlight, as ' is an operator here, not a character delimiter.
a = b' + c'
A'''
# Bonus points:
# Expected: don't highlight the character
x = 'way too long so not a character'
x = ''
## Comments
# Expected: highlight `# foo`
# foo
# Expected: highlight `#= foo\n bar =#`
#= foo
bar =#
# Expected: highlight `#= #= =# =#` (comments can nest).
#= #= =# =#
# Expected: highlight `'` as adjoint operator
A#==#'
(A)#==#'
A[1]#==#'
## Type declarations
# Expected highlight `Foo` and `Bar`
mutable struct Foo
x::Bar
end
# Expected highlight `Foo` and `Bar`
struct Foo
x::Bar
end
# Expected: highlight `Foo` and `Bar`
abstract type Foo <: Bar end
# Expected: don't highlight x or y
x <: y
## Type annotations
# Expected: highlight `FooBar`
f(x::FooBar) = x
# Expected: highlight `Int8`
function foo()
local x::Int8 = 5
x
end
# Expected: highlight `Point` and `Real` as types
function norm(p::Point{<:Real})
sqrt(p.x^2 + p.y^2)
end
# Expected: highlight `g` as function and `Int8` as type
function g(x, y)::Int8
return x * y
end
# Expected: highlight `T` and `Number`
same_type_numeric(x::T, y::T) where {T <: Number} = true
same_type_numeric(x::T, y::T) where T = false
## Parametric type declaration
# Expected: highlight `Pointy` and `T`
abstract type Pointy{T} end
# Expected: highlight `Point`, `Pointy` and `T`
struct Point{T} <: Pointy{T}
x::T
y::T
end
## Variable declarations
# Expected: highlight `x` and `y`
global x = "foo, bar = 2", y = 3
# Expected: highlight `x` and `y`
global x = foo(a, b), y = 3
# Expected: highlight `y`
const y = "hello world"
# Expected: highlight `x` and `y`
function foo()
local x = f(1, 2), y = f(3, 4)
x + y
end
# Expected: highlight `x` and `y`
let x = f(1, 2), y = f(3, 4)
x + y
end
## Colons and end
# Expected: highlight `:foo`, `:end` and `:function`
:foo
x = :foo
y = :function
z = :end
# Expected: highlight index `[end]` differently to block delimiter `end`
if foo[end]
end
# Expected: highlight as index `end`
foo[bar:end]
# Expected: highlight as index `begin`
foo[begin:4]
# Expected: don't highlight `:123`
x = :123
# Expected: don't highlight `:baz`
foo[bar:baz]
# Expected: highlight `:baz`
foo[:baz]
# Expected: highlight both `:baz`
foo(:baz,:baz)
# Note that `: foo` is currently a valid quoted symbol, this will hopefully
# change in 0.4: https://github.com/JuliaLang/julia/issues/5997
# Expected: highlight `:foo`
[1 :foo]
# Expected: highlight `:end`
[1 :end]
# Expected: highlight `:two`
@eval :one+:two
# Expected: don't highlight `:end` but `end` as index
[(1+1):end]
# Expected: don't highlight `:end` but `end` as index
[a[1]:end]
# Expected: don't highlight `:foo`
for x=1:foo
print(x)
end
## Range detection
# Bonus points:
# Expected: don't highlight `:s2`
push!(a, s1 :s2)
# Bonus points:
# Expected: don't highlight `:end`
a[begin :end]
## Expression evaluation
# Expected: highlight `:` as operator
a = :(x = 2)
# Expected: highlight `:call` and `:b` as symbols
# Debatable: highlight `:+` as operator
ex = Expr(:call, :+, a, :b)
## Number highlighting
# Expected: highlight all these as numbers
x = 123
x = 1.1
x = .5
x = 0x123abcdef
x = 0o7
x = 0b1011
x = 2.5e-4
x = 2.5E-4
x = 1e+00
x = 2.5f-4
x = 0x.4p-1
x = 1_000
# Expected: highlight these as numbers or built-ins
x = Inf
x = NaN
# Expected: highlight `123`, not the letter
y = 123x
y = 123e
# Expected: highlight `1e+1` and `1e-1`
1e+1+1e-1
# Expected: highlight `1.` and `.1`
1. +.1
# Note that `1.+1` is currently ambiguous and gives an error
# Bonus points:
# Expected: don't highlight `..`
x = 1..3
# Bonus points:
# Debatable: highlight the first two digits, not the following digits
# or show an error
x = 0o1291
x = 0b1091
# Debatable: highlight `π` as a number or built-in
# (note that `πx` is a single symbol, not `π * x`)
x = π
## List comprehension
# Expected: highlight `for` and `if` without the `end` keyword
[i for i in 1:5 if i%2==0]
## Broadcasting
# Expected: highlight `.+` as operator
a.+1
## Command
# Expected: highlight "`echo 1`"
c = `echo 1`
# Expected: highlight "```echo `hello 1` ```"
c = ```echo `hello 1` ```
# Expected: highlight "raw`echo $1`"
c = raw`echo $1`
## Non-standard identifiers
# Bonus points:
# Expected: highlight `var"##"` as a function
function var"##"(x)
println(x)
end
# Bonus points:
# Expected: highlight `var"%%"` as a function
var"%%"(x) = println(x)
# Bonus points:
# Expected: highlight `$var` as string and `##""` as comment
"$var"##""
# Bonus points:
# Expected: highlight `$(var")(")` as string interpolation
"$(var")(")"
# Bonus points:
# Expected: highlight `'` as adjoint operator
var"##mat"'
## Code folding: for and if in list comprehension
# Expected: fold between function and last end
function test(x)
a = (if x; 0 else 1 end)
println(a)
end
## Default struct attributes
Base.@kwdef struct Test
a::Float64 = 1E12
b::Float64 = pi
end
## Parametric constructors
struct OurRational{T<:Integer} <: Real
"Numerator"
num::T
"Denominator"
den::T
OurRational{Int8}(num::T, den::T) where T<:Integer = new(convert(Int8, num), convert(Int8, den))
"""
Parametric inner constructor
"""
function OurRational{T}(num::T, den::T) where T<:Integer
if num == 0 && den == 0
error("invalid rational: 0//0")
end
# Bug with short function misidentification of == and =>
length(num) == 0
length(den) => 0
g = gcd(den, num)
num = div(num, g)
den = div(den, g)
new(num, den)
end
test::T
OurRational{Int64}(num::T, den::T, test::T) where T<:Integer = new(num, den, test)
end
OurRational{Int16}(num::T, den::T) where T<:Integer = new(num, den)
## Import modules
using Module1
using Module2: func1, func2
import Module3
import Module4.func1, Module5, Module6.func2
import Module7: func1, func2
module MyModule
using Module8,
Module9,
Module10
using Module11: func1,
func2,
func3
end
import Base.show,
# Base.print as pr,
Base.*
#using Module12: func1, func2 as alias2, func3
using Module13: func1,
# func2 as alias2,
func3
#import Module14 as Alias12
## Function scope
module MyModule
function func3(a::Int)
a
end
function func4(a::Int)
function func5(b::Int)
b
end
func5(a)
end
end
## Docstring
"""
This is a test docstring
with multiple lines.
"""
function test_docstring end