diff --git a/packages/web/src/index.js b/packages/web/src/index.js index d6bc461a7..b6607d8e4 100644 --- a/packages/web/src/index.js +++ b/packages/web/src/index.js @@ -11,6 +11,10 @@ import 'ace-builds/src-noconflict/mode-pgsql'; import 'ace-builds/src-noconflict/mode-sqlserver'; import 'ace-builds/src-noconflict/theme-github'; import 'ace-builds/src-noconflict/ext-searchbox'; +import 'ace-builds/src-noconflict/ext-language_tools'; +// import 'ace-builds/src-noconflict/snippets/sqlserver'; +// import 'ace-builds/src-noconflict/snippets/pgsql'; +// import 'ace-builds/src-noconflict/snippets/mysql'; ReactDOM.render(, document.getElementById('root')); diff --git a/packages/web/src/sqleditor/SqlEditor.js b/packages/web/src/sqleditor/SqlEditor.js index 923e6b1e9..aa97371d8 100644 --- a/packages/web/src/sqleditor/SqlEditor.js +++ b/packages/web/src/sqleditor/SqlEditor.js @@ -2,6 +2,9 @@ import React from 'react'; import styled from 'styled-components'; import AceEditor from 'react-ace'; import useDimensions from '../utility/useDimensions'; +import { addCompleter } from 'ace-builds/src-noconflict/ext-language_tools'; +import { useDatabaseInfo, getDatabaseInfo } from '../utility/metadataLoaders'; +// import { Autocomplete } from 'ace-builds'; const Wrapper = styled.div` position: absolute; @@ -26,6 +29,8 @@ export default function SqlEditor({ onKeyDown = undefined, editorRef = undefined, focusOnCreate = false, + conid = undefined, + database = undefined, }) { const [containerRef, { height, width }] = useDimensions(); const ownEditorRef = React.useRef(null); @@ -46,12 +51,71 @@ export default function SqlEditor({ }; }, [onKeyDown]); - // React.useEffect(() => { - // if (currentEditorRef.current.editor) - // currentEditorRef.current.editor.setOptions({ - // showGutter: false, - // }); - // }, []); + React.useEffect(() => { + 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 }); + + if (/from\s*$/i.test(line)) { + if (dbinfo) { + const 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, + })), + ]; + 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 (e.args == ' ' || e.args == '.') { + if (/from\s*$/i.test(line)) { + console.log('FROM', line); + currentEditorRef.current.editor.execCommand('startAutocomplete'); + } + } + // console.log('e.command', e.command); + // console.log('e.args', e.args); + + // if (!hasCompleter) { + // startAutocomplete + // // // always start completer + // // var completer = Autocomplete.for(editor); + // // // Disable autoInsert + // // completer.autoInsert = false; + // // completer.showPopup(editor); + // } + } + }; + + currentEditorRef.current.editor.commands.on('afterExec', doLiveAutocomplete); + }, []); return ( @@ -62,6 +126,15 @@ export default function SqlEditor({ onChange={onChange} name="UNIQUE_ID_OF_DIV" editorProps={{ $blockScrolling: true }} + setOptions={{ + enableBasicAutocompletion: true, + // enableLiveAutocompletion: true, + // enableSnippets: true, + showPrintMargin: false, + // showGutter: false, + // showLineNumbers: true, + // tabSize: 2 + }} value={value} readOnly={readOnly} fontSize="11pt" diff --git a/packages/web/src/tabs/QueryTab.js b/packages/web/src/tabs/QueryTab.js index 29b68e32b..5dade4009 100644 --- a/packages/web/src/tabs/QueryTab.js +++ b/packages/web/src/tabs/QueryTab.js @@ -198,6 +198,8 @@ export default function QueryTab({ onKeyDown={handleKeyDown} editorRef={editorRef} readOnly={queryText == loadingText} + conid={conid} + database={database} /> {sessionId && (