Skip to content

Commit 1654445

Browse files
authored
Merge pull request #54 from luusluus/46-enable-sql-autocomplete-suggestions
46 enable sql autocomplete suggestions
2 parents 5dd7ed5 + a8fb010 commit 1654445

File tree

6 files changed

+106
-6
lines changed

6 files changed

+106
-6
lines changed

media/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<script nonce="{{nonce}}" type="text/javascript" src="{{scripts}}/ace/src-min/theme-idle_fingers.js"></script>
2828
<script nonce="{{nonce}}" type="text/javascript" src="{{scripts}}/ace/src-min/theme-dawn.js"></script>
2929
<script nonce="{{nonce}}" type="text/javascript" src="{{scripts}}/ace/src-min/mode-sql.js"></script>
30+
<script nonce="{{nonce}}" type="text/javascript" src="{{scripts}}/ace/src-min/ext-language_tools.js"></script>
3031

3132
</head>
3233

media/scripts/ace/src-min/ext-language_tools.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

media/scripts/main.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@
204204
<path d="m15 15-4.5-4.5"></path>
205205
</svg>
206206
</div>
207-
<input class="search-box" id="input-filter-values" type="text" placeholder="Search rows" disabled>
207+
<input class="search-box" id="input-filter-values" type="text" placeholder="Search rows in page" disabled>
208208
<div class="clear-icon-element" id="clear-icon">
209209
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" focusable="false" aria-hidden="true" class="clear-icon">
210210
<path d="m2 2 12 12M14 2 2 14" stroke="#ffffff"></path>
@@ -291,7 +291,9 @@
291291
});
292292
}
293293

