diff --git a/src/main/java/net/sf/jabref/gui/autocompleter/AutoCompleteListener.java b/src/main/java/net/sf/jabref/gui/autocompleter/AutoCompleteListener.java index df2e0fac3fc..1bf03082a06 100644 --- a/src/main/java/net/sf/jabref/gui/autocompleter/AutoCompleteListener.java +++ b/src/main/java/net/sf/jabref/gui/autocompleter/AutoCompleteListener.java @@ -69,10 +69,10 @@ public void keyPressed(KeyEvent e) { } // Cycle through alternative completions when user presses PGUP/PGDN: else if ((e.getKeyCode() == KeyEvent.VK_PAGE_DOWN) && (textToInsert != null)) { - cycle((JTextComponent) e.getSource(), 1); + cycleSuggestion((JTextComponent) e.getSource(), 1); e.consume(); } else if ((e.getKeyCode() == KeyEvent.VK_PAGE_UP) && (textToInsert != null)) { - cycle((JTextComponent) e.getSource(), -1); + cycleSuggestion((JTextComponent) e.getSource(), -1); e.consume(); } // else if ((e.getKeyCode() == KeyEvent.VK_BACK_SPACE)) { @@ -91,39 +91,42 @@ else if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED) { } } - private void cycle(JTextComponent comp, int increment) { + private void cycleSuggestion(JTextComponent textField, int increment) { assert (lastCompletions != null); assert (!lastCompletions.isEmpty()); + lastShownCompletion += increment; if (lastShownCompletion >= lastCompletions.size()) { lastShownCompletion = 0; } else if (lastShownCompletion < 0) { lastShownCompletion = lastCompletions.size() - 1; } - String sno = lastCompletions.get(lastShownCompletion); - textToInsert = sno.substring(lastBeginning.length() - 1); - StringBuilder alltext = new StringBuilder(comp.getText()); + // new suggestion + String newSuggestion = lastCompletions.get(lastShownCompletion); + textToInsert = newSuggestion.substring(lastBeginning.length() - 1); + + // replace suggestion selection with new suggestion + StringBuilder text = new StringBuilder(textField.getText()); - int oldSelectionStart = comp.getSelectionStart(); - int oldSelectionEnd = comp.getSelectionEnd(); + int oldSelectionStart = textField.getSelectionStart(); + int oldSelectionEnd = textField.getSelectionEnd(); // replace prefix with new prefix - int startPos = comp.getSelectionStart() - lastBeginning.length(); - alltext.delete(startPos, oldSelectionStart); - alltext.insert(startPos, sno.subSequence(0, lastBeginning.length())); + int startPos = textField.getSelectionStart() - lastBeginning.length(); + text.delete(startPos, oldSelectionStart); + text.insert(startPos, newSuggestion.subSequence(0, lastBeginning.length())); // replace suffix with new suffix - alltext.delete(oldSelectionStart, oldSelectionEnd); - //int cp = oldSelectionEnd - deletedChars; - alltext.insert(oldSelectionStart, textToInsert.substring(1)); - - LOGGER.debug(alltext.toString()); - comp.setText(alltext.toString()); - //comp.setCaretPosition(cp+textToInsert.length()-1); - comp.select(oldSelectionStart, (oldSelectionStart + textToInsert.length()) - 1); - lastCaretPosition = comp.getCaretPosition(); - LOGGER.debug("ToSetIn: '" + textToInsert + "'"); + text.delete(oldSelectionStart, oldSelectionEnd); + text.insert(oldSelectionStart, textToInsert.substring(1)); + + // set new suggestion + textField.setText(text.toString()); + // highlight auto-complete part + textField.select(oldSelectionStart, (oldSelectionStart + textToInsert.length()) - 1); + // update caret position + lastCaretPosition = textField.getCaretPosition(); } /** @@ -183,44 +186,42 @@ private void setUnmodifiedTypedLetters(JTextComponent comp, boolean lastBeginnin * Start a new completion attempt (instead of treating a continuation of an existing word or an interrupt of the * current word) */ - private void startCompletion(StringBuffer currentword, KeyEvent e) { + private void startCompletion(String currentWord, KeyEvent e) { JTextComponent textField = (JTextComponent) e.getSource(); - String word = currentword.toString(); - List completed = completer.complete(word); + List suggestions = completer.complete(currentWord); - int no = 0; // We use the first word in the array of completions. - if ((completed != null) && (!completed.isEmpty())) { - lastShownCompletion = 0; - lastCompletions = completed; - String sno = completed.get(no); - - // these two lines obey the user's input - //textToInsert = Character.toString(ch); - //textToInsert = textToInsert.concat(sno.substring(word.length())); - // BUT we obey the completion - textToInsert = sno.substring(word.length() - 1); - - LOGGER.debug("textToInsert: >" + textToInsert + '<'); - - StringBuilder alltext = new StringBuilder(textField.getText()); - int cp = textField.getCaretPosition(); - alltext.insert(cp, textToInsert); - textField.setText(alltext.toString()); - textField.setCaretPosition(cp); - textField.select(cp + 1, (cp + 1 + sno.length()) - word.length()); - e.consume(); - lastCaretPosition = textField.getCaretPosition(); - char ch = e.getKeyChar(); + if (suggestions == null || suggestions.isEmpty()) { + return; + } - LOGGER.debug("Appending >" + ch + '<'); + lastShownCompletion = 0; + lastCompletions = suggestions; + // we use the first word inside the suggestions + String suggestedWord = suggestions.get(0); + + // these two lines obey the user's input + //textToInsert = Character.toString(ch); + //textToInsert = textToInsert.concat(suggestedWord.substring(word.length())); + // BUT we obey the completion + textToInsert = suggestedWord.substring(currentWord.length() - 1); + + StringBuilder alltext = new StringBuilder(textField.getText()); + int cp = textField.getCaretPosition(); + alltext.insert(cp, textToInsert); + textField.setText(alltext.toString()); + textField.setCaretPosition(cp); + textField.select(cp + 1, (cp + 1 + suggestedWord.length()) - currentWord.length()); + e.consume(); + lastCaretPosition = textField.getCaretPosition(); + char ch = e.getKeyChar(); - if (word.length() <= 1) { - lastBeginning = Character.toString(ch); - } else { - lastBeginning = word.substring(0, word.length() - 1).concat(Character.toString(ch)); - } - } + LOGGER.debug("Appending >" + ch + '<'); + if (currentWord.length() <= 1) { + lastBeginning = Character.toString(ch); + } else { + lastBeginning = currentWord.substring(0, currentWord.length() - 1).concat(Character.toString(ch)); + } } @Override @@ -240,6 +241,7 @@ public void keyTyped(KeyEvent e) { JTextComponent comp = (JTextComponent) e.getSource(); // don't do auto completion inside words + // TODO: ac not working as expected, e.g. Appstand, Application -> App -> Apps (no completion here) try { char pos = comp.getText().charAt(comp.getCaretPosition()); if (!Character.isWhitespace(pos)) { @@ -335,7 +337,7 @@ public void keyTyped(KeyEvent e) { // only "real characters" end up here assert (!Character.isISOControl(ch)); currentword.append(ch); - startCompletion(currentword, e); + startCompletion(currentword.toString(), e); return; } else { if (Character.isWhitespace(ch)) {