You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by jo...@apache.org on 2011/08/01 16:38:36 UTC

svn commit: r1152804 [11/15] - in /uima/sandbox/trunk/TextMarker: org.apache.uima.tm.dltk.debug.ui/ org.apache.uima.tm.dltk.debug.ui/META-INF/ org.apache.uima.tm.dltk.debug.ui/bin/ org.apache.uima.tm.dltk.debug.ui/icons/ org.apache.uima.tm.dltk.debug.u...

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/SimpleTextMarkerSourceViewerConfiguration.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/SimpleTextMarkerSourceViewerConfiguration.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/SimpleTextMarkerSourceViewerConfiguration.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/SimpleTextMarkerSourceViewerConfiguration.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,87 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import org.eclipse.dltk.ui.text.IColorManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.formatter.IContentFormatter;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.jface.text.information.IInformationPresenter;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class SimpleTextMarkerSourceViewerConfiguration extends TextMarkerSourceViewerConfiguration {
+
+  private boolean fConfigureFormatter;
+
+  public SimpleTextMarkerSourceViewerConfiguration(IColorManager colorManager,
+          IPreferenceStore preferenceStore, ITextEditor editor, String partitioning,
+          boolean configureFormatter) {
+    super(colorManager, preferenceStore, editor, partitioning);
+    fConfigureFormatter = configureFormatter;
+  }
+
+  @Override
+  public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
+    return null;
+  }
+
+  @Override
+  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+    return null;
+  }
+
+  @Override
+  public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
+    return null;
+  }
+
+  @Override
+  public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) {
+    return null;
+  }
+
+  @Override
+  public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) {
+    return null;
+  }
+
+  @Override
+  public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+    return null;
+  }
+
+  @Override
+  public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
+    if (fConfigureFormatter)
+      return super.getContentFormatter(sourceViewer);
+    else
+      return null;
+  }
+
+  @Override
+  public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
+    return null;
+  }
+
+  @Override
+  public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
+    return null;
+  }
+
+  public IInformationPresenter getOutlinePresenter(ISourceViewer sourceViewer, boolean doCodeResolve) {
+    return null;
+  }
+
+  public IInformationPresenter getHierarchyPresenter(ISourceViewer sourceViewer,
+          boolean doCodeResolve) {
+    return null;
+  }
+
+  @Override
+  public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
+    return null;
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/SimpleTextMarkerSourceViewerConfiguration.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/SimpleTextMarkerSourceViewerConfiguration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerAutoEditStrategy.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerAutoEditStrategy.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerAutoEditStrategy.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerAutoEditStrategy.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,901 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import java.util.regex.Pattern;
+
+import org.apache.uima.tm.dltk.ui.text.TextMarkerPartitions;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.ui.CodeFormatterConstants;
+import org.eclipse.dltk.ui.PreferenceConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.DocumentRewriteSession;
+import org.eclipse.jface.text.DocumentRewriteSessionType;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.rules.FastPartitioner;
+
+
+public class TextMarkerAutoEditStrategy extends DefaultIndentLineAutoEditStrategy {
+  // TODO
+  IPreferenceStore fStore;
+
+  String fPartitioning;
+
+  final int maxCharsAway = 100;
+
+  public TextMarkerAutoEditStrategy(IPreferenceStore store, String part) {
+    fStore = store;
+    fPartitioning = part;
+  }
+
+  /*
+   * possible prefereces:
+   * 
+   * general indent on/off smart tab key behaviour autoclose "strings", 'strings' autoclose
+   * {brackets}, [], () smart paste
+   */
+
+  private boolean isSmartTab() {
+    return fStore.getBoolean(PreferenceConstants.EDITOR_SMART_TAB);
+  }
+
+  private boolean isSmartMode() {
+    return fStore.getBoolean(PreferenceConstants.EDITOR_SMART_INDENT);
+  }
+
+  private boolean closeBrackets() {
+    return fStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_BRACKETS);
+  }
+
+  private boolean isSmartPaste() {
+    return fStore.getBoolean(PreferenceConstants.EDITOR_SMART_PASTE);
+  }
+
+  private boolean closeStrings() {
+    return fStore.getBoolean(PreferenceConstants.EDITOR_CLOSE_STRINGS);
+  }
+
+  private int getIndentSize() {
+    return fStore.getInt(CodeFormatterConstants.FORMATTER_INDENTATION_SIZE);
+  }
+
+  private String getTabStyle() {
+    return fStore.getString(CodeFormatterConstants.FORMATTER_TAB_CHAR);
+  }
+
+  private String getIndent() {
+    if (getTabStyle().equals(CodeFormatterConstants.SPACE)) {
+      int size = getIndentSize();
+      String res = "";
+      for (int i = 0; i < size; i++)
+        res += " ";
+      return res;
+    } else
+      return "\t";
+  }
+
+  private boolean isLineDelimiter(IDocument document, String text) {
+    String[] delimiters = document.getLegalLineDelimiters();
+    if (delimiters != null)
+      return TextUtilities.equals(delimiters, text) > -1;
+    return false;
+  }
+
+  /**
+   * Returns the leading whitespaces and tabs.
+   * 
+   * @param document
+   *          - the document being parsed
+   * @param line
+   *          - the line being searched
+   * @return the leading whitespace
+   * @throws BadLocationException
+   *           in case <code>line</code> is invalid in the document
+   */
+  private String getLineIndent(IDocument document, int line) throws BadLocationException {
+    if (line > -1) {
+      int start = document.getLineOffset(line);
+      int end = start + document.getLineLength(line); // was - 1
+      int whiteend = findEndOfWhiteSpace(document, start, end);
+      return document.get(start, whiteend - start);
+    }
+    return ""; //$NON-NLS-1$
+  }
+
+  /**
+   * Returns the leading whitespaces and tabs.
+   * 
+   * @param line
+   *          - the line being searched
+   * @return the leading whitespace
+   */
+  public String getLineIndent(String line) {
+    int end = line.length();
+    int whiteend = end;
+    int offset = 0;
+    while (offset < end) {
+      char c = line.charAt(offset);
+      if (c != ' ' && c != '\t') {
+        whiteend = offset;
+        break;
+      }
+      offset++;
+    }
+    return line.substring(0, whiteend);
+  }
+
+  /**
+   * Find line with number <=line, that is not empty and is not a comment line starting with #
+   * 
+   * @param d
+   *          the document to search in
+   * @param line
+   *          number of starting line
+   * @return number of code line or -1 if no such line found
+   * @throws BadLocationException
+   */
+  private int getLastNonEmptyLine(IDocument d, int line) throws BadLocationException {
+    int res = line;
+
+    while (res > -1) {
+      String str = getDocumentLine(d, res).trim();
+      if ((!str.startsWith("#")) && str.length() > 0)
+        return res;
+      res--;
+    }
+
+    return res;
+  }
+
+  /**
+   * Fetched line from document
+   * 
+   * @param d
+   *          the document
+   * @param line
+   *          number of req. line
+   * @return string with line
+   * @throws BadLocationException
+   *           if <b>line</b> is not correct line number
+   */
+  public String getDocumentLine(IDocument d, int line) throws BadLocationException {
+    int start = d.getLineOffset(line);
+    int length = d.getLineLength(line);
+    return d.get(start, length);
+  }
+
+  /**
+   * Get partition type covering offset
+   * 
+   * @param d
+   * @param offset
+   * @return
+   * @throws BadLocationException
+   */
+  private String getRegionType(IDocument d, int offset) throws BadLocationException {
+    int p = ((offset == d.getLength()) ? offset - 1 : offset);
+    ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, p, true);
+    return region.getType();
+  }
+
+  /**
+   * Searchs an pair from offset, forward of backwards. Can skip strings and comments (uses
+   * textmarker partitioning).
+   * 
+   * @param d
+   * @param offset
+   * @param forward
+   * @param opening
+   * @param closing
+   * @param skipCommentLines
+   * @param skipStrings
+   * @return offset of pair, or -1 if not found
+   * @throws BadLocationException
+   */
+  private int searchPair(IDocument d, int offset, boolean forward, char opening, char closing,
+          boolean skipCommentLines, boolean skipStrings) throws BadLocationException {
+    int deep = 0;
+    int i = offset;
+    if (forward) {
+      while (i < d.getLength()) {
+        ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, i, true);
+        if (region.getType() == TextMarkerPartitions.TM_COMMENT && skipCommentLines) {
+          i = region.getOffset() + region.getLength();
+          continue;
+        }
+        if (region.getType() == TextMarkerPartitions.TM_STRING && skipStrings) {
+          i = region.getOffset() + region.getLength();
+          continue;
+        }
+        char c = d.getChar(i);
+        if (c == opening)
+          deep++;
+        if (c == closing) {
+          if (deep == 0)
+            return i;
+          deep--;
+        }
+        i++;
+        if (i - offset > maxCharsAway)
+          return -1;
+      }
+    } else {
+      while (i >= 0) {
+        ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, i, true);
+        if (region.getType() == TextMarkerPartitions.TM_COMMENT && skipCommentLines) {
+          i = region.getOffset() - 1;
+          continue;
+        }
+        if (region.getType() == TextMarkerPartitions.TM_STRING && skipStrings) {
+          i = region.getOffset() - 1;
+          continue;
+        }
+        char c = d.getChar(i);
+        if (c == closing)
+          deep++;
+        if (c == opening) {
+          if (deep == 0)
+            return i;
+          deep--;
+        }
+        i--;
+        if (offset - i > maxCharsAway)
+          return -1;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Finds line < <b>line</b>, such the indent of it is less than of <b>line</b>
+   * 
+   * @param d
+   *          the document to search in
+   * @param line
+   *          appropriate line number
+   * @return if found, number < <b>line</b>, else <b>line</b>
+   */
+  private int findIndentStart(IDocument d, int line) throws BadLocationException {
+    String curIndent = getLineIndent(d, line);
+    int curIndentLength = getPhysicalLength(curIndent);
+    int cur = line - 1;
+    while (cur >= 0) {
+      String curLine = getDocumentLine(d, cur);
+      String ind = getLineIndent(d, cur);
+      if ((!curLine.trim().startsWith("#")) && getPhysicalLength(ind) < curIndentLength)
+        return cur;
+      cur--;
+    }
+    return line;
+  }
+
+  /**
+   * Calculates real length of string. So any char except \t has length 1, \t has length 8.
+   * 
+   * @param str
+   *          string to process
+   * @return length
+   */
+  public int getPhysicalLength(String str) {
+    int res = 0;
+    for (int i = 0; i < str.length(); i++) {
+      if (str.charAt(i) == '\t')
+        res += 8; // TODO
+      else
+        res++;
+    }
+    return res;
+  }
+
+  /**
+   * Return pair to brace. Ex. '(' for ')', e.t.c.
+   * 
+   * @param b
+   *          input brace
+   * @return peer brace
+   */
+  private char getBracePair(char b) {
+    switch (b) {
+      case '(':
+        return ')';
+      case ')':
+        return '(';
+      case '[':
+        return ']';
+      case ']':
+        return '[';
+      case '{':
+        return '}';
+      case '}':
+        return '{';
+      case '\"':
+        return '\"';
+      case '\'':
+        return '\'';
+    }
+    return b;
+  }
+
+  /**
+   * Installs a partitioner with <code>document</code>.
+   * 
+   * @param document
+   *          the document
+   */
+  private static void installStuff(Document document) {
+    String[] types = new String[] { TextMarkerPartitions.TM_STRING,
+        TextMarkerPartitions.TM_COMMENT, IDocument.DEFAULT_CONTENT_TYPE };
+    FastPartitioner partitioner = new FastPartitioner(new TextMarkerPartitionScanner(), types);
+    partitioner.connect(document);
+    document.setDocumentPartitioner(TextMarkerPartitions.TM_PARTITIONING, partitioner);
+  }
+
+  /**
+   * Removes partitioner with <code>document</code>.
+   * 
+   * @param document
+   *          the document
+   */
+  private static void removeStuff(Document document) {
+    document.setDocumentPartitioner(TextMarkerPartitions.TM_PARTITIONING, null);
+  }
+
+  /**
+   * STRATEGIES
+   */
+
+  /**
+   * Main indenting algorithm. Needs correct partitioning to work.
+   * 
+   * @param d
+   *          the processed document
+   * @param line
+   *          line, indenting of which we wanna know
+   * @param newLine
+   *          if <b>line</b> is new line, so we have pressed enter-key, and need indentation for new
+   *          line
+   * @param offset
+   *          position, where we have jumped to new line
+   * @return correct indent for line, or null if we should use "default" indent. So calling side
+   *         should determine, change indent or not, or may be use indent of previous line.
+   * @throws BadLocationException
+   */
+  private String calcLineIndent(IDocument d, int line, boolean newLine, int offset)
+          throws BadLocationException {
+
+    boolean isDocumentEnd = (offset == d.getLength());
+
+    // STRINGS
+    if (newLine) {
+      // if we wrap string
+      if (getRegionType(d, offset) == TextMarkerPartitions.TM_STRING) {
+        int realLine = d.getLineOfOffset(offset);
+        String curIndent = getLineIndent(d, realLine);
+        // if we just closed string
+        if (d.getChar(offset - 1) != '"') {
+          // if we are fully in string
+          if (getRegionType(d, d.getLineOffset(realLine)) == TextMarkerPartitions.TM_STRING) {
+            return curIndent;
+          }
+          // if we first time wrap string
+          return curIndent + getIndent();
+        }
+      }
+    } else {
+      // don't correct strings
+      if (getRegionType(d, d.getLineOffset(line)) == TextMarkerPartitions.TM_STRING) {
+        return getLineIndent(d, line); // notice, that we don't use
+        // null
+      }
+    }
+
+    // LINE JOINING
+    if (newLine) {
+      int realLine = d.getLineOfOffset(offset);
+      if (line > 0) {
+        String previousLine = "";
+        if (realLine == line - 1) {
+          int start = d.getLineOffset(realLine);
+          previousLine = d.get(start, offset - start);
+        } else
+          previousLine = getDocumentLine(d, line - 1);
+        if (previousLine.trim().endsWith("\\")) {
+          String prePreviousLine = getDocumentLine(d, line - 2);
+          if (prePreviousLine.trim().endsWith("\\"))
+            return getLineIndent(d, line - 1);
+          return getLineIndent(d, line - 1) + getIndent() + getIndent();
+        }
+        if (line > 1) {
+          String prePreviousLine = getDocumentLine(d, line - 2);
+          if (prePreviousLine.trim().endsWith("\\")) {
+            // find start
+            int t = line - 2;
+            while (t > 0 && getDocumentLine(d, t - 1).trim().endsWith("\\")) {
+              t--;
+            }
+            return getLineIndent(d, t);
+          }
+        }
+      }
+    } else {
+      /*
+       * If this line is explicitly joined: If the previous line was also joined, line it up with
+       * that one, otherwise add two 'shiftwidth'
+       */
+      if (line > 0) {
+        String previousLine = getDocumentLine(d, line - 1);
+        if (previousLine.trim().endsWith("\\")) {
+          if (line > 1) {
+            String prePreviousLine = getDocumentLine(d, line - 2);
+            if (prePreviousLine.trim().endsWith("\\"))
+              return getLineIndent(d, line - 1);
+          }
+          return getLineIndent(d, line - 1) + getIndent() + getIndent();
+        }
+      }
+    }
+
+    // Search backwards for the previous non-empty line.
+    int lastNonEmptyLine = getLastNonEmptyLine(d, line - 1);
+
+    if (lastNonEmptyLine < 0) {
+      // This is the first non-empty line, use zero indent.
+      return "";
+    }
+
+    // first check, if we not inside string, if yes, jump to start
+    ITypedRegion region = TextUtilities.getPartition(d, fPartitioning, d
+            .getLineOffset(lastNonEmptyLine), true);
+    if (region.getType() == TextMarkerPartitions.TM_STRING) {
+      lastNonEmptyLine = d.getLineOfOffset(region.getOffset());
+    }
+
+    // If the previous line is inside parenthesis, use the indent of the
+    // starting line.
+    int plnumstart;
+    String previousLineIndent = "";
+    int pairOffset = searchPair(d, d.getLineOffset(lastNonEmptyLine), false, '(', ')', true, true);
+
+    if (pairOffset >= 0) {
+      plnumstart = d.getLineOfOffset(pairOffset);
+      previousLineIndent = getLineIndent(d, plnumstart);
+    } else {
+      plnumstart = lastNonEmptyLine;
+      previousLineIndent = getLineIndent(d, lastNonEmptyLine);
+    }
+
+    /*
+     * When inside parenthesis: If at the first line below the parenthesis add two 'shiftwidth',
+     * otherwise same as previous line. i = (a + b + c)
+     */
+    int p = searchPair(d, offset - 1, false, '(', ')', true, true);
+    if (p >= 0) {
+      if (d.getLineOfOffset(p) == lastNonEmptyLine) {
+        // When the start is inside parenthesis, only indent one
+        // 'shiftwidth'.
+        int pp = searchPair(d, p, false, '(', ')', true, true);
+        if (pp >= 0)
+          return getLineIndent(d, lastNonEmptyLine) + getIndent();
+        return getLineIndent(d, lastNonEmptyLine) + getIndent() + getIndent();
+      }
+      if (d.getLineOfOffset(p) == plnumstart) {
+        return getLineIndent(d, lastNonEmptyLine);
+      }
+      if (d.getLineOfOffset(p) == line && !newLine)
+        return null;
+      return previousLineIndent;
+    }
+
+    // Get the line and remove a trailing comment.
+
+    String pline = "";
+    if (lastNonEmptyLine == line - 1 && newLine) {
+      pline = d.get(d.getLineOffset(line - 1), offset - d.getLineOffset(line - 1));
+    } else {
+      pline = getDocumentLine(d, lastNonEmptyLine);
+    }
+    int plineLen = pline.length();
+    int i;
+    for (i = 0; i < plineLen; i++) {
+      if (pline.charAt(i) == '#') {
+        pline = pline.substring(0, i);
+        break;
+      }
+    }
+
+    String plineTrimmed = pline.trim();
+
+    try {// If the current line begins with a keyword that lines up with
+      // "try"
+      String curLine = "";
+      if (lastNonEmptyLine == line - 1 && newLine) {
+        curLine = d.get(offset, d.getLineLength(line - 1) + d.getLineOffset(line - 1) - offset);
+      } else {
+        curLine = getDocumentLine(d, line).trim();
+      }
+
+      if (curLine.startsWith("except") || curLine.startsWith("finally")) {
+        int lnum = line - 1;
+
+        while (lnum >= 0) {
+          String temp = getDocumentLine(d, lnum).trim();
+          if (temp.startsWith("try") || temp.startsWith("except")) {
+            String ind = getLineIndent(d, lnum);
+            return ind;
+          }
+          lnum--;
+        }
+        // no mathing "try"
+        // System.out.println ("No matching 'try'!");
+        return null;
+      }
+
+      // If the current line begins with a header keyword, dedent
+      if (curLine.startsWith("elif") || curLine.startsWith("else")) {
+
+        // Unless the previous line was a one-liner
+        String temp = getDocumentLine(d, lastNonEmptyLine).trim();
+        if (temp.startsWith("for") || temp.startsWith("if") || temp.startsWith("try")
+                || temp.startsWith("while")) {
+          return previousLineIndent;
+        }
+        int sline = findIndentStart(d, lastNonEmptyLine);
+        String reqIndent = getLineIndent(d, sline);
+        return reqIndent;
+      }
+
+    } catch (BadLocationException e) {
+      // do nothing, we just don't have current line
+    }
+
+    // If the previous line was a stop-execution statement...
+    String regex = "^\\s*(break|continue|raise|pass|return)(\\s+.*$|$)";
+    if (Pattern.matches(regex, plineTrimmed)) {
+      // find indent
+      int sline = findIndentStart(d, lastNonEmptyLine);
+      String reqIndent = getLineIndent(d, sline);
+      if (newLine || isDocumentEnd
+              || (getPhysicalLength(getLineIndent(d, line)) > getPhysicalLength(reqIndent))) {
+        return reqIndent;
+      }
+      // trust the user
+      return null;
+    }
+
+    // If the previous line ended with a colon, indent this line
+    if (plineTrimmed.endsWith(":"))
+      return previousLineIndent + getIndent();
+
+    if (pairOffset >= 0 && newLine) {
+      return previousLineIndent;
+    }
+
+    // after-string
+    int prevLine = getLastNonEmptyLine(d, line - 1);
+    if (getRegionType(d, d.getLineOffset(prevLine)) == TextMarkerPartitions.TM_STRING)
+      return previousLineIndent;
+
+    return null;
+  }
+
+  /**
+   * If we have pressed ":" for example, than we need to reindent line. This function changes
+   * document and sets correct indent for current line.
+   * 
+   * @param d
+   * @param c
+   */
+  private void reindent(IDocument d, DocumentCommand c) {
+    try {
+      if (getRegionType(d, c.offset) != IDocument.DEFAULT_CONTENT_TYPE)
+        return;
+      int line = d.getLineOfOffset(c.offset);
+      String newIndent = calcLineIndent(d, line, false, c.offset);
+      if (newIndent == null)
+        return;
+      String curIndent = getLineIndent(d, line);
+      if (getPhysicalLength(curIndent) < getPhysicalLength(newIndent))
+        return;
+      d.replace(d.getLineOffset(line), curIndent.length(), newIndent);
+      c.offset += (newIndent.length() - curIndent.length());
+    } catch (BadLocationException e) {
+    }
+  }
+
+  /**
+   * Processes command in work with brackets, strings, etc
+   * 
+   * @param d
+   * @param c
+   */
+  private void autoClose(IDocument d, DocumentCommand c) {
+    if (c.offset == -1)
+      return;
+    try {
+      if (d.getChar(c.offset - 1) == '\\')
+        return;
+    } catch (BadLocationException e1) {
+    }
+    if ('\"' == c.text.charAt(0) && !closeStrings())
+      return;
+    if ('\'' == c.text.charAt(0) && !closeStrings())
+      return;
+    if (!closeBrackets()
+            && ('[' == c.text.charAt(0) || '(' == c.text.charAt(0) || '{' == c.text.charAt(0)))
+      return;
+    try {
+
+      switch (c.text.charAt(0)) {
+        case '\"':
+        case '\'':
+          // if we close existing quote, do nothing
+          if ('\"' == c.text.charAt(0) && c.offset > 0 && "\"".equals(d.get(c.offset - 1, 1)))
+            return;
+
+          if ('\'' == c.text.charAt(0) && c.offset > 0 && "\'".equals(d.get(c.offset - 1, 1)))
+            return;
+
+          if (c.offset != d.getLength() && c.text.charAt(0) == d.get(c.offset, 1).charAt(0))
+            c.text = "";
+          else {
+            c.text += c.text;
+            c.length = 0;
+          }
+
+          c.shiftsCaret = false;
+          c.caretOffset = c.offset + 1;
+          break;
+        case '(':
+        case '{':
+        case '[':
+          // check partition
+          if (getRegionType(d, c.offset) != IDocument.DEFAULT_CONTENT_TYPE)
+            return;
+          if (c.offset != d.getLength() && c.text.charAt(0) == d.get(c.offset, 1).charAt(0))
+            return;
+
+          try { // in class closing
+            String regex = "^\\s*class\\s+.*";
+            String regex2 = ".*\\(.*\\).*";
+            int start = d.getLineOffset(d.getLineOfOffset(c.offset));
+            String curLine = d.get(start, c.offset - start);
+            if (Pattern.matches(regex, curLine) && !Pattern.matches(regex2, curLine)) {
+              c.text = "():";
+              c.shiftsCaret = false;
+              c.caretOffset = c.offset + 1;
+              return;
+            }
+          } catch (BadLocationException e) {
+          }
+
+          // add closing peer
+          c.text = c.text + getBracePair(c.text.charAt(0));
+          c.length = 0;
+
+          c.shiftsCaret = false;
+          c.caretOffset = c.offset + 1;
+          break;
+        case '}':
+        case ']':
+        case ')':
+          // check partition
+          if (getRegionType(d, c.offset) != IDocument.DEFAULT_CONTENT_TYPE)
+            return;
+          if (!closeBrackets())
+            return;
+          // if we already have bracket we should jump over it
+          if (c.offset != d.getLength() && c.text.charAt(0) == d.get(c.offset, 1).charAt(0)) {
+            c.text = "";
+            c.shiftsCaret = false;
+            c.caretOffset = c.offset + 1;
+            return;
+          }
+          break;
+      }
+    } catch (BadLocationException e) {
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * When we have pressed \t, sometimes we wanna not to tabulate, and jump to correct line start
+   * position.
+   * 
+   * @param d
+   * @param c
+   * @return
+   */
+  private boolean smartIndentJump(IDocument d, DocumentCommand c) {
+    if (c.offset == -1 || d.getLength() == 0)
+      return false;
+    try {
+      // int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
+      int line = d.getLineOfOffset(c.offset);
+      int start = d.getLineOffset(line);
+      // calculate indentation of this line
+      String resultIndent = calcLineIndent(d, line, false, start);
+      String currentIndent = getLineIndent(d, line);
+      if (resultIndent == null) { // we should save indentation
+        String curLine = getDocumentLine(d, line);
+        if (curLine.trim().length() > 0) // if indentation is "real",
+          // use it
+          resultIndent = currentIndent;
+        else {
+          // get current block level
+          int pl = getLastNonEmptyLine(d, line - 1); // find last
+          // code line
+          if (pl >= 0) {
+            String plStr = getDocumentLine(d, pl).trim();
+            // simple indent-guess strategy
+            String regex = "^\\s*(break|continue|raise|pass|return)(\\s+.*$|$)";
+            if (plStr.endsWith(":"))
+              resultIndent = getLineIndent(plStr) + getIndent();
+            else if (Pattern.matches(regex, plStr)) {
+              // find indent
+              int sline = findIndentStart(d, pl);
+              resultIndent = getLineIndent(d, sline);
+            } else
+              resultIndent = getLineIndent(d, pl);
+          } else
+            return false; // no indent is applicable, do nothing
+        }
+      }
+
+      if (c.offset >= start + resultIndent.length())
+        return false; // we already in the place
+
+      if (!currentIndent.startsWith(resultIndent)) { // create indent
+        c.offset = start;
+        c.length = currentIndent.length();
+        c.shiftsCaret = false;
+        c.text = resultIndent;
+        c.caretOffset = d.getLineOffset(line) + resultIndent.length();
+        return true;
+      }
+
+      c.length = 0;
+      c.shiftsCaret = false;
+      c.text = "";
+      c.caretOffset = d.getLineOffset(line) + resultIndent.length();
+      return true;
+    } catch (BadLocationException e) {
+      e.printStackTrace();
+    }
+    return false;
+  }
+
+  /**
+   * Reindents c.text when pasting.
+   * 
+   * @param d
+   * @param c
+   */
+  private void smartPaste(IDocument d, DocumentCommand c) {
+    /*
+     * We are creating temp document, inserting text as is, and then sequentially calling
+     * calcLineIndent for each new line.
+     */
+    try {
+      String content = d.get(0, c.offset) + c.text;
+      Document temp = new Document(content);
+      DocumentRewriteSession session = temp
+              .startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL);
+      installStuff(temp);
+      int offset = c.offset;
+      int line = temp.getLineOfOffset(offset);
+      String lastIndent = getLineIndent(temp, line);
+      int firstLineOffset = temp.getLineOffset(line);
+      String commonIndent = temp.get(firstLineOffset, c.offset - firstLineOffset);
+      line++;
+      try {
+        while (getDocumentLine(temp, line).trim().length() == 0)
+          line++;
+        offset = temp.getLineOffset(line);
+      } catch (BadLocationException e) {
+        // ok, we are inserting only one string...
+        offset = temp.getLength();
+      }
+      while (offset < temp.getLength()) {
+        // calculate indentation of this line
+        String resultIndent = calcLineIndent(temp, line, false, temp.getLineOffset(line));
+        // change current line offset
+        String currentIndent = getLineIndent(temp, line);
+        // String dbg = temp.get ();
+        if (resultIndent == null) {
+          resultIndent = commonIndent + currentIndent;
+          if (getPhysicalLength(resultIndent) > getPhysicalLength(lastIndent))
+            resultIndent = lastIndent;
+        }
+        temp.replace(offset, currentIndent.length(), resultIndent);
+        String currentLine = getDocumentLine(temp, line);
+        if (currentLine.trim().length() > 0 && (!currentLine.trim().startsWith("#")))
+          lastIndent = resultIndent;
+
+        // dbg = temp.get ();
+        if (temp.getLineOffset(line) + temp.getLineLength(line) == temp.getLength())
+          break;
+        line++;
+        offset = temp.getLineOffset(line);
+      }
+      temp.stopRewriteSession(session);
+      removeStuff(temp);
+      c.text = temp.get(c.offset, temp.getLength() - c.offset);
+    } catch (BadLocationException e) {
+      e.printStackTrace();
+    }
+
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument
+   * , org.eclipse.jface.text.DocumentCommand)
+   */
+  @Override
+  public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
+    if (c.doit == false)
+      return;
+    if (c.length == 0 && c.text != null && isLineDelimiter(d, c.text)) {
+      if (!isSmartMode()) {
+        super.customizeDocumentCommand(d, c);
+        return;
+      }
+      try {
+        String indent = calcLineIndent(d, d.getLineOfOffset(c.offset) + 1, true, c.offset);
+        if (indent == null)
+          super.customizeDocumentCommand(d, c);
+        else {
+          if (DLTKCore.DEBUG) {
+            System.err.println("Bug:PTN-9");
+          }
+          // if (c.offset - 1 >= 0 &&
+          // d.getChar(c.offset - 1) != '"' &&
+          // getRegionType(d, c.offset - 1) ==
+          // TextMarkerPartitions.TM_STRING)
+          // c.text = "\\" + c.text + indent;
+          // else {
+          c.text = c.text + indent;
+          // }
+        }
+      } catch (BadLocationException e) {
+        super.customizeDocumentCommand(d, c);
+      }
+      return;
+    } else {
+      if (c.length <= 1 && c.text.length() == 1) {
+        switch (c.text.charAt(0)) {
+          case ':':
+            reindent(d, c);
+            break;
+          case '\"':
+          case '\'':
+          case '(':
+          case '{':
+          case '[':
+          case '}':
+          case ']':
+          case ')':
+            autoClose(d, c);
+            break;
+          case '\t':
+            boolean jumped = false;
+            if (isSmartTab()) {
+              jumped = smartIndentJump(d, c);
+            }
+            if (!jumped) {
+              c.text = getIndent();
+            }
+            break;
+        }
+      } else if (c.text.length() >= 1 && isSmartPaste())
+        smartPaste(d, c); // no smart backspace for paste
+    }
+  }
+
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerAutoEditStrategy.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerAutoEditStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCodeScanner.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCodeScanner.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCodeScanner.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCodeScanner.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,89 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.tm.dltk.core.ITextMarkerKeywords;
+import org.apache.uima.tm.dltk.core.TextMarkerKeywordsManager;
+import org.eclipse.dltk.ui.text.AbstractScriptScanner;
+import org.eclipse.dltk.ui.text.IColorManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+
+public class TextMarkerCodeScanner extends AbstractScriptScanner {
+
+  private static String fgTokenProperties[] = new String[] {
+      TextMarkerColorConstants.TM_SINGLE_LINE_COMMENT, TextMarkerColorConstants.TM_DEFAULT,
+      TextMarkerColorConstants.TM_KEYWORD, TextMarkerColorConstants.TM_KEYWORD_RETURN,
+      TextMarkerColorConstants.TM_NUMBER, TextMarkerColorConstants.TM_FUNCTION,
+      TextMarkerColorConstants.TM_CONDITION, TextMarkerColorConstants.TM_ACTION,
+      TextMarkerColorConstants.TM_RULE, TextMarkerColorConstants.TM_DECLARATION,
+      TextMarkerColorConstants.TM_BASICSYMBOL, TextMarkerColorConstants.TM_THEN };
+
+  public TextMarkerCodeScanner(IColorManager manager, IPreferenceStore store) {
+    super(manager, store);
+    initialize();
+  }
+
+  @Override
+  protected String[] getTokenProperties() {
+    return fgTokenProperties;
+  }
+
+  @Override
+  protected List createRules() {
+    List<IRule> rules = new ArrayList<IRule>();
+    IToken keyword = getToken(TextMarkerColorConstants.TM_KEYWORD);
+    IToken rule = getToken(TextMarkerColorConstants.TM_RULE);
+    IToken comment = getToken(TextMarkerColorConstants.TM_SINGLE_LINE_COMMENT);
+    IToken other = getToken(TextMarkerColorConstants.TM_DEFAULT);
+    IToken declaration = getToken(TextMarkerColorConstants.TM_DECLARATION);
+    IToken basicSymbol = getToken(TextMarkerColorConstants.TM_BASICSYMBOL);
+    IToken function = getToken(TextMarkerColorConstants.TM_FUNCTION);
+    IToken condition = getToken(TextMarkerColorConstants.TM_CONDITION);
+    IToken action = getToken(TextMarkerColorConstants.TM_ACTION);
+    IToken then = getToken(TextMarkerColorConstants.TM_THEN);
+    IToken number = getToken(TextMarkerColorConstants.TM_NUMBER);
+    IToken string = getToken(TextMarkerColorConstants.TM_STRING);
+
+    // rules.add(new MultiLineRule("/*", "*/", comment, '\\', true));
+    // rules.add(new EndOfLineRule("//", comment));
+    rules.add(new WhitespaceRule(new TextMarkerWhitespaceDetector()));
+    TextMarkerWordRule wordRule = new TextMarkerWordRule(new TextMarkerWordDetector(), other, rule);
+
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.CONDITION)) {
+      wordRule.addWord(each, condition);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.DECLARATION)) {
+      wordRule.addWord(each, declaration);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.ACTION)) {
+      wordRule.addWord(each, action);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.BASIC)) {
+      wordRule.addWord(each, basicSymbol);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.BOOLEANFUNCTION)) {
+      wordRule.addWord(each, function);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.NUMBERFUNCTION)) {
+      wordRule.addWord(each, function);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.STRINGFUNCTION)) {
+      wordRule.addWord(each, function);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.TYPEFUNCTION)) {
+      wordRule.addWord(each, function);
+    }
+    for (String each : TextMarkerKeywordsManager.getKeywords(ITextMarkerKeywords.THEN)) {
+      wordRule.addWord(each, then);
+    }
+    rules.add(wordRule);
+
+    setDefaultReturnToken(other);
+    return rules;
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCodeScanner.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCodeScanner.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerColorConstants.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerColorConstants.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerColorConstants.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerColorConstants.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,41 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import org.eclipse.dltk.ui.text.DLTKColorConstants;
+
+public final class TextMarkerColorConstants {
+
+  private TextMarkerColorConstants() {
+  }
+
+  public static final String TM_STRING = DLTKColorConstants.DLTK_STRING;
+
+  public static final String TM_SINGLE_LINE_COMMENT = DLTKColorConstants.DLTK_SINGLE_LINE_COMMENT;
+
+  public static final String TM_DOC_COMMENT = DLTKColorConstants.DLTK_DOC;
+
+  public static final String TM_NUMBER = DLTKColorConstants.DLTK_NUMBER;
+
+  public static final String TM_KEYWORD = DLTKColorConstants.DLTK_KEYWORD;
+
+  public static final String TM_KEYWORD_RETURN = DLTKColorConstants.DLTK_KEYWORD_RETURN;
+
+  public static final String TM_DEFAULT = DLTKColorConstants.DLTK_DEFAULT;
+
+  public static final String TM_CONDITION = "tm_condition"; //$NON-NLS-1$
+
+  public static final String TM_ACTION = "tm_action"; //$NON-NLS-1$
+
+  public static final String TM_RULE = "tm_rule";
+
+  public static final String TM_THEN = "tm_then";
+
+  public static final String TM_DECLARATION = "tm_declaration";
+
+  public static final String TM_BASICSYMBOL = "tm_basicSymbol";
+
+  public static final String TM_FUNCTION = "tm_function";
+
+  public static final String TM_VARIABLE = "tm_variable"; //$NON-NLS-1$
+
+  public static final String TM_TODO_TAG = DLTKColorConstants.TASK_TAG; // DLTKColorConstants.TASK_TAG;
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerColorConstants.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerColorConstants.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionAssistant.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionAssistant.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionAssistant.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionAssistant.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,354 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.uima.tm.dltk.internal.ui.TextMarkerUI;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.dltk.ui.DLTKUIPlugin;
+import org.eclipse.dltk.ui.PreferenceConstants;
+import org.eclipse.dltk.ui.text.IColorManager;
+import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
+import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+public class TextMarkerCorrectionAssistant extends QuickAssistAssistant {
+
+  private ITextViewer fViewer;
+
+  private ITextEditor fEditor;
+
+  private Position fPosition;
+
+  private Annotation[] fCurrentAnnotations;
+
+  // private TextMarkerQuickAssistLightBulbUpdater fLightBulbUpdater;
+
+  /**
+   * Constructor for JavaCorrectionAssistant.
+   * 
+   * @param editor
+   *          the editor
+   */
+  public TextMarkerCorrectionAssistant(ITextEditor editor) {
+    super();
+    Assert.isNotNull(editor);
+    fEditor = editor;
+
+    TextMarkerCorrectionProcessor processor = new TextMarkerCorrectionProcessor(this);
+
+    setQuickAssistProcessor(processor);
+
+    setInformationControlCreator(getInformationControlCreator());
+
+    TextMarkerTextTools textTools = TextMarkerUI.getDefault().getTextTools();
+    IColorManager manager = textTools.getColorManager();
+
+    IPreferenceStore store = TextMarkerUI.getDefault().getPreferenceStore();
+
+    Color c = getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND, manager);
+    setProposalSelectorForeground(c);
+
+    c = getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND, manager);
+    setProposalSelectorBackground(c);
+  }
+
+  public IEditorPart getEditor() {
+    return fEditor;
+  }
+
+  private IInformationControlCreator getInformationControlCreator() {
+    return new IInformationControlCreator() {
+      public IInformationControl createInformationControl(Shell parent) {
+        return new DefaultInformationControl(parent, new HTMLTextPresenter());
+      }
+    };
+  }
+
+  private static Color getColor(IPreferenceStore store, String key, IColorManager manager) {
+    RGB rgb = PreferenceConverter.getColor(store, key);
+    return manager.getColor(rgb);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.jface.text.contentassist.IContentAssistant#install(org.eclipse
+   * .jface.text.ITextViewer)
+   */
+  @Override
+  public void install(ISourceViewer sourceViewer) {
+    super.install(sourceViewer);
+    fViewer = sourceViewer;
+
+    // fLightBulbUpdater = new
+    // TextMarkerQuickAssistLightBulbUpdater(fEditor,
+    // sourceViewer);
+    // fLightBulbUpdater.install();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.jface.text.contentassist.ContentAssistant#uninstall()
+   */
+  @Override
+  public void uninstall() {
+    // if (fLightBulbUpdater != null) {
+    // fLightBulbUpdater.uninstall();
+    // fLightBulbUpdater = null;
+    // }
+    super.uninstall();
+  }
+
+  /*
+   * @seeorg.eclipse.jface.text.quickassist.QuickAssistAssistant# showPossibleQuickAssists()
+   * 
+   * @since 3.2
+   */
+
+  /**
+   * Show completions at caret position. If current position does not contain quick fixes look for
+   * next quick fix on same line by moving from left to right and restarting at end of line if the
+   * beginning of the line is reached.
+   * 
+   * @see IQuickAssistAssistant#showPossibleQuickAssists()
+   */
+  @Override
+  public String showPossibleQuickAssists() {
+    fPosition = null;
+    fCurrentAnnotations = null;
+
+    if (fViewer == null || fViewer.getDocument() == null)
+      // Let superclass deal with this
+      return super.showPossibleQuickAssists();
+
+    ArrayList resultingAnnotations = new ArrayList(20);
+    try {
+      Point selectedRange = fViewer.getSelectedRange();
+      int currOffset = selectedRange.x;
+      int currLength = selectedRange.y;
+      boolean goToClosest = (currLength == 0);
+
+      int newOffset = collectQuickFixableAnnotations(fEditor, currOffset, goToClosest,
+              resultingAnnotations);
+      if (newOffset != currOffset) {
+        storePosition(currOffset, currLength);
+        fViewer.setSelectedRange(newOffset, 0);
+        fViewer.revealRange(newOffset, 0);
+      }
+    } catch (BadLocationException e) {
+      // JavaPlugin.log(e);
+    }
+    fCurrentAnnotations = (Annotation[]) resultingAnnotations
+            .toArray(new Annotation[resultingAnnotations.size()]);
+
+    return super.showPossibleQuickAssists();
+  }
+
+  private static IRegion getRegionOfInterest(ITextEditor editor, int invocationLocation)
+          throws BadLocationException {
+    IDocumentProvider documentProvider = editor.getDocumentProvider();
+    if (documentProvider == null) {
+      return null;
+    }
+    IDocument document = documentProvider.getDocument(editor.getEditorInput());
+    if (document == null) {
+      return null;
+    }
+    return document.getLineInformationOfOffset(invocationLocation);
+  }
+
+  public static int collectQuickFixableAnnotations(ITextEditor editor, int invocationLocation,
+          boolean goToClosest, ArrayList resultingAnnotations) throws BadLocationException {
+    IAnnotationModel model = DLTKUIPlugin.getDocumentProvider().getAnnotationModel(
+            editor.getEditorInput());
+    if (model == null) {
+      return invocationLocation;
+    }
+
+    ensureUpdatedAnnotations(editor);
+
+    Iterator iter = model.getAnnotationIterator();
+    if (goToClosest) {
+      IRegion lineInfo = getRegionOfInterest(editor, invocationLocation);
+      if (lineInfo == null) {
+        return invocationLocation;
+      }
+      int rangeStart = lineInfo.getOffset();
+      int rangeEnd = rangeStart + lineInfo.getLength();
+
+      ArrayList allAnnotations = new ArrayList();
+      ArrayList allPositions = new ArrayList();
+      int bestOffset = Integer.MAX_VALUE;
+      while (iter.hasNext()) {
+        Annotation annot = (Annotation) iter.next();
+        if (TextMarkerCorrectionProcessor.isQuickFixableType(annot)) {
+          Position pos = model.getPosition(annot);
+          if (pos != null && isInside(pos.offset, rangeStart, rangeEnd)) { // inside
+            // our
+            // range?
+            allAnnotations.add(annot);
+            allPositions.add(pos);
+            bestOffset = processAnnotation(annot, pos, invocationLocation, bestOffset);
+          }
+        }
+      }
+      if (bestOffset == Integer.MAX_VALUE) {
+        return invocationLocation;
+      }
+      for (int i = 0; i < allPositions.size(); i++) {
+        Position pos = (Position) allPositions.get(i);
+        if (isInside(bestOffset, pos.offset, pos.offset + pos.length)) {
+          resultingAnnotations.add(allAnnotations.get(i));
+        }
+      }
+      return bestOffset;
+    } else {
+      while (iter.hasNext()) {
+        Annotation annot = (Annotation) iter.next();
+        if (TextMarkerCorrectionProcessor.isQuickFixableType(annot)) {
+          Position pos = model.getPosition(annot);
+          if (pos != null && isInside(invocationLocation, pos.offset, pos.offset + pos.length)) {
+            resultingAnnotations.add(annot);
+          }
+        }
+      }
+      return invocationLocation;
+    }
+  }
+
+  private static void ensureUpdatedAnnotations(ITextEditor editor) {
+    // Object inputElement = editor.getEditorInput().getAdapter(
+    // IModelElement.class);
+
+  }
+
+  private static int processAnnotation(Annotation annot, Position pos, int invocationLocation,
+          int bestOffset) {
+    int posBegin = pos.offset;
+    int posEnd = posBegin + pos.length;
+    if (isInside(invocationLocation, posBegin, posEnd)) { // covers
+      // invocation
+      // location?
+      return invocationLocation;
+    } else if (bestOffset != invocationLocation) {
+      int newClosestPosition = computeBestOffset(posBegin, invocationLocation, bestOffset);
+      if (newClosestPosition != -1) {
+        if (newClosestPosition != bestOffset) { // new best
+          // if (JavaCorrectionProcessor.hasCorrections(annot)) { //
+          // only
+          // // jump
+          // // to
+          // // it
+          // // if
+          // // there
+          // // are
+          // // proposals
+          // return newClosestPosition;
+          // }
+        }
+      }
+    }
+    return bestOffset;
+  }
+
+  private static boolean isInside(int offset, int start, int end) {
+    return offset == start || offset == end || (offset > start && offset < end); // make sure to
+    // handle
+    // 0-length ranges
+  }
+
+  /**
+   * Computes and returns the invocation offset given a new position, the initial offset and the
+   * best invocation offset found so far.
+   * <p>
+   * The closest offset to the left of the initial offset is the best. If there is no offset on the
+   * left, the closest on the right is the best.
+   * </p>
+   * 
+   * @param newOffset
+   *          the offset to llok at
+   * @param invocationLocation
+   *          the invocation location
+   * @param bestOffset
+   *          the current best offset
+   * @return -1 is returned if the given offset is not closer or the new best offset
+   */
+  private static int computeBestOffset(int newOffset, int invocationLocation, int bestOffset) {
+    if (newOffset <= invocationLocation) {
+      if (bestOffset > invocationLocation) {
+        return newOffset; // closest was on the right, prefer on the
+        // left
+      } else if (bestOffset <= newOffset) {
+        return newOffset; // we are closer or equal
+      }
+      return -1; // further away
+    }
+
+    if (newOffset <= bestOffset)
+      return newOffset; // we are closer or equal
+
+    return -1; // further away
+  }
+
+  /*
+   * @seeorg.eclipse.jface.text.contentassist.ContentAssistant# possibleCompletionsClosed()
+   */
+  @Override
+  protected void possibleCompletionsClosed() {
+    super.possibleCompletionsClosed();
+    restorePosition();
+  }
+
+  private void storePosition(int currOffset, int currLength) {
+    fPosition = new Position(currOffset, currLength);
+  }
+
+  private void restorePosition() {
+    if (fPosition != null && !fPosition.isDeleted() && fViewer.getDocument() != null) {
+      fViewer.setSelectedRange(fPosition.offset, fPosition.length);
+      fViewer.revealRange(fPosition.offset, fPosition.length);
+    }
+    fPosition = null;
+  }
+
+  /**
+   * Returns true if the last invoked completion was called with an updated offset.
+   * 
+   * @return <code> true</code> if the last invoked completion was called with an updated offset.
+   */
+  public boolean isUpdatedOffset() {
+    return fPosition != null;
+  }
+
+  /**
+   * Returns the annotations at the current offset
+   * 
+   * @return the annotations at the offset
+   */
+  public Annotation[] getAnnotationsAtOffset() {
+    return fCurrentAnnotations;
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionAssistant.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionAssistant.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionProcessor.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionProcessor.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionProcessor.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionProcessor.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,179 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.uima.tm.dltk.core.TextMarkerNature;
+import org.apache.uima.tm.dltk.core.TextMarkerProblems;
+import org.apache.uima.tm.dltk.internal.core.packages.PackagesManager;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.dltk.core.CorrectionEngine;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.DLTKLanguageManager;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IScriptModelMarker;
+import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.internal.ui.editor.ScriptEditor;
+import org.eclipse.dltk.launching.IInterpreterInstall;
+import org.eclipse.dltk.launching.ScriptRuntime;
+import org.eclipse.dltk.ui.DLTKUIPlugin;
+import org.eclipse.dltk.ui.editor.IScriptAnnotation;
+import org.eclipse.dltk.ui.text.MarkerResolutionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext;
+import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
+
+
+public class TextMarkerCorrectionProcessor implements IQuickAssistProcessor {
+  TextMarkerCorrectionAssistant fAssistant;
+
+  public TextMarkerCorrectionProcessor(TextMarkerCorrectionAssistant tclCorrectionAssistant) {
+    this.fAssistant = tclCorrectionAssistant;
+  }
+
+  public boolean canAssist(IQuickAssistInvocationContext invocationContext) {
+    return true;
+  }
+
+  public boolean canFix(Annotation annotation) {
+    return hasCorrections(annotation);
+  }
+
+  public ICompletionProposal[] computeQuickAssistProposals(
+          IQuickAssistInvocationContext invocationContext) {
+    final Annotation[] annotations = fAssistant.getAnnotationsAtOffset();
+    final ScriptEditor editor = (ScriptEditor) this.fAssistant.getEditor();
+    final IAnnotationModel model = DLTKUIPlugin.getDocumentProvider().getAnnotationModel(
+            editor.getEditorInput());
+    final IModelElement element = editor.getInputModelElement();
+    final IScriptProject scriptProject = element.getScriptProject();
+    List proposals = null;
+    for (int i = 0; i < annotations.length; i++) {
+      final Annotation annotation = annotations[i];
+      ICompletionProposal proposal = null;
+      if (annotation instanceof MarkerAnnotation) {
+        MarkerAnnotation mAnnot = (MarkerAnnotation) annotation;
+        IMarker marker = mAnnot.getMarker();
+        if (isFixable(marker)) {
+          final String pkgName = CorrectionEngine.getProblemArguments(marker)[0];
+          proposal = new MarkerResolutionProposal(new TextMarkerRequirePackageMarkerResolution(
+                  pkgName, scriptProject), marker);
+        }
+      } else if (annotation instanceof IScriptAnnotation) {
+        if (isFixable((IScriptAnnotation) annotation)) {
+          // final String pkgName = ((IScriptAnnotation) annotation)
+          // .getArguments()[0];
+          // proposal = new AnnotationResolutionProposal(
+          // new TextMarkerRequirePackageMarkerResolution(pkgName,
+          // scriptProject), model, annotation);
+        }
+      }
+      if (proposal != null) {
+        if (proposals == null) {
+          proposals = new ArrayList();
+        }
+        proposals.add(proposal);
+      }
+    }
+    if (proposals != null) {
+      return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]);
+    }
+    return null;
+  }
+
+  public String getErrorMessage() {
+    return null;
+  }
+
+  public static boolean isQuickFixableType(Annotation annotation) {
+    return (annotation instanceof IScriptAnnotation || annotation instanceof SimpleMarkerAnnotation)
+            && !annotation.isMarkedDeleted();
+  }
+
+  public static boolean isFixable(IMarker marker) {
+    if (marker.getAttribute(IScriptModelMarker.ID, 0) == TextMarkerProblems.UNKNOWN_REQUIRED_PACKAGE) {
+      final String[] args = CorrectionEngine.getProblemArguments(marker);
+      if (args != null && args.length != 0 && args[0] != null) {
+        IResource resource = marker.getResource();
+        IProject project = resource.getProject();
+        IScriptProject scriptProject = DLTKCore.create(project);
+        if (isFixable(args[0], scriptProject)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public static boolean isFixable(IScriptAnnotation annotation) {
+    if (annotation.getId() == TextMarkerProblems.UNKNOWN_REQUIRED_PACKAGE) {
+      final String[] args = annotation.getArguments();
+      if (args != null && args.length != 0 && args[0] != null) {
+        final ISourceModule module = annotation.getSourceModule();
+        if (module != null) {
+          final IScriptProject project = module.getScriptProject();
+          if (project != null) {
+            if (isFixable(args[0], project)) {
+              return true;
+            }
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  public static boolean isFixable(String pkgName, IScriptProject scriptProject) {
+    IDLTKLanguageToolkit toolkit = null;
+    toolkit = DLTKLanguageManager.getLanguageToolkit(scriptProject);
+    if (toolkit != null && toolkit.getNatureId().equals(TextMarkerNature.NATURE_ID)) {
+      IInterpreterInstall install = null;
+      try {
+        install = ScriptRuntime.getInterpreterInstall(scriptProject);
+      } catch (CoreException e) {
+        if (DLTKCore.DEBUG) {
+          e.printStackTrace();
+        }
+      }
+      if (install != null) {
+        PackagesManager manager = PackagesManager.getInstance();
+        IPath[] paths = manager.getPathsForPackage(install, pkgName);
+        if (paths != null && paths.length > 0) {
+          return true;
+        }
+        Map dependencies = manager.getDependencies(pkgName, install);
+        for (Iterator iterator = dependencies.keySet().iterator(); iterator.hasNext();) {
+          String pkg = (String) iterator.next();
+          IPath[] paths2 = manager.getPathsForPackage(install, pkg);
+          if (paths2 != null && paths2.length > 0) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  public static boolean hasCorrections(Annotation annotation) {
+    if (annotation instanceof MarkerAnnotation) {
+      MarkerAnnotation mAnnot = (MarkerAnnotation) annotation;
+      IMarker marker = mAnnot.getMarker();
+      return isFixable(marker);
+    } else if (annotation instanceof IScriptAnnotation) {
+      return isFixable((IScriptAnnotation) annotation);
+    }
+    return false;
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionProcessor.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerCorrectionProcessor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerDecoratorDetector.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerDecoratorDetector.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerDecoratorDetector.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerDecoratorDetector.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,15 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+class TextMarkerDecoratorDetector implements IWordDetector {
+
+  public boolean isWordStart(char c) {
+    return c == '@';
+  }
+
+  public boolean isWordPart(char c) {
+    return c != '\n' && c != '\r' && c != '(';
+  }
+
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerDecoratorDetector.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerDecoratorDetector.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerOutlineInformationControl.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerOutlineInformationControl.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerOutlineInformationControl.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerOutlineInformationControl.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,20 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import org.apache.uima.tm.dltk.internal.ui.TextMarkerUI;
+import org.eclipse.dltk.ui.text.ScriptOutlineInformationControl;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class TextMarkerOutlineInformationControl extends ScriptOutlineInformationControl {
+
+  public TextMarkerOutlineInformationControl(Shell parent, int shellStyle, int treeStyle,
+          String commandId) {
+    super(parent, shellStyle, treeStyle, commandId);
+  }
+
+  @Override
+  protected IPreferenceStore getPreferenceStore() {
+    return TextMarkerUI.getDefault().getPreferenceStore();
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerOutlineInformationControl.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerOutlineInformationControl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPairMatcher.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPairMatcher.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPairMatcher.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPairMatcher.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,268 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.tm.dltk.core.TextMarkerNature;
+import org.eclipse.dltk.ast.ASTNode;
+import org.eclipse.dltk.ast.ASTVisitor;
+import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
+import org.eclipse.dltk.ast.expressions.StringLiteral;
+import org.eclipse.dltk.ast.parser.ISourceParser;
+import org.eclipse.dltk.ast.statements.Block;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.DLTKLanguageManager;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.SourceParserUtil;
+import org.eclipse.dltk.internal.ui.editor.ScriptEditor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension4;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
+
+
+/**
+ * Helper class for match pairs of characters.
+ */
+public final class TextMarkerPairMatcher implements ICharacterPairMatcher {
+
+  // private char[] fPairs;
+
+  private IDocument fDocument;
+
+  private int fOffset;
+
+  private int fStartPos;
+
+  private int fEndPos;
+
+  private int fAnchor;
+
+  private ScriptEditor editor;
+
+  private class PairBlock {
+    public PairBlock(int start, int end, char c) {
+      this.start = start;
+      this.end = end;
+      this.c = c;
+    }
+
+    int start;
+
+    int end;
+
+    char c;
+  }
+
+  private PairBlock[] cachedPairs;
+
+  private long cachedStamp = -1;
+
+  private long cachedHash = -1;
+
+  public TextMarkerPairMatcher(char[] pairs, ScriptEditor editor) {
+    // if (pairs == null) {
+    // throw new IllegalArgumentException();
+    // }
+
+    // fPairs = pairs;
+    this.editor = editor;
+  }
+
+  private PairBlock[] computePairRanges(final int offset, String contents) {
+    ISourceParser pp = null;
+    pp = DLTKLanguageManager.getSourceParser(TextMarkerNature.NATURE_ID);
+    ModuleDeclaration md = null;// pp.parse(null, contents.toCharArray(),
+    // null);
+    IModelElement el = this.editor.getInputModelElement();
+    if (el != null && el instanceof ISourceModule) {
+      md = SourceParserUtil.getModuleDeclaration((ISourceModule) el, null);
+    }
+    if (md == null) {
+      md = pp.parse(null, contents.toCharArray(), null);
+    }
+    if (md == null) {
+      return new PairBlock[0];
+    }
+    final List result = new ArrayList();
+    try {
+      md.traverse(new ASTVisitor() {
+        @Override
+        public boolean visitGeneral(ASTNode node) throws Exception {
+          if (node instanceof StringLiteral) {
+            StringLiteral be = (StringLiteral) node;
+            result.add(new PairBlock(offset + be.sourceStart(), offset + be.sourceEnd() - 1, '\"'));
+            // } else if (node instanceof TextMarkerExecuteExpression) {
+            // TextMarkerExecuteExpression be = (TextMarkerExecuteExpression) node;
+            // result.add(new PairBlock(offset + be.sourceStart(),
+            // offset + be.sourceEnd() - 1, '['));
+          } else if (node instanceof Block) {
+            Block be = (Block) node;
+            result.add(new PairBlock(offset + be.sourceStart(), offset + be.sourceEnd() - 1, '{'));
+          }
+          return super.visitGeneral(node);
+        }
+      });
+    } catch (Exception e) {
+      if (DLTKCore.DEBUG) {
+        e.printStackTrace();
+      }
+    }
+
+    // Iterator i = statements.iterator();
+    // while (i.hasNext()) {
+    // Statement sst = (Statement) i.next();
+    // if (sst instanceof TextMarkerStatement) {
+    // TextMarkerStatement statement = (TextMarkerStatement) sst;
+    // /*
+    // * result.add(new CodeBlock(statement, new Region(offset +
+    // * statement.sourceStart(), statement.sourceEnd() -
+    // * statement.sourceStart())));
+    // */
+    // Iterator si = statement.getExpressions().iterator();
+    // while (si.hasNext()) {
+    // Expression ex = (Expression) si.next();
+    // if (ex instanceof TextMarkerBlockExpression) {
+    // TextMarkerBlockExpression be = (TextMarkerBlockExpression) ex;
+    // try {
+    // String newContents = contents.substring(be
+    // .sourceStart() + 1, be.sourceEnd() - 1);
+    // result.add(new PairBlock(offset + be.sourceStart(),
+    // offset + be.sourceEnd() - 1, '{'));
+    // PairBlock[] cb = computePairRanges(offset
+    // + be.sourceStart() + 1, newContents);
+    // for (int j = 0; j < cb.length; j++) {
+    // result.add(cb[j]);
+    // }
+    // } catch (StringIndexOutOfBoundsException e) {
+    // }
+    // } else if (ex instanceof StringLiteral) {
+    // StringLiteral be = (StringLiteral) ex;
+    // result.add(new PairBlock(offset + be.sourceStart(),
+    // offset + be.sourceEnd() - 1, '\"'));
+    // } else if (ex instanceof TextMarkerExecuteExpression) {
+    // TextMarkerExecuteExpression be = (TextMarkerExecuteExpression) ex;
+    // result.add(new PairBlock(offset + be.sourceStart(),
+    // offset + be.sourceEnd() - 1, '['));
+    // }
+    // }
+    // }
+    // }
+    return (PairBlock[]) result.toArray(new PairBlock[result.size()]);
+  }
+
+  /**
+   * Fully recalcs pairs for document
+   * 
+   * @param doc
+   * @throws BadLocationException
+   */
+  private void recalc() throws BadLocationException {
+    String content = fDocument.get(0, fDocument.getLength());
+    cachedPairs = computePairRanges(0, content);
+
+    if (fDocument instanceof IDocumentExtension4) {
+      cachedStamp = ((IDocumentExtension4) fDocument).getModificationStamp();
+    } else {
+      cachedHash = content.hashCode();
+    }
+  }
+
+  /**
+   * Recalcs pairs for the document, only if it is required
+   */
+  private void updatePairs() throws BadLocationException {
+    if (fDocument instanceof IDocumentExtension4) {
+      IDocumentExtension4 document = (IDocumentExtension4) fDocument;
+
+      if (document.getModificationStamp() == cachedStamp) {
+        return;
+      }
+
+    } else {
+      String content = fDocument.get(0, fDocument.getLength());
+
+      if (content.hashCode() == cachedHash) {
+        return;
+      }
+    }
+
+    recalc();
+  }
+
+  private static boolean isBrace(char c) {
+    return (c == '{' || c == '}' || c == '\"' || c == '[' || c == ']');
+  }
+
+  public IRegion match(IDocument document, int offset) {
+    if (document == null || offset < 0) {
+      throw new IllegalArgumentException();
+    }
+
+    try {
+      fOffset = offset;
+      fDocument = document;
+
+      if (!isBrace(fDocument.getChar(offset))
+              && (offset == 0 || !isBrace(fDocument.getChar(offset - 1)))) {
+        return null;
+      }
+
+      updatePairs();
+
+      if (matchPairsAt() && fStartPos != fEndPos)
+        return new Region(fStartPos, fEndPos - fStartPos + 1);
+    } catch (BadLocationException e) {
+      if (DLTKCore.DEBUG_PARSER)
+        e.printStackTrace();
+    }
+
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.jface.text.source.ICharacterPairMatcher#getAnchor()
+   */
+  public int getAnchor() {
+    return fAnchor;
+  }
+
+  public void dispose() {
+    clear();
+    fDocument = null;
+  }
+
+  public void clear() {
+  }
+
+  private boolean matchPairsAt() {
+
+    fStartPos = -1;
+    fEndPos = -1;
+
+    for (int i = 0; i < cachedPairs.length; i++) {
+      PairBlock block = cachedPairs[i];
+
+      if (fOffset == block.end + 1) {
+        fStartPos = block.start - 1;
+        fEndPos = block.start;
+        fAnchor = LEFT;
+        return true;
+      }
+      if (fOffset == block.start + 1) {
+        fStartPos = block.end - 1;
+        fEndPos = block.end;
+        fAnchor = LEFT;
+        return true;
+      }
+
+    }
+
+    return false;
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPairMatcher.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPairMatcher.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPartitionScanner.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPartitionScanner.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPartitionScanner.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPartitionScanner.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,39 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.tm.dltk.ui.text.TextMarkerPartitions;
+import org.eclipse.jface.text.rules.EndOfLineRule;
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.Token;
+
+
+public class TextMarkerPartitionScanner extends RuleBasedPartitionScanner {
+
+  public TextMarkerPartitionScanner() {
+    super();
+
+    IToken string = new Token(TextMarkerPartitions.TM_STRING);
+    IToken comment = new Token(TextMarkerPartitions.TM_COMMENT);
+
+    List/* < IPredicateRule > */rules = new ArrayList/* <IPredicateRule> */();
+
+    rules.add(new EndOfLineRule("//", comment));
+
+    rules.add(new MultiLineRule("\"\"\"", "\"\"\"", string, '\\'));
+
+    rules.add(new MultiLineRule("\'\'\'", "\'\'\'", string, '\\'));
+
+    rules.add(new MultiLineRule("\'", "\'", string, '\\'));
+
+    rules.add(new MultiLineRule("\"", "\"", string, '\\'));
+
+    IPredicateRule[] result = new IPredicateRule[rules.size()];
+    rules.toArray(result);
+    setPredicateRules(result);
+  }
+}
\ No newline at end of file

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPartitionScanner.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerPartitionScanner.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequireMarkerResolutionGenerator.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequireMarkerResolutionGenerator.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequireMarkerResolutionGenerator.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequireMarkerResolutionGenerator.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,25 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.dltk.core.CorrectionEngine;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.ui.IMarkerResolution;
+import org.eclipse.ui.IMarkerResolutionGenerator;
+
+public class TextMarkerRequireMarkerResolutionGenerator implements IMarkerResolutionGenerator {
+
+  public IMarkerResolution[] getResolutions(IMarker marker) {
+    if (TextMarkerCorrectionProcessor.isFixable(marker)) {
+      String pkgName = CorrectionEngine.getProblemArguments(marker)[0];
+      if (pkgName != null) {
+        IProject project = marker.getResource().getProject();
+        IScriptProject scriptProject = DLTKCore.create(project);
+        return new IMarkerResolution[] { new TextMarkerRequirePackageMarkerResolution(pkgName,
+                scriptProject) };
+      }
+    }
+    return new IMarkerResolution[0];
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequireMarkerResolutionGenerator.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequireMarkerResolutionGenerator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequirePackageMarkerResolution.java
URL: http://svn.apache.org/viewvc/uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequirePackageMarkerResolution.java?rev=1152804&view=auto
==============================================================================
--- uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequirePackageMarkerResolution.java (added)
+++ uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequirePackageMarkerResolution.java Mon Aug  1 14:37:34 2011
@@ -0,0 +1,77 @@
+package org.apache.uima.tm.dltk.internal.ui.text;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.uima.tm.dltk.internal.ui.TextMarkerUI;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.dltk.launching.IInterpreterInstall;
+import org.eclipse.dltk.launching.InterpreterContainerHelper;
+import org.eclipse.dltk.launching.ScriptRuntime;
+import org.eclipse.dltk.ui.editor.IScriptAnnotation;
+import org.eclipse.dltk.ui.text.IAnnotationResolution;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.IMarkerResolution;
+
+
+final class TextMarkerRequirePackageMarkerResolution implements IMarkerResolution,
+        IAnnotationResolution {
+  private String pkgName;
+
+  private IScriptProject project;
+
+  public TextMarkerRequirePackageMarkerResolution(String pkgName, IScriptProject scriptProject) {
+    this.pkgName = pkgName;
+    this.project = scriptProject;
+  }
+
+  public String getLabel() {
+    final String msg = Messages.TextMarkerRequirePackageMarkerResolution_addPackageToBuildpath;
+    return NLS.bind(msg, pkgName);
+  }
+
+  private boolean resolve() {
+    final IInterpreterInstall install;
+    try {
+      install = ScriptRuntime.getInterpreterInstall(project);
+      if (install != null) {
+        final Set names = new HashSet();
+        final Set autoNames = new HashSet();
+        InterpreterContainerHelper.getInterpreterContainerDependencies(project, names, autoNames);
+
+        if (names.add(pkgName)) {
+          InterpreterContainerHelper.setInterpreterContainerDependencies(project, names, autoNames);
+          return true;
+        }
+      }
+    } catch (CoreException e) {
+      TextMarkerUI.error("require package resolve error", e); //$NON-NLS-1$
+    }
+    return false;
+  }
+
+  public void run(final IMarker marker) {
+    if (resolve()) {
+      try {
+        marker.delete();
+      } catch (CoreException e) {
+        if (DLTKCore.DEBUG) {
+          e.printStackTrace();
+        }
+      }
+    }
+  }
+
+  public void run(Annotation annotation, IDocument document) {
+    resolve();
+  }
+
+  public void run(IScriptAnnotation annotation, IDocument document) {
+    resolve();
+  }
+}

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequirePackageMarkerResolution.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: uima/sandbox/trunk/TextMarker/org.apache.uima.tm.dltk.ui/src/main/java/org/apache/uima/tm/dltk/internal/ui/text/TextMarkerRequirePackageMarkerResolution.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain