Package com.redcareditor.mate

Source Code of com.redcareditor.mate.ParserScheduler

package com.redcareditor.mate;

import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;

import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.JFaceTextUtil;
import org.eclipse.jface.text.DocumentEvent;

import com.redcareditor.mate.document.swt.SwtMateTextLocation;
import com.redcareditor.onig.Range;

public class ParserScheduler {
  public static int LOOK_AHEAD = 300;
  public static boolean synchronousParsing = false;
  public int lookAhead;
  public int lastVisibleLine;
  public boolean alwaysParseAll;
  public boolean enabled;
  public RangeSet changes;
  public int deactivationLevel;

  public int modifyStart, modifyEnd;
  public String modifyText;
  public ParseThunk thunk;
  public Parser parser;

  public int parsed_upto; 
  public SwtMateTextLocation parsedUpto;

  public ParserScheduler(Parser parser) {
    this.parser = parser;
    lookAhead = LOOK_AHEAD;
    lastVisibleLine = 0;
    changes = new RangeSet();
    deactivationLevel = 0;
    alwaysParseAll = false;
    modifyStart = -1;
    enabled = true;
    setParsedUpto(0);
    attachListeners();
  }
 
  public void close() {
    if (thunk != null) {
      thunk.stop();
      thunk = null;
    }
    removeListeners();
  }

  private VerifyListener verifyListener;
  private ModifyListener modifyListener;
  private IViewportListener viewportListener;
  private IDocumentListener documentListener;
 
  public void attachListeners() {
    viewportListener = new IViewportListener() {
      public void viewportChanged(int verticalOffset) {
        viewportScrolledCallback();
      }
    };
   
    parser.mateText.viewer.addViewportListener(viewportListener);
   
    documentListener = new IDocumentListener() {
      public void documentAboutToBeChanged(DocumentEvent e) {
        verifyEventCallback(e.fOffset, e.fOffset + e.fLength, e.fText);
      }
     
      public void documentChanged(DocumentEvent e) {
        modifyEventCallback();
      }
    };
    parser.mateText.getDocument().addDocumentListener(documentListener);
  }
 
  public void removeListeners() {
    parser.mateText.viewer.removeViewportListener(viewportListener);
    parser.mateText.getDocument().removeDocumentListener(documentListener);
  }

  public void verifyEventCallback(int start, int end, String text) {
    if (enabled) {
      modifyStart = start;
      modifyEnd   = end;
      modifyText  = text;
    }
  }
 
  public void modifyEventCallback() {
    if (enabled) {
      changes.add(
        parser.getLineAtOffset(modifyStart),
        parser.getLineAtOffset(modifyStart + modifyText.length())
      );
      modifyStart = -1;
      modifyEnd   = -1;
      modifyText  = null;
      if (deactivationLevel == 0)
        processChanges();
    }
  }

  public void viewportScrolledCallback() {
    if (enabled) {
      lastVisibleLineChanged(JFaceTextUtil.getBottomIndex(parser.mateText.getTextWidget()));
    }
  }
 
  public void deactivate() {
    deactivationLevel++;
  }
 
  public void reactivate() {
    deactivationLevel--;
    if (deactivationLevel < 0)
      deactivationLevel = 0;
    if (deactivationLevel == 0)
      processChanges();
  }
 
  // Process all change ranges.
  public void processChanges() {
    int thisParsedUpto = -1;
    // System.out.printf("process_changes (lastVisibleLine: %d) (charCount = %d)\n", lastVisibleLine, document.getLength());
    for (Range range : changes) {
      if (range.end > thisParsedUpto && range.start <= lastVisibleLine + lookAhead) {
        int rangeEnd;
        if (alwaysParseAll) {
          rangeEnd = parser.getLineCount() - 1;
        } else {
          rangeEnd = Math.min(lastVisibleLine + lookAhead, range.end);
        }
        //System.out.printf("parseRange from processChanges\n");
        thisParsedUpto = parseRange(range.start, rangeEnd);
      }
      int startOffset = parser.getOffsetAtLine(range.start);
      int endOffset   = parser.getOffsetAtLine(range.end);
      parser.styledText.redrawRange(startOffset, endOffset - startOffset, false);
    }
    //    System.out.printf("%s\n", root.pretty(0));
    changes.ranges.clear();
  }

