From 27ad4324c3b6177201106ec85dd4a6425cb072c2 Mon Sep 17 00:00:00 2001 From: cweijan Date: Fri, 10 Apr 2020 21:57:20 +0800 Subject: [PATCH] implment complection fully --- src/database/QueryUnit.ts | 2 +- src/extension.ts | 2 +- src/provider/Complection/chain/columnChain.ts | 15 +++++++---- .../Complection/chain/databaseChain.ts | 4 +-- .../Complection/chain/functionChain.ts | 13 +++++++++- .../Complection/chain/tableDetecherChain.ts | 25 +++++++++++++++---- .../Complection/complectionContext.ts | 9 +++++-- tsconfig.json | 3 ++- 8 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/database/QueryUnit.ts b/src/database/QueryUnit.ts index 765d282..a8d3ea5 100644 --- a/src/database/QueryUnit.ts +++ b/src/database/QueryUnit.ts @@ -112,7 +112,7 @@ export class QueryUnit { for (let sql of sqlList) { index += (sql.length + 1) if (doc_cursor < index) { - return sql.trim() + ";"; + return sql.trim(); } } diff --git a/src/extension.ts b/src/extension.ts index 23cffc3..c03176e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -46,7 +46,7 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.languages.registerDocumentRangeFormattingEditProvider('sql', new SqlFormatProvider()), vscode.languages.registerHoverProvider('sql', new TableHoverProvider()), - vscode.languages.registerCompletionItemProvider('sql', new CompletionProvider(), ' ', '.'), + vscode.languages.registerCompletionItemProvider('sql', new CompletionProvider(), ' ', '.',">","<","=","("), vscode.commands.registerCommand(CommandKey.Refresh, () => { mysqlTreeDataProvider.init() }), diff --git a/src/provider/Complection/chain/columnChain.ts b/src/provider/Complection/chain/columnChain.ts index 09e025a..3e93b95 100644 --- a/src/provider/Complection/chain/columnChain.ts +++ b/src/provider/Complection/chain/columnChain.ts @@ -9,11 +9,16 @@ export class ColumnChain implements ComplectionChain { if (complectionContext.preChart === ".") { let subComplectionItems = await this.generateColumnComplectionItem(complectionContext.preWord); - const tableReg = new RegExp("`{0,1}(\\w|-)+`{0,1}(?=\\s*\\b" + complectionContext.preWord + "\\b)", "ig"); - let result = tableReg.exec(complectionContext.currentSql); + const tableReg = new RegExp("\\b(from|join)\\b\\s*`{0,1}(\\w|\.|-)+`{0,1}(?=\\s*\\b" + complectionContext.preWord + "\\b)", "ig"); + let result = tableReg.exec(complectionContext.currentSqlFull); for (; result != null && subComplectionItems.length === 0;) { - subComplectionItems = await this.generateColumnComplectionItem(result[0].replace(/`/ig, "")); - result = tableReg.exec(complectionContext.currentSql); + subComplectionItems = await this.generateColumnComplectionItem( + result[0].trim().replace(/(\w|\s)*\./, "").replace(/`/ig, "") + ); + if (subComplectionItems.length > 0) { + break; + } + result = tableReg.exec(complectionContext.currentSqlFull); } return subComplectionItems; } @@ -43,7 +48,7 @@ export class ColumnChain implements ComplectionChain { const completionItem = new vscode.CompletionItem(columnNode.getTreeItem().columnName); completionItem.detail = columnNode.getTreeItem().detail; completionItem.documentation = columnNode.getTreeItem().document; - completionItem.kind = vscode.CompletionItemKind.Function; + completionItem.kind = vscode.CompletionItemKind.Field; return completionItem; }); } diff --git a/src/provider/Complection/chain/databaseChain.ts b/src/provider/Complection/chain/databaseChain.ts index 6924142..1afa969 100644 --- a/src/provider/Complection/chain/databaseChain.ts +++ b/src/provider/Complection/chain/databaseChain.ts @@ -3,7 +3,7 @@ import {DatabaseCache} from "../../../database/DatabaseCache"; import {ComplectionChain, ComplectionContext} from "../complectionContext"; function wrap(origin: string): string { - if (origin != null && origin.match(/\b(-)\b/ig)) { + if (origin != null && origin.match(/\b(-|\.)\b/ig)) { return `\`${origin}\``; } return origin; @@ -28,7 +28,7 @@ export class DatabaseChain implements ComplectionChain { return databaseNodes.map((databaseNode) => { const label = databaseNode.getTreeItem().label; const completionItem = new vscode.CompletionItem(label); - completionItem.kind = vscode.CompletionItemKind.Struct; + completionItem.kind = vscode.CompletionItemKind.Folder; completionItem.insertText = wrap(label); return completionItem; }); diff --git a/src/provider/Complection/chain/functionChain.ts b/src/provider/Complection/chain/functionChain.ts index a07c48f..e4b74a6 100644 --- a/src/provider/Complection/chain/functionChain.ts +++ b/src/provider/Complection/chain/functionChain.ts @@ -13,7 +13,18 @@ export class FunctionChain implements ComplectionChain { }); } public getComplection(complectionContext: ComplectionContext): vscode.CompletionItem[] { - return this.functionComplectionItems; + if ( + (complectionContext.preWord && complectionContext.preWord.match(/\b(select|HAVING|where|and|,|=|<|>)\b/ig)) + || + (complectionContext.currentWord && complectionContext.currentWord.match(/(<|>|,|=)$/)) + ) { + + let tableMatch = /(from|join)\s*(\w+)/ig + + return this.functionComplectionItems; + } + + return null; } public stop(): boolean { diff --git a/src/provider/Complection/chain/tableDetecherChain.ts b/src/provider/Complection/chain/tableDetecherChain.ts index f56c415..629ba01 100644 --- a/src/provider/Complection/chain/tableDetecherChain.ts +++ b/src/provider/Complection/chain/tableDetecherChain.ts @@ -5,11 +5,26 @@ export class TableDetecherChain implements ComplectionChain { public getComplection(complectionContext: ComplectionContext): vscode.CompletionItem[] | Promise { - if (complectionContext.preWord && complectionContext.preWord.match(/\b(select|on|where)\b/ig)) { - - let tableMatch = /(from|join)\s*(\w+)/ig - - return [new vscode.CompletionItem("test", vscode.CompletionItemKind.Class)]; + const tableMatch = new RegExp('(from|join)\\s*((\\w|\\.)+)( *)?(\\w+)?', 'ig'); + if ( + (complectionContext.preWord && complectionContext.preWord.match(/\b(select|HAVING|\(|on|where|and|,|=|<|>)\b/ig)) + || + (complectionContext.currentWord && complectionContext.currentWord.match(/(<|>|,|=)$/)) + ) { + let completionItem = [] + let result = tableMatch.exec(complectionContext.currentSqlFull) + while (result != null) { + const alias = result[5]; + if (alias) { + completionItem.push(new vscode.CompletionItem(alias, vscode.CompletionItemKind.Interface)) + } else { + const tableName = result[2].replace(/\w*?\./, "") + completionItem.push(new vscode.CompletionItem(tableName, vscode.CompletionItemKind.Interface)) + } + result = tableMatch.exec(complectionContext.currentSqlFull) + } + + return completionItem; } return null; diff --git a/src/provider/Complection/complectionContext.ts b/src/provider/Complection/complectionContext.ts index 586ba49..8129997 100644 --- a/src/provider/Complection/complectionContext.ts +++ b/src/provider/Complection/complectionContext.ts @@ -9,21 +9,23 @@ export interface ComplectionChain { export class ComplectionContext { - public preWord: string; public preChart: string; + public preWord: string; public currentWord: string; public currentSql: string; + public currentSqlFull: string; public static build(document: vscode.TextDocument, position: vscode.Position): ComplectionContext { const context = new ComplectionContext(); const currentSql = QueryUnit.obtainCursorSql(document, position).trim(); if (!currentSql) return context; + context.currentSqlFull = QueryUnit.obtainCursorSql(document, position, document.getText()).trim(); const prePostion = position.character === 0 ? position : new vscode.Position(position.line, position.character - 1); const preChart = position.character === 0 ? null : document.getText(new vscode.Range(prePostion, position)); - const wordMatch = currentSql.match(/(\w|-)+/ig); + const wordMatch = currentSql.match(/(\w|-|\_)+/g); if (wordMatch) { if ((preChart == null || preChart == " " || preChart == ".") && wordMatch.length >= 1) { context.preWord = wordMatch[wordMatch.length - 1] @@ -31,6 +33,9 @@ export class ComplectionContext { context.preWord = wordMatch[wordMatch.length - 2] } } + const codeMatch = currentSql.match(/(\w|=|<|>|\()+$/) + if (codeMatch) + context.currentWord = codeMatch[0] context.preChart = preChart; context.currentSql = currentSql.trim(); diff --git a/tsconfig.json b/tsconfig.json index 8a1d847..fb7d6a5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "target": "es6", "outDir": "out", "lib": [ - "es6" + "es6", + "es2017" ], "sourceMap": true, "rootDir": "src"