|
651 | 651 | return {start: start, end: end}; |
652 | 652 | } |
653 | 653 |
|
| 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 | + |
654 | 711 | // These are our motion commands to be used for navigation and selection with |
655 | 712 | // certian other commands. All should return a cursor object. |
656 | 713 | var motionList = ['B', 'E', 'J', 'K', 'H', 'L', 'W', 'Shift-W', "'^'", "'$'", "'%'", 'Esc']; |
|
805 | 862 |
|
806 | 863 | // Create our text object functions. They work similar to motions but they |
807 | 864 | // return a start cursor as well |
808 | | - var textObjectList = ['W', 'Shift-[', 'Shift-9', '[']; |
| 865 | + var textObjectList = ['W', 'Shift-[', 'Shift-9', '[', "'", "Shift-'"]; |
809 | 866 | var textObjects = { |
810 | 867 | 'W': function(cm, inclusive) { |
811 | 868 | var cur = cm.getCursor(); |
|
820 | 877 | }, |
821 | 878 | 'Shift-[': function(cm, inclusive) { return selectCompanionObject(cm, '}', inclusive); }, |
822 | 879 | '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); } |
824 | 883 | }; |
825 | 884 |
|
826 | 885 | // One function to handle all operation upon text objects. Kinda funky but it works |
|
0 commit comments