49 changes: 40 additions & 9 deletions mode/clike/clike.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
indentSwitch = parserConfig.indentSwitch !== false,
namespaceSeparator = parserConfig.namespaceSeparator,
isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
isNumberChar = parserConfig.isNumberChar || /\d/,
numberStart = parserConfig.numberStart || /[\d\.]/,
number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
endStatement = parserConfig.endStatement || /^[;:,]$/;

Expand All @@ -47,9 +48,10 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
curPunc = ch;
return null;
}
if (isNumberChar.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
if (numberStart.test(ch)) {
stream.backUp(1)
if (stream.match(number)) return "number"
stream.next()
}
if (ch == "/") {
if (stream.eat("*")) {
Expand Down Expand Up @@ -220,6 +222,10 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
}
var closing = firstChar == ctx.type;
var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
return ctx.indented
}
if (isStatement(ctx.type))
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
Expand Down Expand Up @@ -252,8 +258,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
}
}
var cKeywords = "auto if break case register continue return default do sizeof " +
"static else struct switch extern typedef float union for " +
"goto while enum const volatile";
"static else struct switch extern typedef union for goto while enum const volatile";
var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";

function cppHook(stream, state) {
Expand Down Expand Up @@ -530,19 +535,36 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
modeProps: {closeBrackets: {triples: '"'}}
});

function tokenKotlinString(tripleString){
return function (stream, state) {
var escaped = false, next, end = false;
while (!stream.eol()) {
if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
if (tripleString && stream.match('"""')) {end = true; break;}
next = stream.next();
if(!escaped && next == "$" && stream.match('{'))
stream.skipTo("}");
escaped = !escaped && next == "\\" && !tripleString;
}
if (end || !tripleString)
state.tokenize = null;
return "string";
}
}

def("text/x-kotlin", {
name: "clike",
keywords: words(
/*keywords*/
"package as typealias class interface this super val " +
"var fun for is in This throw return " +
"break continue object if else while do try when !in !is as?" +
"break continue object if else while do try when !in !is as? " +

/*soft keywords*/
"file import where by get set abstract enum open inner override private public internal " +
"protected catch finally out final vararg reified dynamic companion constructor init " +
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
"external annotation crossinline"
"external annotation crossinline const operator infix"
),
types: words(
/* package java.lang */
Expand All @@ -551,10 +573,18 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
intendSwitch: false,
indentStatements: false,
multiLineStrings: true,
blockKeywords: words("catch class do else finally for if where try while enum"),
defKeywords: words("class val var object package interface fun"),
atoms: words("true false null this"),
hooks: {
'"': function(stream, state) {
state.tokenize = tokenKotlinString(stream.match('""'));
return state.tokenize(stream, state);
}
},
modeProps: {closeBrackets: {triples: '"'}}
});

Expand Down Expand Up @@ -703,7 +733,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
" native optional sealed see serializable shared suppressWarnings tagged throws variable"),
isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
isNumberChar: /[\d#$]/,
numberStart: /[\d#$]/,
number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
multiLineStrings: true,
typeFirstDefinitions: true,
atoms: words("true false null larger smaller equal empty finished"),
Expand Down
2 changes: 1 addition & 1 deletion mode/css/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (type == "}" || type == "{") return popAndPass(type, stream, state);
if (type == "(") return pushContext(state, stream, "parens");

if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
override += " error";
} else if (type == "word") {
wordAsValue(stream);
Expand Down
10 changes: 8 additions & 2 deletions mode/css/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,17 @@
MT("tagColorHex3",
"[tag foo] { [property background]: [atom #fff]; }");

MT("tagColorHex4",
"[tag foo] { [property background]: [atom #ffff]; }");

MT("tagColorHex6",
"[tag foo] { [property background]: [atom #ffffff]; }");

MT("tagColorHex4",
"[tag foo] { [property background]: [atom&error #ffff]; }");
MT("tagColorHex8",
"[tag foo] { [property background]: [atom #ffffffff]; }");

MT("tagColorHex5Invalid",
"[tag foo] { [property background]: [atom&error #fffff]; }");

MT("tagColorHexInvalid",
"[tag foo] { [property background]: [atom&error #ffg]; }");
Expand Down
6 changes: 3 additions & 3 deletions mode/dart/dart.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"implements get native operator set typedef with enum throw rethrow " +
"assert break case continue default in return new deferred async await " +
"try catch finally do else for if switch while import library export " +
"part of show hide is").split(" ");
"part of show hide is as").split(" ");
var blockKeywords = "try catch finally do else for if switch while".split(" ");
var atoms = "true false null".split(" ");
var builtins = "void bool num int double dynamic var String".split(" ");
Expand Down Expand Up @@ -46,7 +46,7 @@
atoms: set(atoms),
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
stream.eatWhile(/[\w\$_\.]/);
return "meta";
},

