Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

small fix for syntax highlighter in async mode #83

Merged
merged 1 commit into from

2 participants

@yiding

when highlighting finishes in a different thread, the source code may
have changed in the mean time, making the tokenization invalid. This can
cause coloring to be applied that's off by a few characters, or even
exceptions if the file has been shortened.

This fix discards the tokenizer result if the file has changed by seeing
if there is another queued highlighter job. When continuously typing, newly
typed characters may not highlight immediately. But on the other hand, this
actually makes the async-highlight mode usable for me.

Also use the implicit lock in the SingleJobQueue object for
synchronization instead of creating another object.

@yiding yiding fix issues when running highlighter in a different thread
when highlighting finishes in a different thread, the source code may
have changed in the mean time, making the tokenization invalid. This can
cause coloring to be applied that's off by a few characters, or even
exceptions if the file has been shortened.

This fix discards the tokenizer result if the file has changed by seeing
if there is another queued highlighter job. This has a side effect of
causing newly typed text to syntax highlight slower (if you type really
fast, or highlighting is slow).

Also use the implicit lock in the SingleJobQueue object for
synchronization instead of creating another object.
8deb3ac
@JPMoresmau JPMoresmau merged commit 3e6bd3d into JPMoresmau:master
@JPMoresmau
Owner

Thank you, merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 10, 2013
  1. @yiding

    fix issues when running highlighter in a different thread

    yiding authored
    when highlighting finishes in a different thread, the source code may
    have changed in the mean time, making the tokenization invalid. This can
    cause coloring to be applied that's off by a few characters, or even
    exceptions if the file has been shortened.
    
    This fix discards the tokenizer result if the file has changed by seeing
    if there is another queued highlighter job. This has a side effect of
    causing newly typed text to syntax highlight slower (if you type really
    fast, or highlighting is slow).
    
    Also use the implicit lock in the SingleJobQueue object for
    synchronization instead of creating another object.
This page is out of date. Refresh to see the latest.
View
3  ...c/net/sf/eclipsefp/haskell/ui/internal/editors/haskell/HaskellPresentationReconciler.java
@@ -63,7 +63,8 @@ public SyntaxColoringJob( final IRegion damage, final IDocument document ) {
@Override
protected IStatus run( final IProgressMonitor arg0 ) {
final TextPresentation p=HaskellPresentationReconciler.super.createPresentation( damage, document );
- if (p!=null && viewer!=null && viewer.getTextWidget()!=null && !viewer.getTextWidget().isDisposed()){
+ if (p!=null && viewer!=null && viewer.getTextWidget()!=null && !viewer.getTextWidget().isDisposed() &&
+ !queue.hasPendingJob()){
viewer.getTextWidget().getDisplay().syncExec( new Runnable(){
/* (non-Javadoc)
* @see java.lang.Runnable#run()
View
47 net.sf.eclipsefp.haskell.util/src/net/sf/eclipsefp/haskell/util/SingleJobQueue.java
@@ -11,11 +11,6 @@
*/
public class SingleJobQueue {
/**
- * lock to ensure concurrency
- */
- private Object lock=new Object();
-
- /**
* the currently running job
*/
private Job current;
@@ -23,37 +18,37 @@
* the next job to run
*/
private Job next;
-
+
/**
* add a job to the queue
* if the queue is empty, schedule the job straight away
* otherwise queue the job (losing the previously waiting job if any)
* @param j
*/
- public void addJob(Job j){
- synchronized (lock){
- if (current==null){
- current=j;
- launchCurrent();
- } else {
- next=j;
- }
+ public synchronized void addJob(Job j) {
+ if (current==null){
+ current=j;
+ launchCurrent();
+ } else {
+ next=j;
}
}
-
+
/**
* close the queue: cancel current job and remove next
*/
- public void close(){
- synchronized (lock){
- next=null;
- if (current!=null){
- current.cancel();
- }
- current=null;
+ public synchronized void close(){
+ next=null;
+ if (current!=null){
+ current.cancel();
}
+ current=null;
+ }
+
+ public synchronized boolean hasPendingJob() {
+ return next != null;
}
-
+
/**
* launch the current job with a listener that will launch the waiting job on completion
*/
@@ -63,11 +58,11 @@ private void launchCurrent(){
current.schedule();
}
}
-
+
private class ScheduleNextListener extends JobChangeAdapter {
@Override
public void done(IJobChangeEvent event) {
- synchronized (lock) {
+ synchronized (SingleJobQueue.this) {
// we're not running
current=null;
// we have a job waiting, let's run it
@@ -79,5 +74,5 @@ public void done(IJobChangeEvent event) {
}
}
}
-
+
}
Something went wrong with that request. Please try again.