/** * Refreshes the view after a file has been saved. * * @param root root directory * @param ctx database context * @throws InterruptedException interruption */ void parse(final IOFile root, final Context ctx) throws InterruptedException { final long id = ++parseId; final HashSet<String> parsed = new HashSet<>(); final TreeMap<String, InputInfo> errs = new TreeMap<>(); // collect files to be parsed final ProjectCache pc = cache(root); final StringList mods = new StringList(), lmods = new StringList(); for (final String path : pc) { final IOFile file = new IOFile(path); if (file.hasSuffix(IO.XQSUFFIXES)) (file.hasSuffix(IO.XQMSUFFIX) ? lmods : mods).add(path); } mods.add(lmods); // parse modules for (final String path : mods) { if (id != parseId) throw new InterruptedException(); if (parsed.contains(path)) continue; final IOFile file = new IOFile(path); try (final TextInput ti = new TextInput(file)) { // parse query try (final QueryContext qc = new QueryContext(ctx)) { final String input = ti.cache().toString(); final boolean lib = QueryProcessor.isLibrary(input); qc.parse(input, lib, path, null); // parsing was successful: remember path parsed.add(path); for (final byte[] mod : qc.modParsed) parsed.add(Token.string(mod)); } catch (final QueryException ex) { // parsing failed: remember path final InputInfo ii = ex.info(); errs.put(path, ii); parsed.add(ii.path()); } } catch (final IOException ex) { // file may not be accessible Util.debug(ex); } } errors = errs; }
/** Code completion. */ private void complete() { if (selected()) return; // find first character final int caret = editor.pos(), startPos = editor.completionStart(); final String prefix = string(substring(editor.text(), startPos, caret)); if (prefix.isEmpty()) return; // find insertion candidates final TreeMap<String, String> tmp = new TreeMap<>(); for (final Entry<String, String> entry : REPLACE.entrySet()) { final String key = entry.getKey(); if (key.startsWith(prefix)) tmp.put(key, entry.getValue()); } if (tmp.size() == 1) { // insert single candidate complete(tmp.values().iterator().next(), startPos); } else if (!tmp.isEmpty()) { // show popup menu final JPopupMenu pm = new JPopupMenu(); final ActionListener al = new ActionListener() { @Override public void actionPerformed(final ActionEvent ae) { complete(ae.getActionCommand().replaceAll("^.*?\\] ", ""), startPos); } }; for (final Entry<String, String> entry : tmp.entrySet()) { final JMenuItem mi = new JMenuItem("[" + entry.getKey() + "] " + entry.getValue()); pm.add(mi); mi.addActionListener(al); } pm.addSeparator(); final JMenuItem mi = new JMenuItem(Text.INPUT + Text.COLS + prefix); mi.setEnabled(false); pm.add(mi); final int[] cursor = rend.cursor(); pm.show(this, cursor[0], cursor[1]); // highlight first entry final MenuElement[] me = {pm, (JMenuItem) pm.getComponent(0)}; MenuSelectionManager.defaultManager().setSelectedPath(me); } }