diff --git a/csl.api/apichanges.xml b/csl.api/apichanges.xml --- a/csl.api/apichanges.xml +++ b/csl.api/apichanges.xml @@ -49,6 +49,21 @@ Common Scripting Language API + + + Add DeleteWordHandler + + + + + +

+ Add DeleteWordHandler to replace KeystrokeHandler in future. KeystrokeHandler is deprecated since clients can use TypingHooks from editor.lib2 +

+
+ + +
Add useMultiview to @LanguageRegistration diff --git a/csl.api/nbproject/project.properties b/csl.api/nbproject/project.properties --- a/csl.api/nbproject/project.properties +++ b/csl.api/nbproject/project.properties @@ -40,7 +40,7 @@ # Version 2 license, then the option applies only if the new code is # made subject to such option by the copyright holder. -spec.version.base=2.33.0 +spec.version.base=2.34.0 is.autoload=true javac.source=1.6 diff --git a/csl.api/src/org/netbeans/modules/csl/api/CamelCaseOperations.java b/csl.api/src/org/netbeans/modules/csl/api/CamelCaseOperations.java --- a/csl.api/src/org/netbeans/modules/csl/api/CamelCaseOperations.java +++ b/csl.api/src/org/netbeans/modules/csl/api/CamelCaseOperations.java @@ -44,11 +44,14 @@ package org.netbeans.modules.csl.api; +import java.util.Collection; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.JTextComponent; +import org.netbeans.api.editor.mimelookup.MimeLookup; import org.netbeans.editor.BaseDocument; import org.netbeans.editor.Utilities; +import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor; import org.openide.ErrorManager; /** @@ -68,7 +71,16 @@ if (offset == doc.getLength()) { return -1; } - + Collection deleteWordHandlers = MimeLookup.getLookup(UiUtils.getMimePath(doc, offset)).lookupAll(DeleteWordHandler.class); + if (!deleteWordHandlers.isEmpty()) { + for (DeleteWordHandler dw :deleteWordHandlers) { + int nextOffset = dw.getNextWordOffset(doc, offset); + if (nextOffset != -1) { + return nextOffset; + } + } + } + KeystrokeHandler bc = UiUtils.getBracketCompletion(doc, offset); if (bc != null) { int nextOffset = bc.getNextWordOffset(doc, offset, false); @@ -96,6 +108,16 @@ final Document doc = textComponent.getDocument(); + Collection deleteWordHandlers = MimeLookup.getLookup(UiUtils.getMimePath(doc, offset)).lookupAll(DeleteWordHandler.class); + if (!deleteWordHandlers.isEmpty()) { + for (DeleteWordHandler dw :deleteWordHandlers) { + int nextOffset = dw.getPreviousWordOffset(doc, offset); + if (nextOffset != -1) { + return nextOffset; + } + } + } + KeystrokeHandler bc = UiUtils.getBracketCompletion(doc, offset); if (bc != null) { int nextOffset = bc.getNextWordOffset( diff --git a/csl.api/src/org/netbeans/modules/csl/api/KeystrokeHandler.java b/csl.api/src/org/netbeans/modules/csl/api/DeleteWordHandler.java copy from csl.api/src/org/netbeans/modules/csl/api/KeystrokeHandler.java copy to csl.api/src/org/netbeans/modules/csl/api/DeleteWordHandler.java --- a/csl.api/src/org/netbeans/modules/csl/api/KeystrokeHandler.java +++ b/csl.api/src/org/netbeans/modules/csl/api/DeleteWordHandler.java @@ -49,76 +49,27 @@ import javax.swing.text.JTextComponent; import org.netbeans.api.annotations.common.CheckForNull; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.modules.csl.core.CslDeletedTextInterceptor; import org.netbeans.modules.csl.spi.ParserResult; +import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor; /** - * Interface that a plugin can implement to assist with bracket completion during - * editing. - * - * @author Tor Norbye + * Interface that a plugin can implement to assist with Delete word. */ -public interface KeystrokeHandler { +public interface DeleteWordHandler { /** - * (Based on BracketCompletion class in NetBeans' java editor support) - * - * A hook method called after a character was inserted into the - * document. The function checks for special characters for - * completion ()[]'"{} and other conditions and optionally performs - * changes to the doc and or caret (complets braces, moves caret, - * etc.) - * - * Return true if the character was already inserted (and the IDE - * should not further insert anything) - * - * XXX Fix javadoc. + * Compute the next word position, if any. Can be used to implement + * camel case motion etc. + * + * @param doc The document to move in + * @param caretOffset The caret position corresponding to the current word + * @return The next word boundary offset in the given direction, or -1 if this + * implementation doesn't want to compute word boundaries (the default will be used) */ - boolean beforeCharInserted(@NonNull Document doc, int caretOffset, @NonNull JTextComponent target, char ch) - throws BadLocationException; - - /** @todo Rip out the boolean return value? What does it mean? */ - boolean afterCharInserted(@NonNull Document doc, int caretOffset, @NonNull JTextComponent target, char ch) - throws BadLocationException; - - /** - * (Based on KeystrokeHandler class in NetBeans' java editor support) - * - * Hook called after a character *ch* was backspace-deleted from - * *doc*. The function possibly removes bracket or quote pair if - * appropriate. - * @todo Document why both caretOffset and caret is passed in! - * Return the new offset, or -1 - */ - - /** @todo Split into before and after? */ - public boolean charBackspaced(@NonNull Document doc, int caretOffset, @NonNull JTextComponent target, char ch) - throws BadLocationException; - - /** - * A line break is being called. Return -1 to do nothing. - * If you want to modify the document first, you can do that, and then - * return the new offset to assign the caret to AFTER the newline has been - * inserted. - * - * @todo rip out return value - * @todo Document why both caretOffset and caret is passed in! - */ - int beforeBreak(@NonNull Document doc, int caretOffset, @NonNull JTextComponent target) - throws BadLocationException; - - /** - * Compute a range matching the caret position. If no eligible range - * is found, return {@link OffsetRange#NONE}. - */ - @NonNull - OffsetRange findMatching(@NonNull Document doc, int caretOffset); - - /** - * Compute set of selection ranges for the given parse tree (around the given offset), - * in leaf-to-root order. - */ - @NonNull - List findLogicalRanges(@NonNull ParserResult info, int caretOffset); + @CheckForNull + int getNextWordOffset(Document doc, int caretOffset); /** * Compute the previous word position, if any. Can be used to implement @@ -126,10 +77,9 @@ * * @param doc The document to move in * @param caretOffset The caret position corresponding to the current word - * @param reverse If true, move forwards, otherwise move backwards (e.g. "previous" word) - * @return The next word boundary offset in the given direction, or -1 if this + * @return The previous word boundary offset in the given direction, or -1 if this * implementation doesn't want to compute word boundaries (the default will be used) */ @CheckForNull - int getNextWordOffset(Document doc, int caretOffset, boolean reverse); + int getPreviousWordOffset(Document doc, int caretOffset); } diff --git a/csl.api/src/org/netbeans/modules/csl/api/KeystrokeHandler.java b/csl.api/src/org/netbeans/modules/csl/api/KeystrokeHandler.java --- a/csl.api/src/org/netbeans/modules/csl/api/KeystrokeHandler.java +++ b/csl.api/src/org/netbeans/modules/csl/api/KeystrokeHandler.java @@ -49,13 +49,16 @@ import javax.swing.text.JTextComponent; import org.netbeans.api.annotations.common.CheckForNull; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.modules.csl.core.CslDeletedTextInterceptor; import org.netbeans.modules.csl.spi.ParserResult; +import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor; /** * Interface that a plugin can implement to assist with bracket completion during * editing. - * + * @deprecated Use Typing Hooks instead, for details see Editor Library 2 and csL DeleteWordHandler. * @author Tor Norbye */ public interface KeystrokeHandler { diff --git a/csl.api/src/org/netbeans/modules/csl/api/UiUtils.java b/csl.api/src/org/netbeans/modules/csl/api/UiUtils.java --- a/csl.api/src/org/netbeans/modules/csl/api/UiUtils.java +++ b/csl.api/src/org/netbeans/modules/csl/api/UiUtils.java @@ -59,9 +59,11 @@ import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.JTextComponent; +import org.netbeans.api.editor.mimelookup.MimePath; import org.netbeans.api.lexer.TokenHierarchy; import org.netbeans.api.lexer.TokenSequence; import org.netbeans.api.progress.ProgressUtils; +import org.netbeans.lib.editor.util.swing.DocumentUtilities; import org.netbeans.modules.csl.api.DeclarationFinder.DeclarationLocation; import org.netbeans.modules.csl.core.Language; import org.netbeans.modules.csl.core.LanguageRegistry; @@ -346,4 +348,18 @@ } return result[0] != null ? result[0] : DeclarationLocation.NONE; } + + static MimePath getMimePath(final Document doc, final int offset) { + final MimePath[] mimePathR = new MimePath[1]; + doc.render(new Runnable() { + @Override + public void run() { + List> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true); + TokenSequence seq = seqs.isEmpty() ? null : seqs.get(seqs.size() - 1); + seq = seq == null ? TokenHierarchy.get(doc).tokenSequence() : seq; + mimePathR[0] = seq == null ? MimePath.parse(DocumentUtilities.getMimeType(doc)) : MimePath.parse(seq.languagePath().mimePath()); + } + }); + return mimePathR[0]; } +} diff --git a/csl.api/src/org/netbeans/modules/csl/core/CslDeletedTextInterceptor.java b/csl.api/src/org/netbeans/modules/csl/core/CslDeletedTextInterceptor.java new file mode 100644 --- /dev/null +++ b/csl.api/src/org/netbeans/modules/csl/core/CslDeletedTextInterceptor.java @@ -0,0 +1,87 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.csl.core; + +import javax.swing.text.BadLocationException; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.api.editor.mimelookup.MimeRegistrations; +import org.netbeans.modules.csl.api.KeystrokeHandler; +import org.netbeans.modules.csl.api.UiUtils; +import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor; + +public class CslDeletedTextInterceptor implements DeletedTextInterceptor { + + @Override + public boolean beforeRemove(Context context) throws BadLocationException { + return false; + } + + @Override + public void remove(Context context) throws BadLocationException { + } + + @Override + public void afterRemove(Context context) throws BadLocationException { + if (CslEditorKit.completionSettingEnabled()) { + KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(context.getDocument(), context.getOffset()); + if (bracketCompletion != null) { + bracketCompletion.charBackspaced(context.getDocument(), context.getComponent().getCaretPosition(), context.getComponent(), context.getText().charAt(0)); + } + } + } + + @Override + public void cancelled(Context context) { + } + + @MimeRegistrations(value = { + @MimeRegistration(mimeType = "", service = DeletedTextInterceptor.Factory.class)}) + public static class Factory implements DeletedTextInterceptor.Factory { + + @Override + public DeletedTextInterceptor createDeletedTextInterceptor(MimePath mimePath) { + return new CslDeletedTextInterceptor(); + } + } + +} diff --git a/csl.api/src/org/netbeans/modules/csl/core/CslEditorKit.java b/csl.api/src/org/netbeans/modules/csl/core/CslEditorKit.java --- a/csl.api/src/org/netbeans/modules/csl/core/CslEditorKit.java +++ b/csl.api/src/org/netbeans/modules/csl/core/CslEditorKit.java @@ -51,13 +51,14 @@ import javax.swing.JMenuItem; import javax.swing.KeyStroke; import javax.swing.text.BadLocationException; -import javax.swing.text.Caret; import javax.swing.text.Document; import javax.swing.text.EditorKit; import javax.swing.text.JTextComponent; import javax.swing.text.Keymap; import javax.swing.text.TextAction; import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.api.editor.mimelookup.MimeRegistrations; import org.netbeans.editor.BaseAction; import org.netbeans.editor.BaseDocument; import org.netbeans.editor.BaseKit; @@ -69,7 +70,6 @@ import org.netbeans.modules.csl.api.CslActions; import org.netbeans.modules.csl.api.DeleteToNextCamelCasePosition; import org.netbeans.modules.csl.api.DeleteToPreviousCamelCasePosition; -import org.netbeans.modules.csl.api.GoToDeclarationAction; import org.netbeans.modules.csl.api.InstantRenameAction; import org.netbeans.modules.csl.api.KeystrokeHandler; import org.netbeans.modules.csl.api.NextCamelCasePosition; @@ -82,9 +82,13 @@ import org.netbeans.modules.csl.api.UiUtils; import org.netbeans.modules.csl.api.GoToMarkOccurrencesAction; import org.netbeans.modules.editor.NbEditorKit; +import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor; +import org.netbeans.spi.editor.typinghooks.DeletedTextInterceptor.Context; +import org.netbeans.spi.editor.typinghooks.TypedBreakInterceptor; +import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor; +import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor.MutableContext; import org.openide.awt.Mnemonics; import org.openide.filesystems.FileObject; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; /** @@ -164,10 +168,6 @@ Action[] superActions = super.createActions(); Language language = LanguageRegistry.getInstance().getLanguageByMimeType(mimeType); ArrayList actions = new ArrayList(30); - - actions.add(new GsfDefaultKeyTypedAction()); - actions.add(new GsfInsertBreakAction()); - actions.add(new GsfDeleteCharAction(deletePrevCharAction, false)); // The php needs to handle special cases of toggle comment. There has to be // registered ToggleBlockCommentAction in PHP that handles these special cases, @@ -226,172 +226,11 @@ /** * Returns true if bracket completion is enabled in options. */ - private static boolean completionSettingEnabled() { + static boolean completionSettingEnabled() { //return ((Boolean)Settings.getValue(GsfEditorKit.class, JavaSettingsNames.PAIR_CHARACTERS_COMPLETION)).booleanValue(); return true; } - - private final class GsfDefaultKeyTypedAction extends ExtDefaultKeyTypedAction { - private JTextComponent currentTarget; - private String replacedText = null; - - @Override - public void actionPerformed(ActionEvent evt, JTextComponent target) { - currentTarget = target; - super.actionPerformed(evt, target); - currentTarget = null; - } - - @Override - protected void insertString(BaseDocument doc, int dotPos, Caret caret, String str, - boolean overwrite) throws BadLocationException { - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); - - if (bracketCompletion != null) { - // TODO - check if we're in a comment etc. and if so, do nothing - boolean handled = - bracketCompletion.beforeCharInserted(doc, dotPos, currentTarget, - str.charAt(0)); - - if (!handled) { - super.insertString(doc, dotPos, caret, str, overwrite); - handled = bracketCompletion.afterCharInserted(doc, dotPos, currentTarget, - str.charAt(0)); - } - - return; - } - } - - super.insertString(doc, dotPos, caret, str, overwrite); - } - - @Override - protected void replaceSelection(JTextComponent target, int dotPos, Caret caret, - String str, boolean overwrite) throws BadLocationException { - if (str.equals("")) { - return; - } - char insertedChar = str.charAt(0); - Document document = target.getDocument(); - - if (document instanceof BaseDocument) { - BaseDocument doc = (BaseDocument)document; - - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); - - if (bracketCompletion != null) { - try { - int caretPosition = caret.getDot(); - - boolean handled = - bracketCompletion.beforeCharInserted(doc, caretPosition, - target, insertedChar); - - int p0 = Math.min(caret.getDot(), caret.getMark()); - int p1 = Math.max(caret.getDot(), caret.getMark()); - - if (p0 != p1) { - doc.remove(p0, p1 - p0); - } - - if (!handled) { - if ((str != null) && (str.length() > 0)) { - doc.insertString(p0, str, null); - } - - bracketCompletion.afterCharInserted(doc, caret.getDot() - 1, - target, insertedChar); - } - } catch (BadLocationException e) { - e.printStackTrace(); - } - - return; - } - } - } - - super.replaceSelection(target, dotPos, caret, str, overwrite); - } - } - - private final class GsfInsertBreakAction extends InsertBreakAction { - static final long serialVersionUID = -1506173310438326380L; - - @Override - protected Object beforeBreak(JTextComponent target, BaseDocument doc, Caret caret) { - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, caret.getDot()); - - if (bracketCompletion != null) { - try { - int newOffset = bracketCompletion.beforeBreak(doc, caret.getDot(), target); - - if (newOffset >= 0) { - return new Integer(newOffset); - } - } catch (BadLocationException ble) { - Exceptions.printStackTrace(ble); - } - } - } - - // return Boolean.TRUE; - return null; - } - - @Override - protected void afterBreak(JTextComponent target, BaseDocument doc, Caret caret, - Object cookie) { - if (completionSettingEnabled()) { - if (cookie != null) { - if (cookie instanceof Integer) { - // integer - int dotPos = ((Integer)cookie).intValue(); - if (dotPos != -1) { - caret.setDot(dotPos); - } else { - int nowDotPos = caret.getDot(); - caret.setDot(nowDotPos + 1); - } - } - } - } - } - } - - private final class GsfDeleteCharAction extends ExtDeleteCharAction { - private JTextComponent currentTarget; - - public GsfDeleteCharAction(String nm, boolean nextChar) { - super(nm, nextChar); - } - - @Override - public void actionPerformed(ActionEvent evt, JTextComponent target) { - currentTarget = target; - super.actionPerformed(evt, target); - currentTarget = null; - } - - @Override - protected void charBackspaced(BaseDocument doc, int dotPos, Caret caret, char ch) - throws BadLocationException { - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); - - if (bracketCompletion != null) { - boolean success = bracketCompletion.charBackspaced(doc, dotPos, currentTarget, ch); - return; - } - } - super.charBackspaced(doc, dotPos, caret, ch); - } - } - + private final class GenericGenerateGoToPopupAction extends NbGenerateGoToPopupAction { @Override public void actionPerformed(ActionEvent evt, JTextComponent target) { @@ -501,6 +340,4 @@ return jm; } } - - } diff --git a/csl.api/src/org/netbeans/modules/csl/core/CslTypedBreakInterceptor.java b/csl.api/src/org/netbeans/modules/csl/core/CslTypedBreakInterceptor.java new file mode 100644 --- /dev/null +++ b/csl.api/src/org/netbeans/modules/csl/core/CslTypedBreakInterceptor.java @@ -0,0 +1,97 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.csl.core; + +import javax.swing.text.BadLocationException; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.api.editor.mimelookup.MimeRegistrations; +import org.netbeans.modules.csl.api.KeystrokeHandler; +import org.netbeans.modules.csl.api.UiUtils; +import org.netbeans.spi.editor.typinghooks.TypedBreakInterceptor; + +public class CslTypedBreakInterceptor implements TypedBreakInterceptor { + + private int caretPosition = -1; + + @Override + public boolean beforeInsert(Context context) throws BadLocationException { + return false; + } + + @Override + public void insert(MutableContext context) throws BadLocationException { + if (CslEditorKit.completionSettingEnabled()) { + KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(context.getDocument(), context.getCaretOffset()); + if (bracketCompletion != null) { + int newOffset = bracketCompletion.beforeBreak(context.getDocument(), context.getCaretOffset(), context.getComponent()); + if (newOffset >= 0) { + caretPosition = newOffset; + } + } + } + } + + @Override + public void afterInsert(Context context) throws BadLocationException { + if (CslEditorKit.completionSettingEnabled()) { + if (caretPosition != -1) { + context.getComponent().getCaret().setDot(caretPosition); + caretPosition = -1; + } + } + } + + @Override + public void cancelled(Context context) { + } + + @MimeRegistrations(value = { + @MimeRegistration(mimeType = "", service = TypedBreakInterceptor.Factory.class)}) + public static class Factory implements TypedBreakInterceptor.Factory { + + @Override + public TypedBreakInterceptor createTypedBreakInterceptor(MimePath mimePath) { + return new CslTypedBreakInterceptor(); + } + } +} diff --git a/csl.api/src/org/netbeans/modules/csl/core/CslTypedTextInterceptor.java b/csl.api/src/org/netbeans/modules/csl/core/CslTypedTextInterceptor.java new file mode 100644 --- /dev/null +++ b/csl.api/src/org/netbeans/modules/csl/core/CslTypedTextInterceptor.java @@ -0,0 +1,116 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.csl.core; + +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.JTextComponent; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.api.editor.mimelookup.MimeRegistrations; +import org.netbeans.modules.csl.api.KeystrokeHandler; +import org.netbeans.modules.csl.api.UiUtils; +import org.netbeans.spi.editor.typinghooks.TypedTextInterceptor; + +public class CslTypedTextInterceptor implements TypedTextInterceptor { + + private boolean handled = true; + + @Override + public boolean beforeInsert(Context context) throws BadLocationException { + return false; + } + + @Override + public void insert(MutableContext context) throws BadLocationException { + if (CslEditorKit.completionSettingEnabled()) { + Document doc = context.getDocument(); + int dotPos = context.getOffset(); + KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); + if (bracketCompletion != null) { + JTextComponent currentTarget = context.getComponent(); + String str = context.getText(); + // TODO - check if we're in a comment etc. and if so, do nothing + handled = bracketCompletion.beforeCharInserted(doc, dotPos, currentTarget, str.charAt(0)); + if (handled) { + context.setText("", 0); + } + } + } + } + + @Override + public void afterInsert(Context context) throws BadLocationException { + if (CslEditorKit.completionSettingEnabled()) { + if (!handled) { + Document doc = context.getDocument(); + int dotPos = context.getOffset(); + KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); + if (bracketCompletion != null) { + JTextComponent currentTarget = context.getComponent(); + String str = context.getText(); + bracketCompletion.afterCharInserted(doc, dotPos, currentTarget, str.charAt(0)); + } + handled = true; + } else { + KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(context.getDocument(), context.getOffset()); + if (bracketCompletion != null) { + context.getComponent().getCaret().setDot(context.getComponent().getCaret().getDot() + 1); + } + } + } + } + + @Override + public void cancelled(Context context) { + } + + @MimeRegistrations(value = { + @MimeRegistration(mimeType = "", service = TypedTextInterceptor.Factory.class)}) + public static class Factory implements TypedTextInterceptor.Factory { + + @Override + public TypedTextInterceptor createTypedTextInterceptor(MimePath mimePath) { + return new CslTypedTextInterceptor(); + } + } +} diff --git a/csl.api/src/org/netbeans/modules/csl/core/Language.java b/csl.api/src/org/netbeans/modules/csl/core/Language.java --- a/csl.api/src/org/netbeans/modules/csl/core/Language.java +++ b/csl.api/src/org/netbeans/modules/csl/core/Language.java @@ -252,7 +252,7 @@ } else if (language instanceof DefaultLanguageConfig) { languageConfig = (DefaultLanguageConfig)language; } - } + } return language; } @@ -782,5 +782,4 @@ void setOverridingMethodsFile(FileObject fo) { this.overridingMethodsFile = fo; } - } diff --git a/csl.api/test/unit/src/org/netbeans/modules/csl/editor/TypingCompletion.java b/csl.api/test/unit/src/org/netbeans/modules/csl/editor/TypingCompletion.java new file mode 100644 --- /dev/null +++ b/csl.api/test/unit/src/org/netbeans/modules/csl/editor/TypingCompletion.java @@ -0,0 +1,199 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2012 Sun Microsystems, Inc. + */ +package org.netbeans.modules.csl.editor; + +import java.awt.EventQueue; +import java.awt.event.KeyEvent; +import javax.swing.JEditorPane; +import javax.swing.SwingUtilities; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.EditorKit; +import junit.framework.TestCase; +import org.netbeans.api.lexer.Language; +import org.netbeans.lib.editor.util.CharSequenceUtilities; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; +import org.openide.util.lookup.ServiceProvider; + +/** + * Test brackets completion - unlike the original test this one + * emulates real typing and tests the resulting state of the document. + */ +public class TypingCompletion { + public static final class Context { + + private JEditorPane pane; + + public Context(final EditorKit kit, final Language language, final String mimetype, final String textWithPipe) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + pane = new JEditorPane(); + pane.setEditorKit(kit); + Document doc = pane.getDocument(); + // Required by Java's default key typed + doc.putProperty(Language.class, language); + doc.putProperty("mimeType", mimetype); + int caretOffset = textWithPipe.indexOf('|'); + String text; + if (caretOffset != -1) { + text = textWithPipe.substring(0, caretOffset) + textWithPipe.substring(caretOffset + 1); + } else { + text = textWithPipe; + } + pane.setText(text); + pane.setCaretPosition((caretOffset != -1) ? caretOffset : doc.getLength()); + } + }); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + public JEditorPane pane() { + return pane; + } + + public Document document() { + return pane.getDocument(); + } + + public void typeChar(final char ch) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + KeyEvent keyEvent; + switch (ch) { + case '\n': + keyEvent = new KeyEvent(pane, KeyEvent.KEY_PRESSED, + EventQueue.getMostRecentEventTime(), + 0, KeyEvent.VK_ENTER, KeyEvent.CHAR_UNDEFINED); // Simulate pressing of Enter + break; + case '\b': + keyEvent = new KeyEvent(pane, KeyEvent.KEY_PRESSED, + EventQueue.getMostRecentEventTime(), + 0, KeyEvent.VK_BACK_SPACE, KeyEvent.CHAR_UNDEFINED); // Simulate pressing of BackSpace + break; + case '\f': + keyEvent = new KeyEvent(pane, KeyEvent.KEY_PRESSED, + EventQueue.getMostRecentEventTime(), + 0, KeyEvent.VK_DELETE, KeyEvent.CHAR_UNDEFINED); // Simulate pressing of Delete + break; + default: + keyEvent = new KeyEvent(pane, KeyEvent.KEY_TYPED, + EventQueue.getMostRecentEventTime(), + 0, KeyEvent.VK_UNDEFINED, ch); + } + SwingUtilities.processKeyBindings(keyEvent); + } + }); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + public void typeText(String text) { + for (int i = 0; i < text.length(); i++) { + typeChar(text.charAt(i)); + } + } + + public void assertDocumentTextEquals(final String textWithPipe) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + int caretOffset = textWithPipe.indexOf('|'); + String text; + if (caretOffset != -1) { + text = textWithPipe.substring(0, caretOffset) + textWithPipe.substring(caretOffset + 1); + } else { + text = textWithPipe; + } + try { + // Use debug text to prefix special chars for easier readability + text = CharSequenceUtilities.debugText(text); + String docText = document().getText(0, document().getLength()); + docText = CharSequenceUtilities.debugText(docText); + if (!text.equals(docText)) { + int diffIndex = 0; + int minLen = Math.min(docText.length(), text.length()); + while (diffIndex < minLen) { + if (text.charAt(diffIndex) != docText.charAt(diffIndex)) { + break; + } + diffIndex++; + } + TestCase.fail("Invalid document text - diff at index " + diffIndex + + "\nExpected: \"" + text + + "\"\n Actual: \"" + docText + "\"" + ); + } + } catch (BadLocationException e) { + throw new IllegalStateException(e); + } + if (caretOffset != -1) { + TestCase.assertEquals("Invalid caret offset", caretOffset, pane.getCaretPosition()); + } + } + }); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + } + + @ServiceProvider(service=MIMEResolver.class) + public static final class MIMEResolverImpl extends MIMEResolver { + + public MIMEResolverImpl() { + super("text/x-nbeditor-keybindingsettings"); + } + + @Override public String findMIMEType(FileObject fo) { + return fo.getPath().contains("Keybindings") ? "text/x-nbeditor-keybindingsettings" : null; + } + } +} diff --git a/html.editor/src/org/netbeans/modules/html/editor/api/HtmlKit.java b/html.editor/src/org/netbeans/modules/html/editor/api/HtmlKit.java --- a/html.editor/src/org/netbeans/modules/html/editor/api/HtmlKit.java +++ b/html.editor/src/org/netbeans/modules/html/editor/api/HtmlKit.java @@ -123,25 +123,10 @@ c.setTransferHandler(new HtmlTransferHandler()); } - protected DeleteCharAction createDeletePrevAction() { - return new HtmlDeleteCharAction(deletePrevCharAction, false); - } - - protected ExtDefaultKeyTypedAction createDefaultKeyTypedAction() { - return new HtmlDefaultKeyTypedAction(); - } - - protected InsertBreakAction createInsertBreakAction() { - return new HtmlInsertBreakAction(); - } @Override protected Action[] createActions() { Action[] HtmlActions = new Action[]{ - createInsertBreakAction(), - createDefaultKeyTypedAction(), - createDeletePrevAction(), - new HtmlDeleteCharAction(deleteNextCharAction, true), CslActions.createSelectCodeElementAction(true), CslActions.createSelectCodeElementAction(false), CslActions.createInstantRenameAction(), @@ -370,190 +355,6 @@ } } - - public class HtmlInsertBreakAction extends InsertBreakAction { - - static final long serialVersionUID = -1506173310438326380L; - - @Override - protected Object beforeBreak(JTextComponent target, BaseDocument doc, Caret caret) { - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, caret.getDot()); - - if (bracketCompletion != null) { - try { - int newOffset = bracketCompletion.beforeBreak(doc, caret.getDot(), target); - - if (newOffset >= 0) { - return new Integer(newOffset); - } - } catch (BadLocationException ble) { - Exceptions.printStackTrace(ble); - } - } - } - - // return Boolean.TRUE; - return null; - } - - @Override - protected void afterBreak(JTextComponent target, BaseDocument doc, Caret caret, - Object cookie) { - if (completionSettingEnabled()) { - if (cookie != null) { - if (cookie instanceof Integer) { - // integer - int dotPos = ((Integer) cookie).intValue(); - if (dotPos != -1) { - caret.setDot(dotPos); - } else { - int nowDotPos = caret.getDot(); - caret.setDot(nowDotPos + 1); - } - } - } - } - } - } - - public static class HtmlDefaultKeyTypedAction extends ExtDefaultKeyTypedAction { - - private JTextComponent currentTarget; - - @Override - public void actionPerformed(ActionEvent evt, JTextComponent target) { - currentTarget = target; - super.actionPerformed(evt, target); - currentTarget = null; - } - - @Override - protected void insertString(BaseDocument doc, int dotPos, - Caret caret, String str, - boolean overwrite) throws BadLocationException { - - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); - - if (bracketCompletion != null) { - // TODO - check if we're in a comment etc. and if so, do nothing - boolean handled = - bracketCompletion.beforeCharInserted(doc, dotPos, currentTarget, - str.charAt(0)); - - if (!handled) { - super.insertString(doc, dotPos, caret, str, overwrite); - handled = bracketCompletion.afterCharInserted(doc, dotPos, currentTarget, - str.charAt(0)); - } - - - return; - } - } - - super.insertString(doc, dotPos, caret, str, overwrite); - } - - @Override - protected void replaceSelection(JTextComponent target, int dotPos, Caret caret, - String str, boolean overwrite) throws BadLocationException { - - //workaround for #209019 - regression of issue - //#204450 - Rewrite actions to use TypingHooks SPI - if(str.length() == 0) { - //called from BaseKit.actionPerformed():1160 with empty str argument - //==> ignore this call since we are going to be called a bit later - //from HtmlKit.performTextInsertion() properly with the text typed - return ; - } - - char insertedChar = str.charAt(0); - Document document = target.getDocument(); - - if (document instanceof BaseDocument) { - BaseDocument doc = (BaseDocument) document; - - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); - - if (bracketCompletion != null) { - try { - int caretPosition = caret.getDot(); - - boolean handled = - bracketCompletion.beforeCharInserted(doc, caretPosition, - target, insertedChar); - - int p0 = Math.min(caret.getDot(), caret.getMark()); - int p1 = Math.max(caret.getDot(), caret.getMark()); - - if (p0 != p1) { - doc.remove(p0, p1 - p0); - } - - if (!handled) { - if ((str != null) && (str.length() > 0)) { - doc.insertString(p0, str, null); - } - - bracketCompletion.afterCharInserted(doc, caret.getDot() - 1, - target, insertedChar); - - } - } catch (BadLocationException e) { - e.printStackTrace(); - } - - return; - } - } - } - - super.replaceSelection(target, dotPos, caret, str, overwrite); - } - - } - - public static class HtmlDeleteCharAction extends DeleteCharAction { - - private JTextComponent currentTarget; - - public HtmlDeleteCharAction(String name, boolean nextChar) { - super(name, nextChar); - } - - @Override - public void actionPerformed(ActionEvent evt, JTextComponent target) { - try { - currentTarget = target; - super.actionPerformed(evt, target); - } finally { - currentTarget = null; - } - } - - @Override - protected void charBackspaced(BaseDocument doc, int dotPos, Caret caret, char ch) throws BadLocationException { - if (completionSettingEnabled()) { - KeystrokeHandler bracketCompletion = UiUtils.getBracketCompletion(doc, dotPos); - - if (bracketCompletion != null) { - boolean success = bracketCompletion.charBackspaced(doc, dotPos, currentTarget, ch); - return; - } - } - - - super.charBackspaced(doc, dotPos, caret, ch); - } - - public boolean getNextChar() { - return nextChar; - } - } - /* !!!!!!!!!!!!!!!!!!!!! * * Inner classes bellow were taken from BasicTextUI and rewritten in the place marked diff --git a/java.editor/test/unit/src/org/netbeans/modules/editor/java/TypingCompletionUnitTest.java b/html.editor/test/unit/src/org/netbeans/modules/html/editor/gsf/TypingCompletionUnitTest.java copy from java.editor/test/unit/src/org/netbeans/modules/editor/java/TypingCompletionUnitTest.java copy to html.editor/test/unit/src/org/netbeans/modules/html/editor/gsf/TypingCompletionUnitTest.java --- a/java.editor/test/unit/src/org/netbeans/modules/editor/java/TypingCompletionUnitTest.java +++ b/html.editor/test/unit/src/org/netbeans/modules/html/editor/gsf/TypingCompletionUnitTest.java @@ -42,36 +42,21 @@ * made subject to such option by the copyright holder. */ -package org.netbeans.modules.editor.java; +package org.netbeans.modules.html.editor.gsf; -import java.awt.EventQueue; -import java.awt.event.KeyEvent; import java.util.prefs.Preferences; -import java.util.regex.Pattern; -import javax.swing.JEditorPane; -import javax.swing.SwingUtilities; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.EditorKit; -import javax.swing.text.PlainDocument; -import junit.framework.TestCase; import org.netbeans.api.editor.mimelookup.MimeLookup; import org.netbeans.api.editor.settings.SimpleValueNames; -import org.netbeans.api.java.lexer.JavaTokenId; -import org.netbeans.api.lexer.Language; +import org.netbeans.api.html.lexer.HTMLTokenId; import org.netbeans.junit.NbTestCase; -import org.netbeans.lib.editor.util.CharSequenceUtilities; +import org.netbeans.modules.csl.editor.TypingCompletion; +import org.netbeans.modules.html.editor.api.HtmlKit; import org.openide.awt.AcceleratorBinding; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.MIMEResolver; -import org.openide.util.lookup.ServiceProvider; /** * Test java brackets completion - unlike the original test this one * emulates real typing and tests the resulting state of the document. - * - * @autor Miloslav Metelka */ public class TypingCompletionUnitTest extends NbTestCase { @@ -82,1311 +67,94 @@ @Override protected void setUp() throws Exception { super.setUp(); - Preferences prefs = MimeLookup.getLookup(JavaKit.JAVA_MIME_TYPE).lookup(Preferences.class); + Preferences prefs = MimeLookup.getLookup(HtmlKit.HTML_MIME_TYPE).lookup(Preferences.class); prefs.putBoolean(SimpleValueNames.COMPLETION_PAIR_CHARACTERS, true); Class.forName(AcceleratorBinding.class.getName(), true, AcceleratorBinding.class.getClassLoader()); } // ------- Tests for completion of right parenthesis ')' ------------- - public void testTypeSemicolonInForLoop() { // #146139 - Context ctx = new Context(new JavaKit(), - "for (int i = 0|)" + public void testQuoteCompletion() { + TypingCompletion.Context ctx = new TypingCompletion.Context(new HtmlKit(), HTMLTokenId.language(), HtmlKit.HTML_MIME_TYPE, + "
6) {\n" + - "}" - ); - ctx.typeChar(')'); - ctx.assertDocumentTextEquals( - "if (a())| + 5 > 6) {\n" + - "}" - ); - } - - public void testTypeRightParenNoSkipNonBracketChar() { - Context ctx = new Context(new JavaKit(), - "m()|" - ); - ctx.typeChar(' '); - ctx.assertDocumentTextEquals( - "m() |" - ); - } - - - - // ------- Tests for completion of right brace '}' ------------- - - public void testTypeAddRightBraceIfLeftBrace() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) {|\n" + - " }\n" + - "}\n" - ); - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) {\n" + - " |\n" + - " }\n" + - " }\n" + - "}\n" - ); - } - - public void testTypeAddRightBraceIfLeftBraceWhiteSpace() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) { \t|\n" + - " }\n" + - "}\n" - ); - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) { \t\n" + - " |\n" + - " }\n" + - " }\n" + - "}\n" - ); - } - - public void testTypeAddRightBraceIfLeftBraceLineComment() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) { // line-comment|\n" + - " }\n" + - "}\n" - ); - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) { // line-comment\n" + - " |\n" + - " }\n" + - " }\n" + - "}\n" - ); - } - - public void testTypeAddRightBraceIfLeftBraceBlockComment() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) { /* block-comment */|\n" + - " }\n" + - "}\n" - ); - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) { /* block-comment */\n" + - " |\n" + - " }\n" + - " }\n" + - "}\n" - ); - } - - public void testTypeAddRightBraceIfLeftBraceAlreadyPresent() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) {|\n" + - " }\n" + - " }\n" + - "}\n" - ); - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) {\n" + - " |\n" + - " }\n" + - " }\n" + - "}\n" - ); - } - - public void XtestTypeAddRightBraceCaretInComment() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) { /* unclosed-block-comment|\n" + - " */\n" + - " }\n" + - "}\n" - ); - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) { /* unclosed-block-comment\n" + - " * |\n" + - " */\n" + - " }\n" + - "}\n" - ); - } - - public void testTypeAddRightBraceMultiLine() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) {| System.out.println(\n" + - " \"\");\n" + - " }\n" + - "}\n" - ); - - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) {\n" + - " System.out.println(\n" + - " \"\");\n" + - " }\n" + - "}\n" - ); - } - - public void testTypeAddRightBraceSingleLine() { - Context ctx = new Context(new JavaKit(), - "class Test {\n" + - " {\n" + - " if (true) {| System.out.println(\"\");\n" + - " }\n" + - "}\n" - ); - - ctx.typeChar('\n'); - ctx.assertDocumentTextEquals( - "class Test {\n" + - " {\n" + - " if (true) {\n" + - " System.out.println(\"\");\n" + - " }\n" + - " }\n" + - "}\n" - ); - } - - - // ------- Tests for completion of quote (") ------------- - public void testTypeSimpleQuoteInEmptyDoc () throws Exception { - Context ctx = new Context(new JavaKit(), - "|" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - "\"|\"" - ); - } - - public void testTypeSimpleQuoteAtBeginingOfDoc () throws Exception { - Context ctx = new Context(new JavaKit(), - "| " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - "\"|\" " - ); - } - - public void testTypeSimpleQuoteAtEndOfDoc () throws Exception { - Context ctx = new Context(new JavaKit(), - " |" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " \"|\"" - ); - } - - public void testTypeSimpleQuoteInWhiteSpaceArea () throws Exception { - Context ctx = new Context(new JavaKit(), - " | " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " \"|\" " - ); - } - - public void testTypeQuoteAtEOL () throws Exception { - Context ctx = new Context(new JavaKit(), - " |\n" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " \"|\"\n" - ); - } - - public void testTypeQuoteWithUnterminatedStringLiteral () throws Exception { - Context ctx = new Context(new JavaKit(), - " \"unterminated string| \n" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " \"unterminated string\"| \n" - ); - } - - public void testTypeQuoteAtEOLWithUnterminatedStringLiteral () throws Exception { - Context ctx = new Context(new JavaKit(), - " \"unterminated string | \n" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " \"unterminated string \"| \n" - ); - } - - public void testTypeQuoteInsideStringLiteral () throws Exception { - Context ctx = new Context(new JavaKit(), - " \"stri|ng literal\" " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " \"stri\"|ng literal\" " - ); - } - - public void testTypeQuoteInsideEmptyParentheses () throws Exception { - Context ctx = new Context(new JavaKit(), - " System.out.println(|) " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " System.out.println(\"|\") " - ); - } - - public void testTypeQuoteInsideNonEmptyParentheses () throws Exception { - Context ctx = new Context(new JavaKit(), - " System.out.println(|some text) " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " System.out.println(\"|some text) " - ); - } - - public void testTypeQuoteInsideNonEmptyParenthesesBeforeClosingParentheses () throws Exception { - Context ctx = new Context(new JavaKit(), - " System.out.println(i+|) " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " System.out.println(i+\"|\") " - ); - } - - public void testTypeQuoteInsideNonEmptyParenthesesBeforeClosingParenthesesAndUnterminatedStringLiteral () throws Exception { - Context ctx = new Context(new JavaKit(), - " System.out.println(\"unterminated string literal |); " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " System.out.println(\"unterminated string literal \"|); " - ); - } - - public void testTypeQuoteBeforePlus () throws Exception { - Context ctx = new Context(new JavaKit(), - " System.out.println(|+\"string literal\"); " - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - " System.out.println(\"|\"+\"string literal\"); " - ); - } - - public void testTypeQuoteBeforeComma () throws Exception { - Context ctx = new Context(new JavaKit(), - "String s[] = new String[]{|,\"two\"};" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - "String s[] = new String[]{\"|\",\"two\"};" - ); - } - - public void testTypeQuoteBeforeBrace () throws Exception { - Context ctx = new Context(new JavaKit(), - "String s[] = new String[]{\"one\",|};" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - "String s[] = new String[]{\"one\",\"|\"};" - ); - } - - public void testTypeQuoteBeforeSemicolon() throws Exception { - Context ctx = new Context(new JavaKit(), - "String s = \"\" + |;" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - "String s = \"\" + \"|\";" - ); - } - - public void testTypeQuoteBeforeSemicolonWithWhitespace() throws Exception { - Context ctx = new Context(new JavaKit(), - "String s = \"\" +| ;" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - "String s = \"\" +\"|\" ;" - ); - } - - public void testTypeQuoteAfterEscapeSequence() throws Exception { - Context ctx = new Context(new JavaKit(), - "\\|" - ); - ctx.typeChar('"'); - ctx.assertDocumentTextEquals( - "\\\"|" - ); - } - - public void testTypeQuoteEaten() throws Exception { - Context ctx = new Context(new JavaKit(), - "|" - ); - ctx.typeChar('"'); ctx.typeChar('"'); ctx.assertDocumentTextEquals( "\"\"|" ); } - - public void testTypeQuoteOnFirstQuote () throws Exception { - Context ctx = new Context(new JavaKit(), - " |\"asdf\"" + + public void testBackSlash() { + TypingCompletion.Context ctx = new TypingCompletion.Context(new HtmlKit(), HTMLTokenId.language(), HtmlKit.HTML_MIME_TYPE, + "|" + ); + } + + public void testChangeQuote() { + TypingCompletion.Context ctx = new TypingCompletion.Context(new HtmlKit(), HTMLTokenId.language(), HtmlKit.HTML_MIME_TYPE, + "