  public void thunkFrom(int lineIx) {
    if (thunk != null) {
      thunk.delayAndUpdate(lineIx);
    }
    else {
      if (lineIx <= parser.getLineCount() - 1) {
        thunk = new ParseThunk(parser, lineIx);
        if (ParserScheduler.synchronousParsing) {
          thunk.execute();
        }
      }
    }
  }

  // Parse from from_line to *at least* to_line. Will parse
  // more if necessary. Returns the index of the last line
  // parsed.
  public int parseRange(int fromLine, int toLine) {
    //System.out.printf("parse_range(%d, %d)\n", fromLine, toLine);

    int lineIx = fromLine;
    boolean scopeChanged = false;
    boolean scopeEverChanged = false;
    while (lineIx <= toLine) {
      scopeChanged = parser.parseLine(lineIx);
      if (scopeChanged) {
        if (scopeEverChanged == false && getParsedUpto() > lineIx) {
          //System.out.printf(parser.root.pretty(4));
          //System.out.printf("-- clearFrom(%d) --\n", lineIx);
          parser.clearFrom(parser.getOffsetAtLine(lineIx + 1));
          //System.out.printf(parser.root.pretty(4));
        }
        setParsedUpto(lineIx);
        scopeEverChanged = true;
      }
      lineIx++;
    }
    if (scopeEverChanged) {
      thunkFrom(lineIx);
    }

    return toLine;
  }
 
  public int parseOnwards(int fromLine) {
    // The widget can be disposed between the Thunk being created and being executed.
    if (parser.styledText.isDisposed())
      return -1;
    int lineIx = fromLine;
    int lineCount = parser.getLineCount();
    int lastLine = Math.min(lastVisibleLine + LOOK_AHEAD, lineCount - 1);
    int toLine = Math.min(fromLine + LOOK_AHEAD, lastLine);
    while (lineIx <= toLine) {
      parser.parseLine(lineIx);
      setParsedUpto(lineIx);
      parser.redrawLine(lineIx);
      lineIx++;
    }
   
    return lineIx;
  }
 
  public void lastVisibleLineChanged(int newLastVisibleLine) {
    int oldLastVisibleLine = lastVisibleLine;
    //System.out.printf("lastVisibleLineChanged(%d)\n", newLastVisibleLine);
    this.lastVisibleLine = newLastVisibleLine;
    //System.out.printf("lastVisibleLine: %d, lookAhead: %d, getParsedUpto: %d\n", lastVisibleLine, lookAhead, getParsedUpto());
    if (lastVisibleLine + lookAhead >= getParsedUpto() && getParsedUpto() < parser.getLineCount() - 1) {
      int endRange = Math.min(parser.getLineCount() - 1, lastVisibleLine + lookAhead);
      thunkFrom(getParsedUpto());
    }
  }
 
  public void setParsedUpto(int line_ix) {
    if (parsedUpto == null) {
      parsedUpto = (SwtMateTextLocation) parser.mateDocument.getTextLocation(0, 0);
      parser.mateDocument.addTextLocation("lefts", parsedUpto);
    }
    parsedUpto.offset = parser.getOffsetAtLine(line_ix);
  }
 
  public int getParsedUpto() {
    // System.out.printf("parsedUpto %d,%d (/%d)\n", parsedUpto.getOffset(), parsedUpto.getLength(), parser.getCharCount());
    return parser.getLineAtOffset(parsedUpto.getOffset());
  }
 
}
TOP

Related Classes of com.redcareditor.mate.ParserScheduler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.