Merge pull request #2460 from sevin7676/master

SQL Server typos and keyword completion modifier
This commit is contained in:
Harutyun Amirjanyan 2015-04-23 18:11:41 +04:00
commit 65ad04082f
4 changed files with 81 additions and 43 deletions

View file

@ -1,9 +1,9 @@
-- ============================================= -- =============================================
-- Author: Morgan Yarbrough -- Author: Morgan Yarbrough
-- Create date: 4/27/2015 -- Create date: 4/27/2015
-- Description: Test Procedure that shows off language features. -- Description: Test procedure that shows off language features.
-- Includes non-standard folding using region comments using either -- Includes non-standard folding with region comments using either
-- line comments or block comments (both are demonstrated below) -- line comments or block comments (both are demonstrated below).
-- This mode imitates SSMS and it designed to be used with SQL Server theme. -- This mode imitates SSMS and it designed to be used with SQL Server theme.
-- ============================================= -- =============================================
CREATE PROCEDURE dbo.TestProcedure CREATE PROCEDURE dbo.TestProcedure
@ -11,7 +11,7 @@ CREATE PROCEDURE dbo.TestProcedure
--#region parameters --#region parameters
@vint INT = 1 @vint INT = 1
,@vdate DATE = NULL ,@vdate DATE = NULL
,@vdatetime DATETIME = DATEADD (dd, 1, GETDATE()) ,@vdatetime DATETIME = DATEADD(dd, 1, GETDATE())
,@vvarchar VARCHAR(MAX) = '' ,@vvarchar VARCHAR(MAX) = ''
--#endregion --#endregion
@ -38,8 +38,8 @@ BEGIN
-- another folding demonstration -- another folding demonstration
IF @vint = 1 IF @vint = 1
BEGIN BEGIN
SET @vvarchar='one' SET @vvarchar = 'one'
SET @vint = DATEDIFFT(dd, @vdate, @vdatetime) SET @vint = DATEDIFF(dd, @vdate, @vdatetime)
END END
-- this mode handles strings properly -- this mode handles strings properly
@ -47,7 +47,7 @@ BEGIN
FROM Orders FROM Orders
WHERE @OrderDate > GETDATE()' WHERE @OrderDate > GETDATE()'
-- this mode is aware of build in stored procedures -- this mode is aware of built in stored procedures
EXECUTE sp_executesql @sql EXECUTE sp_executesql @sql
-- demonstrating some syntax highlighting -- demonstrating some syntax highlighting
@ -60,4 +60,13 @@ BEGIN
WHERE CompanyName NOT LIKE '%something' WHERE CompanyName NOT LIKE '%something'
OR CompanyName IS NULL OR CompanyName IS NULL
OR CompanyName IN ('bla', 'nothing') OR CompanyName IN ('bla', 'nothing')
-- this mode includes snippets
-- place your cusor at the end of the line below and trigger auto complete (Ctrl+Space)
createpr
-- SQL Server allows using keywords as object names (not recommended) as long as they are wrapped in brackets
DATABASE -- keyword
[DATABASE] -- not a keyword
END END

View file

@ -47,6 +47,13 @@ oop.inherits(Mode, TextMode);
this.lineCommentStart = "--"; this.lineCommentStart = "--";
this.blockComment = {start: "/*", end: "*/"}; this.blockComment = {start: "/*", end: "*/"};
/**
* Override keyword completions using list created in highlight rules
*/
this.getCompletions = function(state, session, pos, prefix) {
return session.$mode.$highlightRules.completions;
};
this.$id = "ace/mode/sql"; this.$id = "ace/mode/sql";
}).call(Mode.prototype); }).call(Mode.prototype);

View file

