blob: 125afe27a702c21ea04e655eefe45b87349e53e5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.tracecompass.incubator.internal.filters.ui.lspFilterTextbox;
/**
*
* Client-side autocompletion for parenthesis/brackets/quotes
*
* FIXME: When entering the first say '(' or '"', the text is completed
* correctly. But sometimes the user will close the character himself to avoid
* having to use the arrow to go after the closing character. If the user enters
* the closing character, it should just move to the next one, ie remove the one
* that was auto-added. For example, if I type '"', 'a', '"', I would expect the
* string to be "a", now, it is "a""", with two trailing "". Same with
* parenthesis '(', 'a', ')' should be (a), not (a)). See the behavior in
* Eclipse itself.
*
* TODO: move to core?
*
* @author Maxime Thibault
*/
public class FilterBoxLocalTextCompletion {
private static final String LEFT_PARENTHESIS = "("; //$NON-NLS-1$
private static final String RIGHT_PARENTHESIS = ")"; //$NON-NLS-1$
private static final String LEFT_SQUARE_BRACKET = "["; //$NON-NLS-1$
private static final String RIGHT_SQUARE_BRACKET = "]"; //$NON-NLS-1$
private static final String LEFT_BRACKET = "{"; //$NON-NLS-1$
private static final String RIGHT_BRACKET = "}"; //$NON-NLS-1$
private static final String DOUBLE_QUOTE = "\""; //$NON-NLS-1$
private static final String SINGLE_QUOTE = "'"; //$NON-NLS-1$
private static final String SPACE = " "; //$NON-NLS-1$
/**
* Autocomplete the string based on the cursorPos. This function suppose
* that the last inserted character is at cursorPos-1 (behind the cursor)
*
* @param str
* The string to complete
* @param cursorPos
* The caret position
* @return The completed string
*/
public static String autocomplete(String str, Integer cursorPos) {
boolean canComplete = canComplete(str, cursorPos);
if (canComplete) {
return complete(str, cursorPos);
}
return str;
}
/**
* Check if the string can be completed based on the cursor's position We
* assume that the token before the cursor's position is the token to be
* completed
*
* @param str
* The string to autocomplete
* @param cursorPos
* The caret position when the token has been inserted
* @return boolean that indicated wheter the string can be completed or not
*/
private static boolean canComplete(String str, Integer cursorPos) {
boolean isValid = true;
String charAtCursor = ""; //$NON-NLS-1$
// If cursorPos = 0, it means there's no char behind. Then left
// charAtCursor blank
if (cursorPos > 0) {
charAtCursor = String.valueOf(str.charAt(cursorPos - 1));
}
if (str.length() > cursorPos) {
String nextChar = String.valueOf(str.charAt(cursorPos));
// Check if the char at cursor is a left symbol
boolean charAtCursorOk = charAtCursor.equals(LEFT_BRACKET) ||
charAtCursor.equals(LEFT_PARENTHESIS) ||
charAtCursor.equals(LEFT_SQUARE_BRACKET) ||
charAtCursor.equals(DOUBLE_QUOTE) ||
charAtCursor.equals(SINGLE_QUOTE) ||
charAtCursor.equals(SPACE);
// Check if the char at cursor+1 is a right symbol
boolean rightOK = nextChar.equals(RIGHT_BRACKET) ||
nextChar.equals(RIGHT_PARENTHESIS) ||
nextChar.equals(RIGHT_SQUARE_BRACKET) ||
nextChar.equals(DOUBLE_QUOTE) ||
nextChar.equals(SINGLE_QUOTE) ||
nextChar.equals(SPACE);
// If the left char is a bracket, a parenthesis or a square bracket,
// the right char should not be a quote.
if (charAtCursor.equals(LEFT_BRACKET) ||
charAtCursor.equals(LEFT_PARENTHESIS) ||
charAtCursor.equals(LEFT_SQUARE_BRACKET)) {
rightOK &= !nextChar.equals(DOUBLE_QUOTE) && !nextChar.equals(SINGLE_QUOTE);
}
isValid = rightOK && charAtCursorOk;
}
return isValid;
}
/**
* Add the appropriate symbol at cursorPos to complete the autocompletion
*
* @param str
* The string to complete
* @param cursorPos
* The caret position
* @return The completed string
*/
private static String complete(String str, Integer cursorPos) {
String charAtCursor = ""; //$NON-NLS-1$
// If cursorPos = 0, it means there's no char behind. Then left
// charAtCursor blank
if (cursorPos > 0) {
charAtCursor = String.valueOf(str.charAt(cursorPos - 1));
}
String charToInsert;
switch (charAtCursor) {
case LEFT_PARENTHESIS:
charToInsert = RIGHT_PARENTHESIS;
break;
case LEFT_BRACKET:
charToInsert = RIGHT_BRACKET;
break;
case LEFT_SQUARE_BRACKET:
charToInsert = RIGHT_SQUARE_BRACKET;
break;
case DOUBLE_QUOTE:
charToInsert = DOUBLE_QUOTE;
break;
case SINGLE_QUOTE:
charToInsert = SINGLE_QUOTE;
break;
default:
// D'ont modify
charToInsert = ""; //$NON-NLS-1$
break;
}
// Insert the char between the string at the cursor position
return str.substring(0, cursorPos) + charToInsert + str.substring(cursorPos, str.length());
}
}