Add support to DocumentEdits to 'freeze' cursor

This commit is contained in:
Kris De Volder
2017-05-01 14:50:44 -07:00
parent 86a2dd63c5
commit 76c7c3c791
3 changed files with 86 additions and 13 deletions

View File

@@ -21,8 +21,7 @@ import reactor.ipc.netty.channel.AbortedException;
/**
* This is a stateful callable context that is "aware" of CF errors, and is not
* suitable for reuse as it may cache errors
*
* suitable for reuse as it may cache errors.
*/
public class CFCallableContext {

View File

@@ -135,14 +135,15 @@ public class DocumentEdits implements ProposalApplier {
private int offset;
private String text;
public Insertion(int offset, String insert) {
public Insertion(boolean grabCursor, int offset, String insert) {
super(grabCursor);
this.offset = offset;
this.text = insert;
}
@Override
void apply(DocumentState doc) throws BadLocationException {
doc.insert(offset, text);
doc.insert(grabCursor, offset, text);
}
@Override
@@ -162,6 +163,10 @@ public class DocumentEdits implements ProposalApplier {
}
private abstract class Edit {
protected boolean grabCursor;
protected Edit(boolean grabCursor) {
this.grabCursor = grabCursor;
}
public abstract int getStart();
public abstract int getEnd();
abstract void apply(DocumentState doc) throws BadLocationException;
@@ -174,14 +179,15 @@ public class DocumentEdits implements ProposalApplier {
private int start;
private int end;
public Deletion(int start, int end) {
public Deletion(boolean grabCursor, int start, int end) {
super(grabCursor);
this.start = start;
this.end = end;
}
@Override
void apply(DocumentState doc) throws BadLocationException {
doc.delete(start, end);
doc.delete(grabCursor, start, end);
}
@Override
@@ -227,7 +233,7 @@ public class DocumentEdits implements ProposalApplier {
this.doc = doc;
}
public void insert(int start, final String text) throws BadLocationException {
public void insert(boolean grabCursor, int start, final String text) throws BadLocationException {
final int tStart = org2new.transform(start, Direction.AFTER);
if (!text.isEmpty()) {
if (doc!=null) {
@@ -252,10 +258,14 @@ public class DocumentEdits implements ProposalApplier {
}
};
}
selection = tStart+text.length();
if (grabCursor) {
selection = tStart+text.length();
} else if (selection > tStart) {
selection += text.length();
}
}
public void delete(final int start, final int end) throws BadLocationException {
public void delete(boolean grabCursor, final int start, final int end) throws BadLocationException {
final int tStart = org2new.transform(start, Direction.AFTER);
if (end>start) { // skip work for 'delete nothing' op
final int tEnd = org2new.transform(end, Direction.AFTER);
@@ -280,7 +290,14 @@ public class DocumentEdits implements ProposalApplier {
};
}
}
selection = tStart;
if (grabCursor) {
selection = tStart;
} else if (selection>tStart) {
int len = end - start;
if (len > 0) {
selection = Math.max(tStart, selection-len);
}
}
}
@Override
@@ -299,13 +316,22 @@ public class DocumentEdits implements ProposalApplier {
private List<Edit> edits = new ArrayList<Edit>();
private IDocument doc;
/**
* When this is true, the cursor is moved after each edit, to be positioned right after the
* edit.
* <p>
* When it is false, the cursor only moves to remain in place relative to the surrounding text.
* (I.e. if text is inserted/deleted before the cursor its shifted by the length of the inserted/deleted text).
*/
private boolean grabCursor = true;
public DocumentEdits(IDocument doc) {
this.doc = doc;
}
public void delete(int start, int end) {
Assert.isLegal(start<=end);
edits.add(new Deletion(start, end));
edits.add(new Deletion(grabCursor, start, end));
}
public void delete(int offset, String text) {
@@ -313,7 +339,7 @@ public class DocumentEdits implements ProposalApplier {
}
public void insert(int offset, String insert) {
edits.add(new Insertion(offset, insert));
edits.add(new Insertion(grabCursor, offset, insert));
}
@Override
@@ -417,7 +443,7 @@ public class DocumentEdits implements ProposalApplier {
if (edits.size()>0) {
Edit firstEdit = edits.get(0);
int offset = firstEdit.getStart();
edits.add(0, new Insertion(offset, indentString));
edits.add(0, new Insertion(grabCursor, offset, indentString));
}
}
@@ -445,4 +471,12 @@ public class DocumentEdits implements ProposalApplier {
return null;
}
/**
* Stop moving the cursor to the end of edits for successive edits. The cursor will still be
* update to remain 'in place' relative to the surrounding text.
*/
public void freezeCursor() {
this.grabCursor = false;
}
}

View File

@@ -96,6 +96,10 @@ public class DocumentEditsTest {
edits.deleteLineBackward(0);
}
public void freezeCursor() {
edits.freezeCursor();
}
}
@Test public void testDeletes() throws Exception {
@@ -194,4 +198,40 @@ public class DocumentEditsTest {
}
@Test public void testCursorFreeze() throws Exception {
TestSubject it = new TestSubject(
"something:\n" +
"#end"
);
// it.insBefore("\n#end", "\n foo: ");
// it.insBefore("\n#end", "\n zoro: ");
// it.insBefore("\n#end", "\n banana: ");
//
// it.expect(
// "something:\n" +
// " foo: \n" +
// " zoro: \n" +
// " banana: <*>\n" +
// "#end"
// );
//
// it.reset();
it.insBefore("\n#end", "\n foo: ");
it.freezeCursor();
it.insBefore("\n#end", "\n zoro: ");
it.insBefore("\n#end", "\n banana: ");
it.del("#end");
it.insBefore("something", "replc");
it.del("something");
it.expect(
"replc:\n" +
" foo: <*>\n" +
" zoro: \n" +
" banana: \n"
);
}
}