/******************************************************************************* * Copyright (c) 2007, 2008 Edgar Espina. * 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.deved.antlride.internal.ui.text; import org.eclipse.dltk.ui.PreferenceConstants; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.IAutoEditStrategy; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.TextUtilities; public class AntlrAutoClosePairEditStrategy implements IAutoEditStrategy { private IPreferenceStore fStore; private String fPartitioning; public AntlrAutoClosePairEditStrategy(IPreferenceStore store, String partitioning) { fStore = store; fPartitioning = partitioning; } public void customizeDocumentCommand(IDocument d, DocumentCommand c) { if (c.doit == false) return; if (c.length <= 1 && c.text.length() == 1) { switch (c.text.charAt(0)) { case '\"': case '\'': case '(': case '{': case '[': case '}': case ']': case ')': // check partition String partitioning = getRegionType(d, c.offset); if (partitioning == null || partitioning != IDocument.DEFAULT_CONTENT_TYPE) return; autoClose(d, c); break; } } } private boolean closeBrackets() { return fStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_BRACKETS); } private boolean closeBraces() { return fStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_BRACES); } private boolean closeStrings() { return fStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_STRINGS); } private void autoClose(IDocument document, DocumentCommand command) { if (command.offset == -1) return; try { if (document.getChar(command.offset - 1) == '\\') return; } catch (BadLocationException e1) { } if ('\"' == command.text.charAt(0) && !closeStrings()) return; if ('\'' == command.text.charAt(0) && !closeStrings()) return; if (!closeBrackets() && ('[' == command.text.charAt(0) || '(' == command.text .charAt(0))) return; if (!closeBraces() && ('{' == command.text.charAt(0))) return; try { switch (command.text.charAt(0)) { case '\"': case '\'': // if we close existing quote, do nothing if ('\"' == command.text.charAt(0) && command.offset > 0 && "\"".equals(document.get(command.offset - 1, 1))) return; if ('\'' == command.text.charAt(0) && command.offset > 0 && "\'".equals(document.get(command.offset - 1, 1))) return; if (command.offset != document.getLength() && command.text.charAt(0) == document.get( command.offset, 1).charAt(0)) command.text = ""; else { command.text += command.text; command.length = 0; } command.shiftsCaret = false; command.caretOffset = command.offset + 1; break; case '(': case '{': case '[': if (command.offset != document.getLength() && command.text.charAt(0) == document.get( command.offset, 1).charAt(0)) return; // add closing peer command.text = command.text + getBracePair(command.text.charAt(0)); command.length = 0; command.shiftsCaret = false; command.caretOffset = command.offset + 1; break; case '}': if (!closeBraces()) return; // if we already have bracket we should jump over it if (command.offset != document.getLength() && command.text.charAt(0) == document.get( command.offset, 1).charAt(0)) { command.text = ""; command.shiftsCaret = false; command.caretOffset = command.offset + 1; return; } break; case ']': case ')': if (!closeBrackets()) return; // if we already have bracket we should jump over it if (command.offset != document.getLength() && command.text.charAt(0) == document.get( command.offset, 1).charAt(0)) { command.text = ""; command.shiftsCaret = false; command.caretOffset = command.offset + 1; return; } break; } } catch (BadLocationException e) { e.printStackTrace(); } } private char getBracePair(char ch) { switch (ch) { case '(': return ')'; case ')': return '('; case '[': return ']'; case ']': return '['; case '{': return '}'; case '}': return '{'; case '\"': return '\"'; case '\'': return '\''; } return ch; } private String getRegionType(IDocument d, int offset) { try { int p = ((offset == d.getLength()) ? offset - 1 : offset); ITypedRegion region; region = TextUtilities.getPartition(d, fPartitioning, p, true); return region.getType(); } catch (BadLocationException ex) { } return null; } }