Skip to content

Commit

Permalink
Add insertLeft option to setBookmark
Browse files Browse the repository at this point in the history
  • Loading branch information
marijnh committed Feb 1, 2013
1 parent 8f63800 commit 5a1976b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 17 deletions.
23 changes: 16 additions & 7 deletions doc/manual.html
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,9 @@ <h2 id="events">Events</h2>
</dl>

<p>Marked range handles, as returned
by <a href="#markText"><code>markText</code></a>, emit the
following event:</p>
by <a href="#markText"><code>markText</code></a>
and <a href="#setBookmark"><code>setBookmark</code></a>, emit the
following events:</p>

<dl>
<dt id="event_clear"><code>"clear" ()</code></dt>
Expand Down Expand Up @@ -929,16 +930,24 @@ <h3 id="api_marker">Text-marking methods</h3>
the <a href="#mark_replacedWith"><code>replacedWith</code></a>
option, if any.</dd>

<dt id="setBookmark"><code>doc.setBookmark(pos, widget) → object</code></dt>
<dt id="setBookmark"><code>doc.setBookmark(pos, options) → object</code></dt>
<dd>Inserts a bookmark, a handle that follows the text around it
as it is being edited, at the given position. A bookmark has two
methods <code>find()</code> and <code>clear()</code>. The first
returns the current position of the bookmark, if it is still in
the document, and the second explicitly removes the bookmark.
The widget argument is optional, and can be used to display a
DOM node at the current location of the bookmark (analogous to
the <a href="#mark_replacedWith"><code>replacedWith</code></a>
option to <code>markText</code>).</dd>
The options argument is optional. If given, the following
properties are recognized:
<dl>
<dt><code>widget</code></dt><dd>Can be used to display a DOM
node at the current location of the bookmark (analogous to
the <a href="#mark_replacedWith"><code>replacedWith</code></a>
option to <code>markText</code>).</dd>
<dt><code>insertLeft</code></dt><dd>By default, text typed
when the cursor is on top of the bookmark will end up to the
right of the bookmark. Set this option to true to make it go
to the left instead.</dd>
</dl></dd>

<dt id="findMarksAt"><code>doc.findMarksAt(pos) → array</code></dt>
<dd>Returns an array of all the bookmarks and marked ranges
Expand Down
20 changes: 11 additions & 9 deletions lib/codemirror.js
Original file line number Diff line number Diff line change
Expand Up @@ -3431,11 +3431,11 @@ window.CodeMirror = (function() {
span.marker.attachLine(line);
}

function markedSpansBefore(old, startCh) {
function markedSpansBefore(old, startCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
if (startsBefore || marker.type == "bookmark" && span.from == startCh) {
if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
(nw || (nw = [])).push({from: span.from,
to: endsAfter ? null : span.to,
Expand All @@ -3445,11 +3445,11 @@ window.CodeMirror = (function() {
return nw;
}

function markedSpansAfter(old, startCh, endCh) {
function markedSpansAfter(old, endCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
if (endsAfter || marker.type == "bookmark" && span.from == endCh && span.from != startCh) {
if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
(nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
to: span.to == null ? null : span.to - endCh,
Expand All @@ -3464,10 +3464,10 @@ window.CodeMirror = (function() {
var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
if (!oldFirst && !oldLast) return null;

var startCh = change.from.ch, endCh = change.to.ch;
var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
// Get the spans that 'stick out' on both sides
var first = markedSpansBefore(oldFirst, startCh);
var last = markedSpansAfter(oldLast, change.from.line == change.to.line ? startCh : NaN, endCh);
var first = markedSpansBefore(oldFirst, startCh, isInsert);
var last = markedSpansAfter(oldLast, endCh, isInsert);

// Next, merge those two ends
var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
Expand Down Expand Up @@ -4267,9 +4267,11 @@ window.CodeMirror = (function() {
markText: function(from, to, options) {
return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
},
setBookmark: function(pos, widget) {
setBookmark: function(pos, options) {
var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
insertLeft: options && options.insertLeft};
pos = clipPos(this, pos);
return markText(this, pos, pos, widget ? {replacedWith: widget} : {}, "bookmark");
return markText(this, pos, pos, realOpts, "bookmark");
},
findMarksAt: function(pos) {
pos = clipPos(this, pos);
Expand Down
17 changes: 16 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,21 @@ testCM("bookmark", function(cm) {
});
});

testCM("bookmarkInsertLeft", function(cm) {
var br = cm.setBookmark({line: 0, ch: 2}, {insertLeft: false});
var bl = cm.setBookmark({line: 0, ch: 2}, {insertLeft: true});
cm.setCursor({line: 0, ch: 2});
cm.replaceSelection("hi");
eqPos(br.find(), {line: 0, ch: 2});
eqPos(bl.find(), {line: 0, ch: 4});
cm.replaceRange("", {line: 0, ch: 4}, {line: 0, ch: 5});
cm.replaceRange("", {line: 0, ch: 2}, {line: 0, ch: 4});
cm.replaceRange("", {line: 0, ch: 1}, {line: 0, ch: 2});
// Verify that deleting next to bookmarks doesn't kill them
eqPos(br.find(), {line: 0, ch: 1});
eqPos(bl.find(), {line: 0, ch: 1});
}, {value: "abcdef"});

testCM("bug577", function(cm) {
cm.setValue("a\nb");
cm.clearHistory();
Expand Down Expand Up @@ -726,7 +741,7 @@ testCM("badNestedFold", function(cm) {
});

testCM("inlineWidget", function(cm) {
var w = cm.setBookmark({line: 0, ch: 2}, document.createTextNode("uu"));
var w = cm.setBookmark({line: 0, ch: 2}, {widget: document.createTextNode("uu")});
cm.setCursor(0, 2);
CodeMirror.commands.goLineDown(cm);
eqPos(cm.getCursor(), {line: 1, ch: 4});
Expand Down

0 comments on commit 5a1976b

Please sign in to comment.