Skip to content

Commit ad6635a

Browse files
committed
[vim bindings] Show fat cursor even in contentEditable mode
Issue codemirror#3552
1 parent a073d18 commit ad6635a

3 files changed

Lines changed: 57 additions & 4 deletions

File tree

demo/vim.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ <h2>Vim bindings demo</h2>
9595
mode: "text/x-csrc",
9696
keyMap: "vim",
9797
matchBrackets: true,
98-
showCursorWhenSelecting: true
98+
showCursorWhenSelecting: true,
99+
inputStyle: "contenteditable"
99100
});
100101
var commandDisplay = document.getElementById('command-display');
101102
var keys = '';

keymap/vim.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,20 +255,67 @@
255255
}
256256

257257
function detachVimMap(cm, next) {
258-
if (this == CodeMirror.keyMap.vim)
258+
if (this == CodeMirror.keyMap.vim) {
259259
CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor");
260+
if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
261+
disableFatCursorMark(cm);
262+
cm.getInputField().style.caretColor = "";
263+
}
264+
}
260265

261266
if (!next || next.attach != attachVimMap)
262267
leaveVimMode(cm);
263268
}
264269
function attachVimMap(cm, prev) {
265-
if (this == CodeMirror.keyMap.vim)
270+
if (this == CodeMirror.keyMap.vim) {
266271
CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor");
272+
if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
273+
enableFatCursorMark(cm);
274+
cm.getInputField().style.caretColor = "transparent";
275+
}
276+
}
267277

268278
if (!prev || prev.attach != attachVimMap)
269279
enterVimMode(cm);
270280
}
271281

282+
function fatCursorMarks(cm) {
283+
var ranges = cm.listSelections(), result = []
284+
for (var i = 0; i < ranges.length; i++) {
285+
var range = ranges[i]
286+
if (range.empty()) {
287+
if (range.anchor.ch < cm.getLine(range.anchor.line).length) {
288+
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
289+
{className: "cm-fat-cursor-mark"}))
290+
} else {
291+
var widget = document.createElement("span")
292+
widget.textContent = "\u00a0"
293+
widget.className = "cm-fat-cursor-mark"
294+
result.push(cm.setBookmark(range.anchor, {widget: widget}))
295+
}
296+
}
297+
}
298+
return result
299+
}
300+
301+
function updateFatCursorMark(cm) {
302+
var marks = cm.state.fatCursorMarks
303+
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
304+
cm.state.fatCursorMarks = fatCursorMarks(cm)
305+
}
306+
307+
function enableFatCursorMark(cm) {
308+
cm.state.fatCursorMarks = fatCursorMarks(cm)
309+
cm.on("cursorActivity", updateFatCursorMark)
310+
}
311+
312+
function disableFatCursorMark(cm) {
313+
var marks = cm.state.fatCursorMarks
314+
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
315+
cm.state.fatCursorMarks = null
316+
cm.off("cursorActivity", updateFatCursorMark)
317+
}
318+
272319
// Deprecated, simply setting the keymap works again.
273320
CodeMirror.defineOption('vimMode', false, function(cm, val, prev) {
274321
if (val && cm.getOption("keyMap") != "vim")

lib/codemirror.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@
5959
.cm-fat-cursor div.CodeMirror-cursors {
6060
z-index: 1;
6161
}
62-
62+
.cm-fat-cursor-mark {
63+
background-color: rgba(20, 255, 20, 0.5);
64+
-webkit-animation: blink 1.06s steps(1) infinite;
65+
-moz-animation: blink 1.06s steps(1) infinite;
66+
animation: blink 1.06s steps(1) infinite;
67+
}
6368
.cm-animate-fat-cursor {
6469
width: auto;
6570
border: 0;

0 commit comments

Comments
 (0)