Search in sources :

Example 1 with QualifiedName

use of org.rstudio.studio.client.workbench.views.console.shell.assist.CompletionRequester.QualifiedName in project rstudio by rstudio.

the class RCompletionManager method previewKeyPress.

public boolean previewKeyPress(char c) {
    suggestTimer_.cancel();
    if (isDisabled())
        return false;
    if (popup_.isShowing()) {
        // If insertion of this character completes an available suggestion,
        // and is not a prefix match of any other suggestion, then implicitly
        // apply that.
        QualifiedName selectedItem = popup_.getSelectedValue();
        // can also dismiss the popup on a perfect match of <foo>.
        if (selectedItem != null && selectedItem.name.replaceAll(":", "").equals(token_ + c)) {
            String fullToken = token_ + c;
            // Find prefix matches -- there should only be one if we really
            // want this behaviour (ie the current selection)
            int prefixMatchCount = 0;
            QualifiedName[] items = popup_.getItems();
            for (int i = 0; i < items.length; i++) {
                if (items[i].name.startsWith(fullToken)) {
                    ++prefixMatchCount;
                    if (prefixMatchCount > 1)
                        break;
                }
            }
            if (prefixMatchCount == 1) {
                // We place the completion list offscreen to ensure that
                // backspace events are handled later. 
                popup_.placeOffscreen();
                return false;
            }
        }
        if (c == ':') {
            suggestTimer_.schedule(false, true, false);
            return false;
        }
        if (c == ' ')
            return false;
        // Always update the current set of completions following
        // a key insertion. Defer execution so the key insertion can
        // enter the document.
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {

            @Override
            public void execute() {
                beginSuggest(false, true, false);
            }
        });
        return false;
    } else {
        // Bail if we're not in R mode
        if (!DocumentMode.isCursorInRMode(docDisplay_))
            return false;
        // Bail if we're in a single-line string
        if (docDisplay_.isCursorInSingleLineString())
            return false;
        // if there's a selection, bail
        if (input_.hasSelection())
            return false;
        // following the cursor
        if (isValidForRIdentifier(docDisplay_.getCharacterAtCursor()))
            return false;
        // Perform an auto-popup if a set number of R identifier characters
        // have been inserted (but only if the user has allowed it in prefs)
        boolean autoPopupEnabled = uiPrefs_.codeComplete().getValue().equals(UIPrefsAccessor.COMPLETION_ALWAYS);
        if (!autoPopupEnabled)
            return false;
        // Immediately display completions after '$', '::', etc.
        char prevChar = docDisplay_.getCurrentLine().charAt(input_.getCursorPosition().getColumn() - 1);
        if ((c == ':' && prevChar == ':') || (c == '$') || (c == '@')) {
            // Bail if we're in Vim but not in insert mode
            if (docDisplay_.isVimModeOn() && !docDisplay_.isVimInInsertMode()) {
                return false;
            }
            Scheduler.get().scheduleDeferred(new ScheduledCommand() {

                @Override
                public void execute() {
                    beginSuggest(true, true, false);
                }
            });
            return false;
        }
        // Check for a valid number of R identifier characters for autopopup
        boolean canAutoPopup = checkCanAutoPopup(c, uiPrefs_.alwaysCompleteCharacters().getValue() - 1);
        // Attempt to pop up completions immediately after a function call.
        if (c == '(' && !isLineInComment(docDisplay_.getCurrentLine())) {
            String token = StringUtil.getToken(docDisplay_.getCurrentLine(), input_.getCursorPosition().getColumn(), "[" + RegexUtil.wordCharacter() + "._]", false, true);
            if (token.matches("^(library|require|requireNamespace|data)\\s*$"))
                canAutoPopup = true;
            sigTipManager_.resolveActiveFunctionAndDisplayToolTip();
        }
        if ((canAutoPopup) || isSweaveCompletion(c)) {
            // Delay suggestion to avoid auto-popup while the user is typing
            suggestTimer_.schedule(true, true, false);
        }
    }
    return false;
}
Also used : ScheduledCommand(com.google.gwt.core.client.Scheduler.ScheduledCommand) QualifiedName(org.rstudio.studio.client.workbench.views.console.shell.assist.CompletionRequester.QualifiedName)

Example 2 with QualifiedName

use of org.rstudio.studio.client.workbench.views.console.shell.assist.CompletionRequester.QualifiedName in project rstudio by rstudio.

