Skip to content

Commit fe63c99

Browse files
mattsacksmarijnh
authored andcommitted
Add text-objects ' and "
Adds function findBeginningAndEnd to find identical symbols on the same line
1 parent 4a3ec5a commit fe63c99

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

keymap/vim.js

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,63 @@
651651
return {start: start, end: end};
652652
}
653653

654+
// takes in a symbol and a cursor and tries to simulate text objects that have
655+
// identical opening and closing symbols
656+
// TODO support across multiple lines
657+
function findBeginningAndEnd(cm, symb, inclusive) {
658+
var cur = cm.getCursor();
659+
var line = cm.getLine(cur.line);
660+
var chars = line.split('');
661+
var start = undefined;
662+
var end = undefined;
663+
var firstIndex = chars.indexOf(symb);
664+
665+
// the decision tree is to always look backwards for the beginning first,
666+
// but if the cursor is in front of the first instance of the symb,
667+
// then move the cursor forward
668+
if (cur.ch < firstIndex) {
669+
cur.ch = firstIndex;
670+
cm.setCursor(cur.line, firstIndex+1);
671+
}
672+
// otherwise if the cursor is currently on the closing symbol
673+
else if (firstIndex < cur.ch && chars[cur.ch] == symb) {
674+
end = cur.ch; // assign end to the current cursor
675+
--cur.ch; // make sure to look backwards
676+
}
677+
678+
// if we're currently on the symbol, we've got a start
679+
if (chars[cur.ch] == symb && end == null)
680+
start = cur.ch + 1; // assign start to ahead of the cursor
681+
else {
682+
// go backwards to find the start
683+
for (var i = cur.ch; i > -1 && start == null; i--)
684+
if (chars[i] == symb) start = i + 1;
685+
}
686+
687+
// look forwards for the end symbol
688+
if (start != null && end == null) {
689+
for (var i = start, len = chars.length; i < len && end == null; i++) {
690+
if (chars[i] == symb) end = i;
691+
}
692+
}
693+
694+
// nothing found
695+
// FIXME still enters insert mode
696+
if (start == null || end == null) return {
697+
start: cur, end: cur
698+
};
699+
700+
// include the symbols
701+
if (inclusive) {
702+
--start; ++end;
703+
}
704+
705+
return {
706+
start: {line: cur.line, ch: start},
707+
end: {line: cur.line, ch: end}
708+
};
709+
}
710+
654711
// These are our motion commands to be used for navigation and selection with
655712
// certian other commands. All should return a cursor object.
656713
var motionList = ['B', 'E', 'J', 'K', 'H', 'L', 'W', 'Shift-W', "'^'", "'$'", "'%'", 'Esc'];
@@ -805,7 +862,7 @@
805862

806863
// Create our text object functions. They work similar to motions but they
807864
// return a start cursor as well
808-
var textObjectList = ['W', 'Shift-[', 'Shift-9', '['];
865+
var textObjectList = ['W', 'Shift-[', 'Shift-9', '[', "'", "Shift-'"];
809866
var textObjects = {
810867
'W': function(cm, inclusive) {
811868
var cur = cm.getCursor();
@@ -820,7 +877,9 @@
820877
},
821878
'Shift-[': function(cm, inclusive) { return selectCompanionObject(cm, '}', inclusive); },
822879
'Shift-9': function(cm, inclusive) { return selectCompanionObject(cm, ')', inclusive); },
823-
'[': function(cm, inclusive) { return selectCompanionObject(cm, ']', inclusive); }
880+
'[': function(cm, inclusive) { return selectCompanionObject(cm, ']', inclusive); },
881+
"'": function(cm, inclusive) { return findBeginningAndEnd(cm, "'", inclusive); },
882+
"Shift-'": function(cm, inclusive) { return findBeginningAndEnd(cm, '"', inclusive); }
824883
};
825884

826885
// One function to handle all operation upon text objects. Kinda funky but it works

0 commit comments

Comments
 (0)