294-
function initCodeEditor(isQueryable, defaultQuery, shortCutMapping, aceTheme) {
294+
function initCodeEditor(
295+
isQueryable, defaultQuery, shortCutMapping, aceTheme, aceEditorCompletions
296+
) {
295297
const queryTabPanel = document.getElementById("query-tab-panel");
296298
if (!isQueryable) {
297299
const paragraph = document.createElement("p");
@@ -319,6 +321,21 @@
319321
editor.setTheme(aceTheme);
320322
editor.session.setMode("ace/mode/sql");
321323
editor.setValue(defaultQuery);
324+
325+
editor.setOptions({
326+
enableBasicAutocompletion: true,
327+
enableSnippets: true,
328+
enableLiveAutocompletion: true,
329+
});
330+
331+
const completer = {
332+
getCompletions: function(editor, session, pos, prefix, callback) {
333+
callback(null, aceEditorCompletions);
334+
}
335+
};
336+
337+
var langTools = ace.require("ace/ext/language_tools");
338+
langTools.addCompleter(completer);
322339

323340
editor.commands.addCommand({
324341
name: 'runQuery',
@@ -904,7 +921,8 @@
904921
tableData.isQueryable,
905922
tableData.settings.defaultQuery,
906923
tableData.settings.shortCutMapping,
907-
tableData.aceTheme
924+
tableData.aceTheme,
925+
tableData.aceEditorCompletions
908926
);
909927

910928
currentPageDataTab = tableData.currentPage;

media/styles/parquet-visualizer.css

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,13 @@ html, body {
231231
.dropdown-menu li span:hover {
232232
background-color: #ddd;
233233
font-weight: bolder;
234-
}
234+
}
235+
236+
/* ace tooltip*/
237+
#doc-tooltip {
238+
overflow-wrap: anywhere;
239+
overflow-y: auto;
240+
overflow-x: auto;
241+
height: inherit;
242+
min-width: 300px;
243+
}

src/backend.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export abstract class Backend {
2323
let result: any = [];
2424

2525
if (field.type.children.length > 0) {
26-
result = [this.parseSchema(field.type.children[0])]
26+
result = [this.parseSchema(field.type.children[0])];
2727
return result;
2828
}
2929
return result;
@@ -50,9 +50,12 @@ export abstract class Backend {
5050
public getSchema(): any {
5151
const parsedSchema = this.arrowSchema.fields.map((f, index) => {
5252
let parsedType = this.parseSchema(f);
53+
let typeName = parsedType;
54+
let typeValue = parsedType;
5355

5456
if (typeof parsedType === 'object'){
5557
parsedType = JSON.stringify(parsedType);
58+
typeName = 'object';
5659
}
5760

5861
if(f.metadata.size > 0) {
@@ -62,6 +65,8 @@ export abstract class Backend {
6265
'index': index + 1,
6366
'name': f.name,
6467
'type': parsedType,
68+
'typeName': typeName,
69+
'typeValue': typeValue,
6570
'nullable': f.nullable,
6671
'metadata': JSON.stringify(f.metadata)
6772
};

src/parquet-editor.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,61 @@ export class ParquetEditorProvider implements vscode.CustomReadonlyEditorProvide
414414
throw Error(errorMessage);
415415
}
416416
}
417+
418+
getAceEditorCompletions(schema){
419+
let formattedSchema: any = {};
420+
for (const key in schema){
421+
const columnName = schema[key].name;
422+
const columnType = schema[key].typeValue;
423+
424+
formattedSchema[columnName] = columnType;
425+
}
426+
427+
function getCompletion(columnTypeValue: any, prevColumnName: string = ''){
428+
let completions: any = {};
429+
for (const key in columnTypeValue) {
430+
if (!columnTypeValue.hasOwnProperty(key)) {
431+
continue;
432+
}
433+
434+
const newNamePrefix = prevColumnName ? `${prevColumnName}.${key}` : key;
435+
436+
if (typeof columnTypeValue[key] === 'object' && !Array.isArray(columnTypeValue[key])) {
437+
completions[newNamePrefix] = columnTypeValue[key];
438+
439+
Object.assign(completions, getCompletion(columnTypeValue[key], newNamePrefix));
440+
441+
} else if (Array.isArray(columnTypeValue[key])) {
442+
completions[newNamePrefix] = columnTypeValue[key];
443+
}
444+
else {
445+
completions[newNamePrefix] = columnTypeValue[key];
446+
}
447+
}
448+
return completions;
449+
}
450+
451+
const completions = getCompletion(formattedSchema);
452+
const aceEditorCompletions = Object.entries(completions).reverse().map((e, i) => {
453+
let htmlForDataType: string;
454+
if (typeof e[1] === 'object'){
455+
htmlForDataType = `<pre>${JSON.stringify(e[1], undefined, 4)}</pre>`;
456+
}
457+
else {
458+
htmlForDataType = `${e[1]}`;
459+
}
460+
461+
let docHtml = `<strong>Name</strong> ${e[0]}<br><strong>Type</strong>: ${htmlForDataType}`;
462+
return {
463+
value: e[0],
464+
score: i + 1000, // NOTE: just to get the column meta above the other meta.
465+
meta: 'column',
466+
docHTML: docHtml,
467+
};
468+
});
469+
470+
return aceEditorCompletions;
471+
}
417472

418473
/**
419474
* Called when our custom editor is opened.
@@ -469,6 +524,9 @@ export class ParquetEditorProvider implements vscode.CustomReadonlyEditorProvide
469524
const schema = document.backend.getSchema();
470525
const metadata = document.backend.getMetaData();
471526

527+
// get Code completions for the editor
528+
const aceEditorCompletions = this.getAceEditorCompletions(schema);
529+
472530
let aceTheme = '';
473531
if (vscode.window.activeColorTheme.kind === vscode.ColorThemeKind.Light) {
474532
aceTheme = 'ace/theme/dawn';
@@ -493,7 +551,8 @@ export class ParquetEditorProvider implements vscode.CustomReadonlyEditorProvide
493551
defaultPageSizes: defaultPageSizesFromSettings,
494552
shortCutMapping: shortCutMapping
495553
},
496-
aceTheme: aceTheme
554+
aceTheme: aceTheme,
555+
aceEditorCompletions
497556
};
498557

499558
// Wait for the webview to be properly ready before we init

0 commit comments

Comments
 (0)