code completion

This commit is contained in:
Jan Prochazka
2021-03-21 20:03:46 +01:00
parent b7b9dde5ae
commit d4989c75ca
4 changed files with 191 additions and 1 deletions

View File

@@ -0,0 +1,122 @@
import { addCompleter, setCompleters } from 'ace-builds/src-noconflict/ext-language_tools';
import { getDatabaseInfo } from '../utility/metadataLoaders';
import analyseQuerySources from './analyseQuerySources';
const COMMON_KEYWORDS = [
'select',
'where',
'update',
'delete',
'group',
'order',
'from',
'by',
'create',
'table',
'drop',
'alter',
'view',
'execute',
'procedure',
'distinct',
'go',
];
export function mountCodeCompletion({ conid, database, editor }) {
setCompleters([]);
addCompleter({
getCompletions: async function (editor, session, pos, prefix, callback) {
const cursor = session.selection.cursor;
const line = session.getLine(cursor.row).slice(0, cursor.column);
const dbinfo = await getDatabaseInfo({ conid, database });
let list = COMMON_KEYWORDS.map(word => ({
name: word,
value: word,
caption: word,
meta: 'keyword',
score: 800,
}));
if (dbinfo) {
const colMatch = line.match(/([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]*)?$/);
if (colMatch) {
const table = colMatch[1];
const sources = analyseQuerySources(editor.getValue(), [
...dbinfo.tables.map(x => x.pureName),
...dbinfo.views.map(x => x.pureName),
]);
const source = sources.find(x => (x.alias || x.name) == table);
console.log('sources', sources);
console.log('table', table, source);
if (source) {
const table = dbinfo.tables.find(x => x.pureName == source.name);
if (table) {
list = [
...table.columns.map(x => ({
name: x.columnName,
value: x.columnName,
caption: x.columnName,
meta: 'column',
score: 1000,
})),
];
}
}
} else {
list = [
...list,
...dbinfo.tables.map(x => ({
name: x.pureName,
value: x.pureName,
caption: x.pureName,
meta: 'table',
score: 1000,
})),
...dbinfo.views.map(x => ({
name: x.pureName,
value: x.pureName,
caption: x.pureName,
meta: 'view',
score: 1000,
})),
];
}
}
// if (/(join)|(from)|(update)|(delete)|(insert)\s*([a-zA-Z0-9_]*)?$/i.test(line)) {
// if (dbinfo) {
// }
// }
callback(null, list);
},
});
const doLiveAutocomplete = function (e) {
const editor = e.editor;
var hasCompleter = editor.completer && editor.completer.activated;
const session = editor.session;
const cursor = session.selection.cursor;
const line = session.getLine(cursor.row).slice(0, cursor.column);
// We don't want to autocomplete with no prefix
if (e.command.name === 'backspace') {
// do not hide after backspace
} else if (e.command.name === 'insertstring') {
if ((!hasCompleter && /^[a-zA-Z]/.test(e.args)) || e.args == '.') {
editor.execCommand('startAutocomplete');
}
if (e.args == ' ' && /((from)|(join))\s*$/i.test(line)) {
editor.execCommand('startAutocomplete');
}
}
};
editor.commands.on('afterExec', doLiveAutocomplete);
return () => {
editor.commands.removeListener('afterExec', doLiveAutocomplete);
};
}