@ -77,7 +77,9 @@ var SqlServerHighlightRules = function() {
/* https://msdn.microsoft.com/en-us/library/ms177520.aspx */ /* https://msdn.microsoft.com/en-us/library/ms177520.aspx */
"@@CONNECTIONS|@@CPU_BUSY|@@IDLE|@@IO_BUSY|@@PACKET_ERRORS|@@PACK_RECEIVED|@@PACK_SENT|@@TIMETICKS|@@TOTAL_ERRORS|@@TOTAL_READ|@@TOTAL_WRITE|FN_VIRTUALFILESTATS|" + "@@CONNECTIONS|@@CPU_BUSY|@@IDLE|@@IO_BUSY|@@PACKET_ERRORS|@@PACK_RECEIVED|@@PACK_SENT|@@TIMETICKS|@@TOTAL_ERRORS|@@TOTAL_READ|@@TOTAL_WRITE|FN_VIRTUALFILESTATS|" +
/* https://msdn.microsoft.com/en-us/library/ms188353.aspx */ /* https://msdn.microsoft.com/en-us/library/ms188353.aspx */
"PATINDEX|TEXTPTR|TEXTVALID" "PATINDEX|TEXTPTR|TEXTVALID|" +
/* other */
"COALESCE|NULLIF"
); );
@ -104,12 +106,14 @@ var SqlServerHighlightRules = function() {
keywords += "|TYPE"; keywords += "|TYPE";
//remove any other built in things from key word list //remove specific built in types from keyword list
keywords = keywords.split('|'); keywords = keywords.split('|');
keywords = keywords.filter(function(value, index, self) { keywords = keywords.filter(function(value, index, self) {
return logicalOperators.split('|').indexOf(value) === -1 && builtinFunctions.split('|').indexOf(value) === -1 && dataTypes.split('|').indexOf(value) === -1; return logicalOperators.split('|').indexOf(value) === -1 && builtinFunctions.split('|').indexOf(value) === -1 && dataTypes.split('|').indexOf(value) === -1;
}); });
keywords = keywords.sort().join('|'); keywords = keywords.sort().join('|');
var keywordMapper = this.createKeywordMapper({ var keywordMapper = this.createKeywordMapper({
"constant.language": logicalOperators, "constant.language": logicalOperators,
"storage.type": dataTypes, "storage.type": dataTypes,
@ -119,26 +123,12 @@ var SqlServerHighlightRules = function() {
}, "identifier", true); }, "identifier", true);
// 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
// EXCEPTION: build in stored procedures are lower case
for (var i = 0; i < this.$keywordList.length; i++) {
var keyword = this.$keywordList[i];
if (builtInStoredProcedures.indexOf(keyword) !== -1) continue;
this.$keywordList[i] = keyword.toUpperCase();
}
//https://msdn.microsoft.com/en-us/library/ms190356.aspx //https://msdn.microsoft.com/en-us/library/ms190356.aspx
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 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('|'); var isolationLevels = "READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SNAPSHOP|SERIALIZABLE".split('|');
for (var i = 0; i < isolationLevels.length; i++) { for (var i = 0; i < isolationLevels.length; i++) {
setStatements.push('SET TRANSACTION ISOLATION LEVEL ' + isolationLevels[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 = { this.$rules = {
@ -147,7 +137,7 @@ var SqlServerHighlightRules = function() {
regex: "'", regex: "'",
next: [{ next: [{
token: "constant.language.escape", token: "constant.language.escape",
regex: /\\'/ regex: /''/
}, { }, {
token: "string.end", token: "string.end",
next: "start", next: "start",
@ -163,15 +153,12 @@ var SqlServerHighlightRules = function() {
token: "comment", token: "comment",
start: "/\\*", start: "/\\*",
end: "\\*/" end: "\\*/"
}, {
token: "string", // ' string
regex: "'.*?'"
}, { }, {
token: "constant.numeric", // float token: "constant.numeric", // float
regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
}, { }, {
token: keywordMapper, token: keywordMapper,
regex: "@{0,2}[a-zA-Z_$][a-zA-Z0-9_$]*\\b" //up to 2 @symbols for some build in functions regex: "@{0,2}[a-zA-Z_$][a-zA-Z0-9_$]*\\b(?!])" //up to 2 @symbols for some built in functions
}, { }, {
token: "constant.class", token: "constant.class",
regex: "@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\b" regex: "@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
@ -204,18 +191,39 @@ var SqlServerHighlightRules = function() {
}; };
//add each set statment as regex at top of rules so that they are processed first because they require multiple words //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 //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++) { for (var i = 0; i < setStatements.length; i++) {
var statement = setStatements[i];
this.$rules.start.unshift({ this.$rules.start.unshift({
token: "set.statement", token: "set.statement",
regex: statement regex: setStatements[i]
}); });
} }
this.embedRules(DocCommentHighlightRules, "doc-", [DocCommentHighlightRules.getEndRule("start")]); this.embedRules(DocCommentHighlightRules, "doc-", [DocCommentHighlightRules.getEndRule("start")]);
this.normalizeRules(); this.normalizeRules();
//prepare custom keyword completions used by mode to override default completor
//this allows for custom 'meta' and proper case of completions
var completions = [];
var addCompletions = function(arr, meta) {
arr.forEach(function(v) {
completions.push({
name: v,
value: v,
score: 0,
meta: meta,
});
});
};
addCompletions(builtInStoredProcedures.split('|'), 'procedure');
addCompletions(logicalOperators.split('|'), 'operator');
addCompletions(builtinFunctions.split('|'), 'function');
addCompletions(dataTypes.split('|'), 'type');
addCompletions(setStatements, 'statement');
addCompletions(keywords.split('|'), 'keyword');
this.completions = completions;
}; };
oop.inherits(SqlServerHighlightRules, TextHighlightRules); oop.inherits(SqlServerHighlightRules, TextHighlightRules);

View file

@ -22,6 +22,16 @@ snippet dateadd
# DATEFROMPARTS # DATEFROMPARTS
snippet datefromparts snippet datefromparts
DATEFROMPARTS(${1:year}, ${2:month}, ${3:day}) DATEFROMPARTS(${1:year}, ${2:month}, ${3:day})
# OBJECT_DEFINITION
snippet objectdef
SELECT OBJECT_DEFINITION(OBJECT_ID('${1:sys.server_permissions /*object name*/}'))
# STUFF XML
snippet stuffxml
STUFF((SELECT ', ' + ${1:ColumnName}
FROM ${2:TableName}
WHERE ${3:WhereClause}
FOR XML PATH('')), 1, 1, '') AS ${4:Alias}
${5:/*https://msdn.microsoft.com/en-us/library/ms188043.aspx*/}
# Create Procedure # Create Procedure
snippet createproc snippet createproc
-- ============================================= -- =============================================
@ -30,12 +40,14 @@ snippet createproc
-- Description: ${3:Description} -- Description: ${3:Description}
-- ============================================= -- =============================================
CREATE PROCEDURE ${4:Procedure_Name} CREATE PROCEDURE ${4:Procedure_Name}
-- Add the parameters for the stored procedure here ${5:/*Add the parameters for the stored procedure here*/}
AS AS
BEGIN BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements. -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
SET NOCOUNT ON; SET NOCOUNT ON;
${6:/*Add the T-SQL statements to compute the return value here*/}
END END
GO GO
# Create Scalar Function # Create Scalar Function
@ -52,5 +64,7 @@ snippet createfn
BEGIN BEGIN
DECLARE @Result ${5:Function_Data_Type} DECLARE @Result ${5:Function_Data_Type}
${6:/*Add the T-SQL statements to compute the return value here*/}
END END
GO GO