Expand Down Expand Up @@ -95,7 +95,7 @@
state.tokenize = null;
break;
}
escaped = !escaped && next == "\\";
escaped = !raw && !escaped && next == "\\";
}
return "string";
}
Expand Down
16 changes: 8 additions & 8 deletions mode/django/django.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
"use strict";

CodeMirror.defineMode("django:inner", function() {
var keywords = ["block", "endblock", "for", "endfor", "true", "false",
"loop", "none", "self", "super", "if", "endif", "as",
"else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
"ifnotequal", "endifnotequal", "extends", "include", "load", "comment",
"endcomment", "empty", "url", "static", "trans", "blocktrans", "now", "regroup",
"lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle", "csrf_token",
"autoescape", "endautoescape", "spaceless", "ssi", "templatetag",
"verbatim", "endverbatim", "widthratio"],
var keywords = ["block", "endblock", "for", "endfor", "true", "false", "filter", "endfilter",
"loop", "none", "self", "super", "if", "elif", "endif", "as", "else", "import",
"with", "endwith", "without", "context", "ifequal", "endifequal", "ifnotequal",
"endifnotequal", "extends", "include", "load", "comment", "endcomment",
"empty", "url", "static", "trans", "blocktrans", "endblocktrans", "now",
"regroup", "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle",
"csrf_token", "autoescape", "endautoescape", "spaceless", "endspaceless",
"ssi", "templatetag", "verbatim", "endverbatim", "widthratio"],
filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
"default", "default_if_none", "dictsort",
"dictsortreversed", "divisibleby", "escape", "escapejs",
Expand Down
6 changes: 4 additions & 2 deletions mode/haml/haml.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@
state.tokenize = rubyInQuote(")");
return state.tokenize(stream, state);
} else if (ch == "{") {
state.tokenize = rubyInQuote("}");
return state.tokenize(stream, state);
if (!stream.match(/^\{%.*/)) {
state.tokenize = rubyInQuote("}");
return state.tokenize(stream, state);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions mode/handlebars/handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
{ regex: /\}\}/, pop: true, token: "tag" },

// Double and single quotes
{ regex: /"(?:[^\\]|\\.)*?"/, token: "string" },
{ regex: /'(?:[^\\]|\\.)*?'/, token: "string" },
{ regex: /"(?:[^\\"]|\\.)*"?/, token: "string" },
{ regex: /'(?:[^\\']|\\.)*'?/, token: "string" },

