Skip to content

Commit 743190e

Browse files
fix: show 2 context characters of a line when moving to it (#4998)
1 parent 6fb39e3 commit 743190e

File tree

2 files changed

+59
-25
lines changed

2 files changed

+59
-25
lines changed

src/virtual_renderer.js

+32-25
Original file line numberDiff line numberDiff line change
@@ -1227,40 +1227,47 @@ var VirtualRenderer = function(container, theme) {
12271227

12281228
var pos = this.$cursorLayer.getPixelPosition(cursor);
12291229

1230-
var left = pos.left;
1231-
var top = pos.top;
1232-
1230+
var newLeft = pos.left;
1231+
var newTop = pos.top;
1232+
12331233
var topMargin = $viewMargin && $viewMargin.top || 0;
12341234
var bottomMargin = $viewMargin && $viewMargin.bottom || 0;
12351235

12361236
if (this.$scrollAnimation) {
12371237
this.$stopAnimation = true;
12381238
}
1239-
1240-
var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;
1241-
1242-
if (scrollTop + topMargin > top) {
1243-
if (offset && scrollTop + topMargin > top + this.lineHeight)
1244-
top -= offset * this.$size.scrollerHeight;
1245-
if (top === 0)
1246-
top = -this.scrollMargin.top;
1247-
this.session.setScrollTop(top);
1248-
} else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) {
1249-
if (offset && scrollTop + this.$size.scrollerHeight - bottomMargin < top - this.lineHeight)
1250-
top += offset * this.$size.scrollerHeight;
1251-
this.session.setScrollTop(top + this.lineHeight + bottomMargin - this.$size.scrollerHeight);
1239+
1240+
var currentTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;
1241+
1242+
if (currentTop + topMargin > newTop) {
1243+
if (offset && currentTop + topMargin > newTop + this.lineHeight)
1244+
newTop -= offset * this.$size.scrollerHeight;
1245+
if (newTop === 0)
1246+
newTop = -this.scrollMargin.top;
1247+
this.session.setScrollTop(newTop);
1248+
} else if (currentTop + this.$size.scrollerHeight - bottomMargin < newTop + this.lineHeight) {
1249+
if (offset && currentTop + this.$size.scrollerHeight - bottomMargin < newTop - this.lineHeight)
1250+
newTop += offset * this.$size.scrollerHeight;
1251+
this.session.setScrollTop(newTop + this.lineHeight + bottomMargin - this.$size.scrollerHeight);
12521252
}
12531253

1254-
var scrollLeft = this.scrollLeft;
1254+
var currentLeft = this.scrollLeft;
1255+
// Show 2 context characters of the line when moving to it
1256+
var twoCharsWidth = 2 * this.layerConfig.characterWidth;
12551257

1256-
if (scrollLeft > left) {
1257-
if (left < this.$padding + 2 * this.layerConfig.characterWidth)
1258-
left = -this.scrollMargin.left;
1259-
this.session.setScrollLeft(left);
1260-
} else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
1261-
this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
1262-
} else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) {
1263-
this.session.setScrollLeft(0);
1258+
if (newLeft - twoCharsWidth < currentLeft) {
1259+
newLeft -= twoCharsWidth;
1260+
if (newLeft < this.$padding + twoCharsWidth) {
1261+
newLeft = -this.scrollMargin.left;
1262+
}
1263+
this.session.setScrollLeft(newLeft);
1264+
} else {
1265+
newLeft += twoCharsWidth;
1266+
if (currentLeft + this.$size.scrollerWidth < newLeft + this.characterWidth) {
1267+
this.session.setScrollLeft(Math.round(newLeft + this.characterWidth - this.$size.scrollerWidth));
1268+
} else if (currentLeft <= this.$padding && newLeft - currentLeft < this.characterWidth) {
1269+
this.session.setScrollLeft(0);
1270+
}
12641271
}
12651272
};
12661273

src/virtual_renderer_test.js

+27
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,33 @@ module.exports = {
325325
}, 60);
326326
}, 60);
327327
}, 60);
328+
},
329+
"test: scroll cursor into view": function() {
330+
function X(n) {
331+
return "X".repeat(n);
332+
}
333+
editor.session.setValue(`${X(10)}\n${X(1000)}}`);
334+
335+
var initialContentLeft = editor.renderer.content.getBoundingClientRect().left;
336+
337+
// Scroll so far to the right that the first line is completely hidden
338+
editor.session.selection.$setSelection(1, 1000, 1, 1000);
339+
editor.renderer.scrollCursorIntoView();
340+
editor.renderer.$loop._flush();
341+
342+
editor.session.selection.$setSelection(0, 10, 0, 10);
343+
editor.renderer.scrollCursorIntoView();
344+
editor.renderer.$loop._flush();
345+
346+
var contentLeft = editor.renderer.content.getBoundingClientRect().left;
347+
var scrollDelta = initialContentLeft - contentLeft;
348+
349+
const leftBoundPixelPos = editor.renderer.$cursorLayer.getPixelPosition({row: 0, column: 8}).left;
350+
const rightBoundPixelPos = editor.renderer.$cursorLayer.getPixelPosition({row: 0, column: 9}).left;
351+
assert.ok(
352+
scrollDelta >= leftBoundPixelPos && scrollDelta < rightBoundPixelPos,
353+
"Expected content to have been scrolled two characters beyond the cursor"
354+
);
328355
}
329356

330357
// change tab size after setDocument (for text layer)

0 commit comments

Comments
 (0)