the class CompletionPopupPanel method showCompletionValues.

@Override
public void showCompletionValues(QualifiedName[] values, PositionCallback callback, boolean truncated) {
    registerIgnoredKeys();
    CompletionList<QualifiedName> list = new CompletionList<QualifiedName>(values, 6, true, true);
    list.addSelectionCommitHandler(new SelectionCommitHandler<QualifiedName>() {

        public void onSelectionCommit(SelectionCommitEvent<QualifiedName> event) {
            lastSelectedValue_ = event.getSelectedItem();
            SelectionCommitEvent.fire(CompletionPopupPanel.this, event.getSelectedItem());
        }
    });
    list.addSelectionHandler(new SelectionHandler<QualifiedName>() {

        public void onSelection(SelectionEvent<QualifiedName> event) {
            lastSelectedValue_ = event.getSelectedItem();
            SelectionEvent.fire(CompletionPopupPanel.this, event.getSelectedItem());
        }
    });
    list_ = list;
    container_ = new VerticalPanel();
    container_.add(list_);
    if (truncated)
        container_.add(truncated_);
    setWidget(container_);
    ElementIds.assignElementId(list_.getElement(), ElementIds.POPUP_COMPLETIONS);
    show(callback);
}
Also used : VerticalPanel(com.google.gwt.user.client.ui.VerticalPanel) QualifiedName(org.rstudio.studio.client.workbench.views.console.shell.assist.CompletionRequester.QualifiedName)

Example 3 with QualifiedName

use of org.rstudio.studio.client.workbench.views.console.shell.assist.CompletionRequester.QualifiedName in project rstudio by rstudio.

the class RCompletionManager method previewKeyDown.

