diff --git a/lib/ace/mode/sqlserver_highlight_rules.js b/lib/ace/mode/sqlserver_highlight_rules.js index 84af7656..06cd063b 100644 --- a/lib/ace/mode/sqlserver_highlight_rules.js +++ b/lib/ace/mode/sqlserver_highlight_rules.js @@ -36,6 +36,7 @@ var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var SqlServerHighlightRules = function() { /** + * Transact-SQL Syntax Conventions: https://msdn.microsoft.com/en-us/library/ms177563.aspx * each section has a link and some javacript code. * go to the link, open dev tools, run code to get the string. * @@ -45,7 +46,7 @@ var SqlServerHighlightRules = function() { // https://msdn.microsoft.com/en-us/library/ms189773.aspx var logicalOperators = "ALL|AND|ANY|BETWEEN|EXISTS|IN|LIKE|NOT|OR|SOME"; - logicalOperators+= "|NULL";//SSMS colors this gray too + logicalOperators+= "|NULL|IS";//SSMS colors these gray too @@ -92,26 +93,15 @@ var SqlServerHighlightRules = function() { ); - //https://msdn.microsoft.com/en-us/library/ms190356.aspx - // var r = []; $('.tableSection').find('td').find('a').each(function() { var t = $(this).text().trim().toUpperCase(); r.push($(this).text().trim().toUpperCase()); }); r = r.filter(function(value, index, self) { return self.indexOf(value) === index; }); r.sort(); console.log(r.join('|')); - var setStatements = "SET ANSI_DEFAULTS|SET ANSI_NULLS|SET ANSI_NULL_DFLT_OFF|SET ANSI_NULL_DFLT_ON|SET ANSI_PADDING|SET ANSI_WARNINGS|SET ARITHABORT|SET ARITHIGNORE|SET CONCAT_NULL_YIELDS_NULL|SET CURSOR_CLOSE_ON_COMMIT|SET DATEFIRST|SET DATEFORMAT|SET DEADLOCK_PRIORITY|SET FIPS_FLAGGER|SET FMTONLY|SET FORCEPLAN|SET IDENTITY_INSERT|SET IMPLICIT_TRANSACTIONS|SET LANGUAGE|SET LOCK_TIMEOUT|SET NOCOUNT|SET NOEXEC|SET NUMERIC_ROUNDABORT|SET OFFSETS|SET PARSEONLY|SET QUERY_GOVERNOR_COST_LIMIT|SET QUOTED_IDENTIFIER|SET REMOTE_PROC_TRANSACTIONS|SET ROWCOUNT|SET SHOWPLAN_ALL|SET SHOWPLAN_TEXT|SET SHOWPLAN_XML|SET STATISTICS IO|SET STATISTICS PROFILE|SET STATISTICS TIME|SET STATISTICS XML|SET TEXTSIZE|SET TRANSACTION ISOLATION LEVEL|SET XACT_ABORT"; - - // https://msdn.microsoft.com/en-us/library/ms189822.aspx // var r = []; $('.tableSection').find('td').each(function() { r.push($(this).text().trim()); }); r = r.filter(function(value, index, self) { return self.indexOf(value) === index; }); r.sort(); console.log(r.join('|')); var keywords = "ABSOLUTE|ACTION|ADA|ADD|ADMIN|AFTER|AGGREGATE|ALIAS|ALL|ALLOCATE|ALTER|AND|ANY|ARE|ARRAY|AS|ASC|ASENSITIVE|ASSERTION|ASYMMETRIC|AT|ATOMIC|AUTHORIZATION|BACKUP|BEFORE|BEGIN|BETWEEN|BIT_LENGTH|BLOB|BOOLEAN|BOTH|BREADTH|BREAK|BROWSE|BULK|BY|CALL|CALLED|CARDINALITY|CASCADE|CASCADED|CASE|CATALOG|CHARACTER|CHARACTER_LENGTH|CHAR_LENGTH|CHECK|CHECKPOINT|CLASS|CLOB|CLOSE|CLUSTERED|COALESCE|COLLATE|COLLATION|COLLECT|COLUMN|COMMIT|COMPLETION|COMPUTE|CONDITION|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONSTRUCTOR|CONTAINS|CONTAINSTABLE|CONTINUE|CORR|CORRESPONDING|COVAR_POP|COVAR_SAMP|CREATE|CROSS|CUBE|CUME_DIST|CURRENT|CURRENT_CATALOG|CURRENT_DATE|CURRENT_DEFAULT_TRANSFORM_GROUP|CURRENT_PATH|CURRENT_ROLE|CURRENT_SCHEMA|CURRENT_TIME|CURRENT_TRANSFORM_GROUP_FOR_TYPE|CYCLE|DATA|DATABASE|DBCC|DEALLOCATE|DEC|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DENY|DEPTH|DEREF|DESC|DESCRIBE|DESCRIPTOR|DESTROY|DESTRUCTOR|DETERMINISTIC|DIAGNOSTICS|DICTIONARY|DISCONNECT|DISK|DISTINCT|DISTRIBUTED|DOMAIN|DOUBLE|DROP|DUMP|DYNAMIC|EACH|ELEMENT|ELSE|END|END-EXEC|EQUALS|ERRLVL|ESCAPE|EVERY|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXISTS|EXIT|EXTERNAL|EXTRACT|FETCH|FILE|FILLFACTOR|FILTER|FIRST|FOR|FOREIGN|FORTRAN|FOUND|FREE|FREETEXT|FREETEXTTABLE|FROM|FULL|FULLTEXTTABLE|FUNCTION|FUSION|GENERAL|GET|GLOBAL|GO|GOTO|GRANT|GROUP|HAVING|HOLD|HOLDLOCK|HOST|HOUR|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IGNORE|IMMEDIATE|IN|INCLUDE|INDEX|INDICATOR|INITIALIZE|INITIALLY|INNER|INOUT|INPUT|INSENSITIVE|INSERT|INTEGER|INTERSECT|INTERSECTION|INTERVAL|INTO|IS|ISOLATION|ITERATE|JOIN|KEY|KILL|LANGUAGE|LARGE|LAST|LATERAL|LEADING|LESS|LEVEL|LIKE|LIKE_REGEX|LIMIT|LINENO|LN|LOAD|LOCAL|LOCALTIME|LOCALTIMESTAMP|LOCATOR|MAP|MATCH|MEMBER|MERGE|METHOD|MINUTE|MOD|MODIFIES|MODIFY|MODULE|MULTISET|NAMES|NATIONAL|NATURAL|NCLOB|NEW|NEXT|NO|NOCHECK|NONCLUSTERED|NONE|NORMALIZE|NOT|NULL|NULLIF|OBJECT|OCCURRENCES_REGEX|OCTET_LENGTH|OF|OFF|OFFSETS|OLD|ON|ONLY|OPEN|OPERATION|OPTION|OR|ORDER|ORDINALITY|OUT|OUTER|OUTPUT|OVER|OVERLAPS|OVERLAY|PAD|PARAMETER|PARAMETERS|PARTIAL|PARTITION|PASCAL|PATH|PERCENT|PERCENTILE_CONT|PERCENTILE_DISC|PERCENT_RANK|PIVOT|PLAN|POSITION|POSITION_REGEX|POSTFIX|PRECISION|PREFIX|PREORDER|PREPARE|PRESERVE|PRIMARY|PRINT|PRIOR|PRIVILEGES|PROC|PROCEDURE|PUBLIC|RAISERROR|RANGE|READ|READS|READTEXT|RECONFIGURE|RECURSIVE|REF|REFERENCES|REFERENCING|REGR_AVGX|REGR_AVGY|REGR_COUNT|REGR_INTERCEPT|REGR_R2|REGR_SLOPE|REGR_SXX|REGR_SXY|REGR_SYY|RELATIVE|RELEASE|REPLICATION|RESTORE|RESTRICT|RESULT|RETURN|RETURNS|REVERT|REVOKE|ROLE|ROLLBACK|ROLLUP|ROUTINE|ROW|ROWCOUNT|ROWGUIDCOL|ROWS|RULE|SAVE|SAVEPOINT|SCHEMA|SCOPE|SCROLL|SEARCH|SECOND|SECTION|SECURITYAUDIT|SELECT|SEMANTICKEYPHRASETABLE|SEMANTICSIMILARITYDETAILSTABLE|SEMANTICSIMILARITYTABLE|SENSITIVE|SEQUENCE|SESSION|SET|SETS|SETUSER|SHUTDOWN|SIMILAR|SIZE|SOME|SPECIFIC|SPECIFICTYPE|SQL|SQLCA|SQLCODE|SQLERROR|SQLEXCEPTION|SQLSTATE|SQLWARNING|START|STATE|STATEMENT|STATIC|STATISTICS|STDDEV_POP|STDDEV_SAMP|STRUCTURE|SUBMULTISET|SUBSTRING_REGEX|SYMMETRIC|SYSTEM|TABLESAMPLE|TEMPORARY|TERMINATE|TEXTSIZE|THAN|THEN|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TOP|TRAILING|TRAN|TRANSACTION|TRANSLATE|TRANSLATE_REGEX|TRANSLATION|TREAT|TRIGGER|TRIM|TRUNCATE|TSEQUAL|UESCAPE|UNDER|UNION|UNIQUE|UNKNOWN|UNNEST|UNPIVOT|UPDATE|UPDATETEXT|USAGE|USE|USER|USING|VALUE|VALUES|VARIABLE|VARYING|VAR_POP|VAR_SAMP|VIEW|WAITFOR|WHEN|WHENEVER|WHERE|WHILE|WIDTH_BUCKET|WINDOW|WITH|WITHIN|WITHIN GROUP|WITHOUT|WORK|WRITE|WRITETEXT|XMLAGG|XMLATTRIBUTES|XMLBINARY|XMLCAST|XMLCOMMENT|XMLCONCAT|XMLDOCUMENT|XMLELEMENT|XMLEXISTS|XMLFOREST|XMLITERATE|XMLNAMESPACES|XMLPARSE|XMLPI|XMLQUERY|XMLSERIALIZE|XMLTABLE|XMLTEXT|XMLVALIDATE|ZONE"; - //add isolation levels https://msdn.microsoft.com/en-us/library/ms173763.aspx - keywords += "|UNCOMMITTED|COMMITTED|REPEATABLE|SNAPSHOP|SERIALIZABLE"; - - //add each part of set statement to keywords for highlighting, yet keep set statements as is for code completion - //NOTE: there is likely a better way to do this but I don't fully understand the syntax highlighting part yet - /*var eachSet = setStatements.split('|'); - eachSet.forEach(function(v) { - v.split(' ').forEach(function(v) { - keywords += '|' + v; - }); - });*/ + //add table hints and query hints (many overlap): https://msdn.microsoft.com/en-us/library/ms187373.aspx + // https://msdn.microsoft.com/en-us/library/ms181714.aspx + keywords+= "|KEEPIDENTITY|KEEPDEFAULTS|IGNORE_CONSTRAINTS|IGNORE_TRIGGERS|XLOCK|FORCESCAN|FORCESEEK|HOLDLOCK|NOLOCK|NOWAIT|PAGLOCK|READCOMMITTED|READCOMMITTEDLOCK|READPAST|READUNCOMMITTED|REPEATABLEREAD|ROWLOCK|SERIALIZABLE|SNAPSHOT|SPATIAL_WINDOW_MAX_CELLS|TABLOCK|TABLOCKX|UPDLOCK|XLOCK|IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX|EXPAND|VIEWS|FAST|FORCE|KEEP|KEEPFIXED|MAXDOP|MAXRECURSION|OPTIMIZE|PARAMETERIZATION|SIMPLE|FORCED|RECOMPILE|ROBUST|PLAN|SPATIAL_WINDOW_MAX_CELLS|NOEXPAND|HINT"; + //add join hints: https://msdn.microsoft.com/en-us/library/ms173815.aspx + keywords+= "|LOOP|HASH|MERGE|REMOTE"; //remove any other built in things from key word list @@ -128,18 +118,6 @@ var SqlServerHighlightRules = function() { "storage.type": dataTypes }, "identifier", true); - //store keywordList created by createKeywordMapper so we can merge it with second call - var keywordList = this.$keywordList; - - var statementMapper = this.createKeywordMapper({ - "keyword.set": setStatements, - }, "identifier", true); - - //merge first keyword list back in - for (var i = 0; i < keywordList.length; i++) { - this.$keywordList.push(keywordList[i]); - } - // createKeywordMapper ignores case which we want because SqlServer keywords are not case sensitive which // causes our keywords to get changed to lowercase. // However, the preferred standard for keywords is uppercase, so this transforms them back to uppercase for code completion @@ -147,12 +125,19 @@ var SqlServerHighlightRules = function() { this.$keywordList[i] = this.$keywordList[i].toUpperCase(); } - var originalStatementMapper = statementMapper; - statementMapper= function(value){ - var r = originalStatementMapper(value); - console.log('value: ' + value + '\tresult: ' + r); - return r; - }; + + //https://msdn.microsoft.com/en-us/library/ms190356.aspx + // var r = []; $('.tableSection').find('td').find('a').each(function() { var t = $(this).text().trim().toUpperCase(); r.push($(this).text().trim().toUpperCase()); }); r = r.filter(function(value, index, self) { return self.indexOf(value) === index; }); r.sort(); console.log(r.join('|')); + var setStatements = "SET ANSI_DEFAULTS|SET ANSI_NULLS|SET ANSI_NULL_DFLT_OFF|SET ANSI_NULL_DFLT_ON|SET ANSI_PADDING|SET ANSI_WARNINGS|SET ARITHABORT|SET ARITHIGNORE|SET CONCAT_NULL_YIELDS_NULL|SET CURSOR_CLOSE_ON_COMMIT|SET DATEFIRST|SET DATEFORMAT|SET DEADLOCK_PRIORITY|SET FIPS_FLAGGER|SET FMTONLY|SET FORCEPLAN|SET IDENTITY_INSERT|SET IMPLICIT_TRANSACTIONS|SET LANGUAGE|SET LOCK_TIMEOUT|SET NOCOUNT|SET NOEXEC|SET NUMERIC_ROUNDABORT|SET OFFSETS|SET PARSEONLY|SET QUERY_GOVERNOR_COST_LIMIT|SET QUOTED_IDENTIFIER|SET REMOTE_PROC_TRANSACTIONS|SET ROWCOUNT|SET SHOWPLAN_ALL|SET SHOWPLAN_TEXT|SET SHOWPLAN_XML|SET STATISTICS IO|SET STATISTICS PROFILE|SET STATISTICS TIME|SET STATISTICS XML|SET TEXTSIZE|SET XACT_ABORT".split('|'); + + var isolationLevels = "READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SNAPSHOP|SERIALIZABLE".split('|'); + for (var i = 0; i < isolationLevels.length; i++) { + setStatements.push('SET TRANSACTION ISOLATION LEVEL ' + isolationLevels[i]); + } + //add set statements to keywordList for completions + for (var i = 0; i < setStatements.length; i++) { + this.$keywordList.push(setStatements[i]); + } this.$rules = { "start": [{ @@ -162,22 +147,16 @@ var SqlServerHighlightRules = function() { token: "comment", start: "/\\*", end: "\\*/" - }, { - token: "string", // " string - regex: '".*?"' }, { token: "string", // ' string regex: "'.*?'" }, { token: "constant.numeric", // float regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token: statementMapper, - regex: "SET [a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { token: keywordMapper, regex: "@{0,2}[a-zA-Z_$][a-zA-Z0-9_$]*\\b" //up to 2 @symbols for some build in functions - },{ + }, { token: "constant.class", regex: "@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { @@ -190,13 +169,22 @@ var SqlServerHighlightRules = function() { }, { token: "paren.rparen", regex: "[\\)]" - } - /*, { - token : "text", - regex : "\\s+" - }*/ - ] + }, { + token: "text", + regex: "\\s+" + }] }; + + //add each set statment as regex at top of rules so that they are processed first because they require multiple words + //note, this makes the statements not match if they are not upper case.. which is not ideal but I don't know of an easy way to fix this + for (var i = 0; i < setStatements.length; i++) { + var statement = setStatements[i]; + this.$rules.start.unshift({ + token: "set.statement", + regex: statement //"("+statement+")(| ON| OFF)"// new RegExp(statement, 'i') + }); + } + this.normalizeRules(); }; @@ -204,4 +192,3 @@ oop.inherits(SqlServerHighlightRules, TextHighlightRules); exports.SqlHighlightRules = SqlServerHighlightRules; }); - diff --git a/lib/ace/theme/sqlserver.css b/lib/ace/theme/sqlserver.css index 0151a998..65659516 100644 --- a/lib/ace/theme/sqlserver.css +++ b/lib/ace/theme/sqlserver.css @@ -42,9 +42,12 @@ border: 1px solid magenta; } - - - +.ace-sqlserver .ace_set.ace_statement{ + /*color: #11B7BE;*/ + color: #0000FF; + /*font-style:italic;*/ + text-decoration:underline; +} .ace-sqlserver .ace_cursor {