// Handlebars keywords
{ regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
Expand Down
14 changes: 6 additions & 8 deletions mode/javascript/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"async": kw("async"), "function": kw("function"), "catch": kw("catch"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"await": C, "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
};

// Extend the 'normal' keywords with the TypeScript language extensions
Expand Down Expand Up @@ -121,8 +121,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
} else if (state.lastType == "operator" || state.lastType == "keyword c" ||
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
} else if (/^(?:operator|sof|keyword c|case|new|[\[{}\(,;:])$/.test(state.lastType)) {
readRegexp(stream);
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2");
Expand Down Expand Up @@ -373,7 +372,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {

var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "async") return cont(expression);
if (type == "function") return cont(functiondef, maybeop);
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
Expand Down Expand Up @@ -452,9 +450,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") {cx.marked = "property"; return cont();}
}
function objprop(type, value) {
if (type == "async") {
return cont(objprop);
} else if (type == "variable" || cx.style == "keyword") {
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
return cont(afterprop);
Expand All @@ -465,6 +461,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return cont(afterprop);
} else if (type == "[") {
return cont(expression, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expression);
}
}
function getterSetter(type) {
Expand Down
2 changes: 1 addition & 1 deletion mode/julia/julia.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
if(textAfter=="end" || textAfter=="]" || textAfter=="}" || textAfter=="else" || textAfter=="elseif" || textAfter=="catch" || textAfter=="finally") {
delta = -1;
}
return (state.scopes.length + delta) * 4;
return (state.scopes.length + delta) * _conf.indentUnit;
},

lineComment: "#",
Expand Down
2 changes: 1 addition & 1 deletion mode/markdown/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
f: s.f,

prevLine: s.prevLine,
thisLine: s.this,
thisLine: s.thisLine,

block: s.block,
htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
Expand Down
20 changes: 19 additions & 1 deletion mode/nsis/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,32 @@ <h2>NSIS mode</h2>

OutFile "demo.exe"
RequestExecutionLevel user
SetDetailsPrint listonly

!include "LogicLib.nsh"
!include "WinVer.nsh"

Section -mandatory

Call logWinVer

${If} 1 > 0
MessageBox MB_OK "Hello world"
${EndIf}

SectionEnd

Function logWinVer

${If} ${IsWin10}
DetailPrint "Windows 10!"
${ElseIf} ${AtLeastWinVista}
DetailPrint "We're post-XP"
${Else}
DetailPrint "Legacy system"
${EndIf}

FunctionEnd
</textarea>

<script>
Expand All @@ -59,4 +77,4 @@ <h2>NSIS mode</h2>
</script>

<p><strong>MIME types defined:</strong> <code>text/x-nsis</code>.</p>
</article>
</article>
42 changes: 37 additions & 5 deletions mode/nsis/nsis.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,65 @@ CodeMirror.defineSimpleMode("nsis",{
start:[
// Numbers
{regex: /(?:[+-]?)(?:0x[\d,a-f]+)|(?:0o[0-7]+)|(?:0b[0,1]+)|(?:\d+.?\d*)/, token: "number"},

// Strings
{ regex: /"(?:[^\\"]|\\.)*"?/, token: "string" },
{ regex: /'(?:[^\\']|\\.)*'?/, token: "string" },
{ regex: /`(?:[^\\`]|\\.)*`?/, token: "string" },

// Compile Time Commands
{regex: /(?:\!(include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|finalize|getdllversion|system|tempfile|warning|verbose|define|undef|insertmacro|makensis|searchparse|searchreplace))\b/, token: "keyword"},

// Conditional Compilation
{regex: /(?:\!(if(?:n?def)?|ifmacron?def|macro))\b/, token: "keyword", indent: true},
{regex: /(?:\!(else|endif|macroend))\b/, token: "keyword", dedent: true},

// Runtime Commands
{regex: /(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|IntCmp|IntCmpU|IntFmt|IntOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetPluginUnload|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegStr|WriteUninstaller|XPStyle)\b/, token: "keyword"},
{regex: /\b(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|IntCmp|IntCmpU|IntFmt|IntOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetPluginUnload|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegStr|WriteUninstaller|XPStyle)\b/, token: "keyword"},
{regex: /\b(?:Function|PageEx|Section(?:Group)?)\b/, token: "keyword", indent: true},
{regex: /\b(?:(Function|PageEx|Section(?:Group)?)End)\b/, token: "keyword", dedent: true},
// Options

// Command Options
{regex: /\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\b/, token: "atom"},
{regex: /\b(?:admin|all|auto|both|bottom|bzip2|components|current|custom|directory|force|hide|highest|ifdiff|ifnewer|instfiles|lastused|leave|left|license|listonly|lzma|nevershow|none|normal|notset|right|show|silent|silentlog|textonly|top|try|un\.components|un\.custom|un\.directory|un\.instfiles|un\.license|uninstConfirm|user|Win10|Win7|Win8|WinVista|zlib)\b/, token: "builtin"},

// LogicLib
{regex: /\$\{(?:End(If|Unless|While)|Loop(?:Until)|Next)\}/, token: "variable-2", dedent: true},
{regex: /\$\{(?:Do(Until|While)|Else(?:If(?:Not)?)?|For(?:Each)?|(?:(?:And|Else|Or)?If(?:Cmd|Not|Then)?|Unless)|While)\}/, token: "variable-2", indent: true},
// LogicLib.nsh
{regex: /\$\{(?:And(?:If(?:Not)?|Unless)|Break|Case(?:Else)?|Continue|Default|Do(?:Until|While)?|Else(?:If(?:Not)?|Unless)?|End(?:If|Select|Switch)|Exit(?:Do|For|While)|For(?:Each)?|If(?:Cmd|Not(?:Then)?|Then)?|Loop(?:Until|While)?|Or(?:If(?:Not)?|Unless)|Select|Switch|Unless|While)\}/, token: "variable-2", indent: true},

// FileFunc.nsh
{regex: /\$\{(?:BannerTrimPath|DirState|DriveSpace|Get(BaseName|Drives|ExeName|ExePath|FileAttributes|FileExt|FileName|FileVersion|Options|OptionsS|Parameters|Parent|Root|Size|Time)|Locate|RefreshShellIcons)\}/, token: "variable-2", dedent: true},

// Memento.nsh
{regex: /\$\{(?:Memento(?:Section(?:Done|End|Restore|Save)?|UnselectedSection))\}/, token: "variable-2", dedent: true},

// TextFunc.nsh
{regex: /\$\{(?:Config(?:Read|ReadS|Write|WriteS)|File(?:Join|ReadFromEnd|Recode)|Line(?:Find|Read|Sum)|Text(?:Compare|CompareS)|TrimNewLines)\}/, token: "variable-2", dedent: true},

// WinVer.nsh
{regex: /\$\{(?:(?:At(?:Least|Most)|Is)(?:ServicePack|Win(?:7|8|10|95|98|200(?:0|3|8(?:R2)?)|ME|NT4|Vista|XP))|Is(?:NT|Server))\}/, token: "variable", dedent: true},

// WordFunc.nsh
{regex: /\$\{(?:StrFilterS?|Version(?:Compare|Convert)|Word(?:AddS?|Find(?:(?:2|3)X)?S?|InsertS?|ReplaceS?))\}/, token: "variable-2", dedent: true},

// x64.nsh
{regex: /\$\{(?:RunningX64)\}/, token: "variable", dedent: true},
{regex: /\$\{(?:Disable|Enable)X64FSRedirection\}/, token: "variable-2", dedent: true},

// Line Comment
{regex: /(#|;).*/, token: "comment"},

// Block Comment
{regex: /\/\*/, token: "comment", next: "comment"},

// Operator
{regex: /[-+\/*=<>!]+/, token: "operator"},

// Variable
{regex: /\$[\w]+/, token: "variable"},

// Constant
{regex: /\${[\w]+}/,token: "variable-2"},

// Language String
{regex: /\$\([\w]+\)/,token: "variable-3"}
],
Expand Down
45 changes: 17 additions & 28 deletions mode/python/python.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@
CodeMirror.defineMode("python", function(conf, parserConf) {
var ERRORCLASS = "error";

var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]");
var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/|\*\*)/;
var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/;
var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/;

if (parserConf.version && parseInt(parserConf.version, 10) == 3){
// since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!@]");
var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*");
var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
} else {
var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
}

var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
Expand Down Expand Up @@ -160,13 +160,16 @@

// Handle operators and Delimiters
if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
return null;
return "punctuation";

if (stream.match(doubleOperators) || stream.match(singleOperators))
return "operator";

if (stream.match(singleDelimiters))
return null;
return "punctuation";

if (state.lastToken == "." && stream.match(identifiers))
return "property";

if (stream.match(keywords) || stream.match(wordOperators))
return "keyword";
Expand Down Expand Up @@ -246,17 +249,6 @@
var style = state.tokenize(stream, state);
var current = stream.current();

// Handle '.' connected identifiers
if (current == ".") {
style = stream.match(identifiers, false) ? null : ERRORCLASS;
if (style == null && state.lastStyle == "meta") {
// Apply 'meta' style to '.' connected identifiers when
// appropriate.
style = "meta";
}
return style;
}

// Handle decorators
if (current == "@"){
if(parserConf.version && parseInt(parserConf.version, 10) == 3){
Expand All @@ -267,7 +259,7 @@
}

if ((style == "variable" || style == "builtin")
&& state.lastStyle == "meta")
&& state.lastToken == "meta")
style = "meta";

// Handle scope changes.
Expand Down Expand Up @@ -300,7 +292,6 @@
return {
tokenize: tokenBase,
scopes: [{offset: basecolumn || 0, type: "py", align: null}],
lastStyle: null,
lastToken: null,
lambda: false,
dedent: 0
Expand All @@ -312,11 +303,9 @@
if (addErr) state.errorToken = false;
var style = tokenLexer(stream, state);

state.lastStyle = style;

var current = stream.current();
if (current && style)
state.lastToken = current;
if (style && style != "comment")
state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
if (style == "punctuation") style = null;

if (stream.eol() && state.lambda)
state.lambda = false;
Expand Down
19 changes: 16 additions & 3 deletions mode/rust/rust.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
"use strict";

CodeMirror.defineSimpleMode("rust",{
start:[
start: [
// string and byte string
{regex: /b?"(?:[^\\]|\\.)*?"/, token: "string"},
{regex: /b?"/, token: "string", next: "string"},
// raw string and raw byte string
{regex: /(b?r)(#*)(".*?)("\2)/, token: ["string", "string", "string", "string"]},
{regex: /b?r"/, token: "string", next: "string_raw"},
{regex: /b?r#+"/, token: "string", next: "string_raw_hash"},
// character
{regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"},
// byte
Expand All @@ -39,6 +40,18 @@ CodeMirror.defineSimpleMode("rust",{
{regex: /[\{\[\(]/, indent: true},
{regex: /[\}\]\)]/, dedent: true}
],
string: [
{regex: /"/, token: "string", next: "start"},
{regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"}
],
string_raw: [
{regex: /"/, token: "string", next: "start"},
{regex: /[^"]*/, token: "string"}
],
string_raw_hash: [
{regex: /"#+/, token: "string", next: "start"},
{regex: /(?:[^"]|"(?!#))*/, token: "string"}
],
comment: [
{regex: /.*?\*\//, token: "comment", next: "start"},
{regex: /.*/, token: "comment"}
Expand Down
1 change: 0 additions & 1 deletion mode/rust/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
'[string "\\"foo\\""]',
'[string r#""foo""#]',
'[string "foo #\\"# bar"]',
'[string r##"foo #"# bar"##]',

'[string b"foo"]',
'[string br"foo"]',
Expand Down
2 changes: 1 addition & 1 deletion mode/sql/sql.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
}

// these keywords are used by all SQL dialects (however, a mode can still overwrite it)
var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where ";
var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit";

// turn a space-separated list into an array
function set(str) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version":"5.8.0",
"version":"5.9.0",
"main": "lib/codemirror.js",
"description": "In-browser code editing made bearable",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion test/emacs_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
var code;
for (var c in CodeMirror.keyNames)
if (CodeMirror.keyNames[c] == key) { code = c; break; }
if (c == null) throw new Error("Unknown key: " + key);
if (code == null) throw new Error("Unknown key: " + key);

return eventCache[keyName] = {
type: "keydown", keyCode: code, ctrlKey: ctrl, shiftKey: shift, altKey: alt,
Expand Down
4 changes: 2 additions & 2 deletions test/scroll_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
function barV(cm) { return byClassName(cm.getWrapperElement(), "CodeMirror-vscrollbar")[0]; }

function displayBottom(cm, scrollbar) {
if (scrollbar)
if (scrollbar && cm.display.scroller.offsetHeight > cm.display.scroller.clientHeight)
return barH(cm).getBoundingClientRect().top;
else
return cm.getWrapperElement().getBoundingClientRect().bottom - 1;
}

function displayRight(cm, scrollbar) {
if (scrollbar)
if (scrollbar && cm.display.scroller.offsetWidth > cm.display.scroller.clientWidth)
return barV(cm).getBoundingClientRect().left;
else
return cm.getWrapperElement().getBoundingClientRect().right - 1;
Expand Down
8 changes: 4 additions & 4 deletions theme/material.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
.cm-s-material .cm-atom { color: #F77669; }
.cm-s-material .cm-number { color: #F77669; }
.cm-s-material .cm-def { color: rgba(233, 237, 237, 1); }
.cm-s-material .cm-error {
color: rgba(255, 255, 255, 1.0);
background-color: #EC5F67;
}
.cm-s-material .cm-string { color: #C3E88D; }
.cm-s-material .cm-string-2 { color: #80CBC4; }
.cm-s-material .cm-comment { color: #546E7A; }
Expand All @@ -47,6 +43,10 @@
.cm-s-material .cm-qualifier { color: #DECB6B; }
.cm-s-material .cm-variable-3 { color: #DECB6B; }
.cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); }
.cm-s-material .cm-error {
color: rgba(255, 255, 255, 1.0);
background-color: #EC5F67;
}
.cm-s-material .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
Expand Down