public boolean previewKeyDown(NativeEvent event) {
    suggestTimer_.cancel();
    if (sigTipManager_.previewKeyDown(event))
        return true;
    if (isDisabled())
        return false;
    /**
       * KEYS THAT MATTER
       *
       * When popup not showing:
       * Tab - attempt completion (handled in Console.java)
       * 
       * When popup showing:
       * Esc - dismiss popup
       * Enter/Tab - accept current selection
       * Up-arrow/Down-arrow - change selected item
       * [identifier] - narrow suggestions--or if we're lame, just dismiss
       * All others - dismiss popup
       */
    nativeEvent_ = event;
    int keycode = event.getKeyCode();
    int modifier = KeyboardShortcut.getModifierValue(event);
    if (!popup_.isShowing()) {
        // don't allow ctrl + space for completions in Emacs mode
        if (docDisplay_.isEmacsModeOn() && event.getKeyCode() == KeyCodes.KEY_SPACE)
            return false;
        if (CompletionUtils.isCompletionRequest(event, modifier)) {
            if (initFilter_ == null || initFilter_.shouldComplete(event)) {
                // '[](', or '`r |' contexts
                if (DocumentMode.isCursorInMarkdownMode(docDisplay_)) {
                    String currentLine = docDisplay_.getCurrentLineUpToCursor();
                    if (!(Pattern.create("^```{[rR]").test(currentLine) || Pattern.create(".*\\[.*\\]\\(").test(currentLine) || (Pattern.create(".*`r").test(currentLine) && StringUtil.countMatches(currentLine, '`') % 2 == 1)))
                        return false;
                }
                // If we're in tex mode, only provide completions in chunks
                if (DocumentMode.isCursorInTexMode(docDisplay_)) {
                    String currentLine = docDisplay_.getCurrentLineUpToCursor();
                    if (!Pattern.create("^<<").test(currentLine))
                        return false;
                }
                return beginSuggest(true, false, true);
            }
        } else if (event.getKeyCode() == KeyCodes.KEY_TAB && modifier == KeyboardShortcut.SHIFT) {
            return snippets_.attemptSnippetInsertion(true);
        } else if (// F1
        keycode == 112 && modifier == KeyboardShortcut.NONE) {
            goToHelp();
            return true;
        } else if (// F2
        keycode == 113 && modifier == KeyboardShortcut.NONE) {
            goToFunctionDefinition();
            return true;
        }
    } else {
        // bail on modifier keys
        if (KeyboardHelper.isModifierKey(keycode))
            return false;
        // allow emacs-style navigation of popup entries
        if (modifier == KeyboardShortcut.CTRL) {
            switch(keycode) {
                case KeyCodes.KEY_P:
                    return popup_.selectPrev();
                case KeyCodes.KEY_N:
                    return popup_.selectNext();
            }
        } else if (modifier == KeyboardShortcut.NONE) {
            if (keycode == KeyCodes.KEY_ESCAPE) {
                invalidatePendingRequests();
                return true;
            }
            // had originally requested completions at e.g. "stats::".
            if (popup_.hasCompletions() && !popup_.isOffscreen()) {
                if (keycode == KeyCodes.KEY_ENTER) {
                    QualifiedName value = popup_.getSelectedValue();
                    if (value != null) {
                        context_.onSelection(value);
                        return true;
                    }
                } else if (keycode == KeyCodes.KEY_TAB) {
                    QualifiedName value = popup_.getSelectedValue();
                    if (value != null) {
                        if (value.type == RCompletionType.DIRECTORY)
                            context_.suggestOnAccept_ = true;
                        context_.onSelection(value);
                        return true;
                    }
                } else if (keycode == KeyCodes.KEY_UP)
                    return popup_.selectPrev();
                else if (keycode == KeyCodes.KEY_DOWN)
                    return popup_.selectNext();
                else if (keycode == KeyCodes.KEY_PAGEUP)
                    return popup_.selectPrevPage();
                else if (keycode == KeyCodes.KEY_PAGEDOWN)
                    return popup_.selectNextPage();
                else if (keycode == KeyCodes.KEY_HOME)
                    return popup_.selectFirst();
                else if (keycode == KeyCodes.KEY_END)
                    return popup_.selectLast();
                if (// F1
                keycode == 112) {
                    context_.showHelpTopic();
                    return true;
                } else if (// F2
                keycode == 113) {
                    goToFunctionDefinition();
                    return true;
                }
            }
        }
        if (canContinueCompletions(event))
            return false;
        // pop up completions
        if (keycode == 191 && modifier == KeyboardShortcut.NONE) {
            input_.insertCode("/");
            return beginSuggest(true, true, false);
        }
        // continue showing completions on backspace
        if (keycode == KeyCodes.KEY_BACKSPACE && modifier == KeyboardShortcut.NONE && !docDisplay_.inMultiSelectMode()) {
            int cursorColumn = input_.getCursorPosition().getColumn();
            String currentLine = docDisplay_.getCurrentLine();
            // also halt suggestions if we're about to remove the only character on the line
            if (cursorColumn > 0) {
                char ch = currentLine.charAt(cursorColumn - 2);
                char prevCh = currentLine.charAt(cursorColumn - 3);
                boolean isAcceptableCharSequence = isValidForRIdentifier(ch) || (ch == ':' && prevCh == ':') || ch == '$' || ch == '@' || // for file completions
                ch == '/';
                if (currentLine.length() > 0 && cursorColumn > 0 && isAcceptableCharSequence) {
                    // manually remove the previous character
                    InputEditorSelection selection = input_.getSelection();
                    InputEditorPosition start = selection.getStart().movePosition(-1, true);
                    InputEditorPosition end = selection.getStart();
                    if (currentLine.charAt(cursorColumn) == ')' && currentLine.charAt(cursorColumn - 1) == '(') {
                        // flush cache as old completions no longer relevant
                        requester_.flushCache();
                        end = selection.getStart().movePosition(1, true);
                    }
                    input_.setSelection(new InputEditorSelection(start, end));
                    input_.replaceSelection("", false);
                    return beginSuggest(false, false, false);
                }
            } else {
                invalidatePendingRequests();
                return true;
            }
        }
        invalidatePendingRequests();
        return false;
    }
    return false;
}
Also used : InputEditorSelection(org.rstudio.studio.client.workbench.views.console.shell.editor.InputEditorSelection) QualifiedName(org.rstudio.studio.client.workbench.views.console.shell.assist.CompletionRequester.QualifiedName) InputEditorPosition(org.rstudio.studio.client.workbench.views.console.shell.editor.InputEditorPosition)

Aggregations

QualifiedName (org.rstudio.studio.client.workbench.views.console.shell.assist.CompletionRequester.QualifiedName)3 ScheduledCommand (com.google.gwt.core.client.Scheduler.ScheduledCommand)1 VerticalPanel (com.google.gwt.user.client.ui.VerticalPanel)1 InputEditorPosition (org.rstudio.studio.client.workbench.views.console.shell.editor.InputEditorPosition)1 InputEditorSelection (org.rstudio.studio.client.workbench.views.console.shell.editor.InputEditorSelection)1