Create julia lexer and tags parser (#2584)
* Create julia parser, ctags and lexilla * add ctags test file
This commit is contained in:
parent
f94d7ea6aa
commit
90c6096ed6
@ -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
1554
ctags/parsers/geany_julia.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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 \
|
||||
|
||||
@ -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
|
||||
|
||||
81
data/filedefs/filetypes.julia
Normal file
81
data/filedefs/filetypes.julia
Normal 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"
|
||||
@ -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;
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
36
scintilla/julia_lexilla_v5.patch
Normal file
36
scintilla/julia_lexilla_v5.patch
Normal 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();
|
||||
}
|
||||
};
|
||||
1269
scintilla/lexers/LexJulia.cxx
Normal file
1269
scintilla/lexers/LexJulia.cxx
Normal file
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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 */
|
||||
}
|
||||
|
||||
@ -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 ||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -109,6 +109,7 @@ enum
|
||||
TM_PARSER_JSON,
|
||||
TM_PARSER_ZEPHIR,
|
||||
TM_PARSER_POWERSHELL,
|
||||
TM_PARSER_JULIA,
|
||||
TM_PARSER_BIBTEX,
|
||||
TM_PARSER_COUNT
|
||||
};
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
JsonParser, \
|
||||
ZephirParser, \
|
||||
PowerShellParser, \
|
||||
JuliaParser, \
|
||||
BibtexParser
|
||||
|
||||
#endif
|
||||
|
||||
500
tests/ctags/julia-corner_cases.jl
Normal file
500
tests/ctags/julia-corner_cases.jl
Normal 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
|
||||
Loading…
x
Reference in New Issue
Block a user