|
2348 | 2348 | } |
2349 | 2349 | } |
2350 | 2350 | cm.setCursor(curPosFinal); |
| 2351 | + if (vim.visualMode) { |
| 2352 | + exitVisualMode(cm); |
| 2353 | + } |
2351 | 2354 | }, |
2352 | 2355 | undo: function(cm, actionArgs) { |
2353 | 2356 | cm.operation(function() { |
|
2449 | 2452 | repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */); |
2450 | 2453 | }, |
2451 | 2454 | changeCase: function(cm, actionArgs, vim) { |
2452 | | - var selectedAreaRange = getSelectedAreaRange(cm, vim); |
2453 | | - var selectionStart = selectedAreaRange[0]; |
2454 | | - var selectionEnd = selectedAreaRange[1]; |
| 2455 | + var selectionStart = getSelectedAreaRange(cm, vim)[0]; |
| 2456 | + var text = cm.getSelection(); |
| 2457 | + var lastSelectionCurEnd; |
| 2458 | + var blockSelection; |
| 2459 | + if (vim.lastSelection) { |
2455 | 2460 | // save the curEnd marker to avoid its removal due to cm.replaceRange |
2456 | | - var lastSelectionCurEnd = vim.lastSelection.curEndMark.find(); |
| 2461 | + lastSelectionCurEnd = vim.lastSelection.curEndMark.find(); |
| 2462 | + blockSelection = vim.lastSelection.visualBlock; |
| 2463 | + } |
2457 | 2464 | var toLower = actionArgs.toLower; |
2458 | | - var text = cm.getRange(selectionStart, selectionEnd); |
2459 | | - cm.replaceRange(toLower ? text.toLowerCase() : text.toUpperCase(), selectionStart, selectionEnd); |
| 2465 | + text = toLower ? text.toLowerCase() : text.toUpperCase(); |
| 2466 | + cm.replaceSelections(vim.visualBlock || blockSelection ? text.split('\n') : [text]); |
2460 | 2467 | // restore the last selection curEnd marker |
2461 | | - vim.lastSelection.curEndMark = cm.setBookmark(lastSelectionCurEnd); |
| 2468 | + if (lastSelectionCurEnd) { |
| 2469 | + vim.lastSelection.curEndMark = cm.setBookmark(lastSelectionCurEnd); |
| 2470 | + } |
2462 | 2471 | cm.setCursor(selectionStart); |
| 2472 | + if (vim.visualMode) { |
| 2473 | + exitVisualMode(cm); |
| 2474 | + } |
2463 | 2475 | } |
2464 | 2476 | }; |
2465 | 2477 |
|
|
2623 | 2635 | return -1; |
2624 | 2636 | } |
2625 | 2637 | function getSelectedAreaRange(cm, vim) { |
2626 | | - var selectionStart = cm.getCursor('anchor'); |
2627 | | - var selectionEnd = cm.getCursor('head'); |
2628 | 2638 | var lastSelection = vim.lastSelection; |
2629 | | - if (!vim.visualMode) { |
2630 | | - var lastSelectionCurStart = vim.lastSelection.curStartMark.find(); |
2631 | | - var lastSelectionCurEnd = vim.lastSelection.curEndMark.find(); |
2632 | | - var line = lastSelectionCurEnd.line - lastSelectionCurStart.line; |
2633 | | - var ch = line ? lastSelectionCurEnd.ch : lastSelectionCurEnd.ch - lastSelectionCurStart.ch; |
2634 | | - selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch}; |
2635 | | - if (lastSelection.visualLine) { |
2636 | | - return [{line: selectionStart.line, ch: 0}, {line: selectionEnd.line, ch: lineLength(cm, selectionEnd.line)}]; |
| 2639 | + var getCurrentSelectedAreaRange = function() { |
| 2640 | + var selections = cm.listSelections(); |
| 2641 | + var start = selections[0]; |
| 2642 | + var end = selections[selections.length-1]; |
| 2643 | + var selectionStart = cursorIsBefore(start.anchor, start.head) ? start.anchor : start.head; |
| 2644 | + var selectionEnd = cursorIsBefore(end.anchor, end.head) ? end.head : end.anchor; |
| 2645 | + return [selectionStart, selectionEnd]; |
| 2646 | + }; |
| 2647 | + var getLastSelectedAreaRange = function() { |
| 2648 | + var start = lastSelection.curStartMark.find(); |
| 2649 | + var end = lastSelection.curEndMark.find(); |
| 2650 | + var selectionStart = cm.getCursor(); |
| 2651 | + var selectionEnd = cm.getCursor(); |
| 2652 | + if (lastSelection.visualBlock) { |
| 2653 | + var anchor = Pos(Math.min(start.line, end.line), Math.min(start.ch, end.ch)); |
| 2654 | + var head = Pos(Math.max(start.line, end.line), Math.max(start.ch, end.ch)); |
| 2655 | + var width = head.ch - anchor.ch; |
| 2656 | + var height = head.line - anchor.line; |
| 2657 | + selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width); |
| 2658 | + var endCh = cm.clipPos(selectionEnd).ch; |
| 2659 | + // We do not want selection crossing while selecting here. |
| 2660 | + // So, we cut down the selection. |
| 2661 | + while (endCh != selectionEnd.ch) { |
| 2662 | + if (endCh-1 == selectionStart.ch) { |
| 2663 | + break; |
| 2664 | + } |
| 2665 | + selectionEnd.line--; |
| 2666 | + endCh = cm.clipPos(selectionEnd).ch; |
| 2667 | + } |
| 2668 | + cm.setCursor(selectionStart); |
| 2669 | + selectBlock(cm, selectionEnd); |
| 2670 | + } else { |
| 2671 | + var line = end.line - start.line; |
| 2672 | + var ch = end.ch - start.ch; |
| 2673 | + selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch}; |
| 2674 | + if (lastSelection.visualLine) { |
| 2675 | + selectionStart = Pos(selectionStart.line, 0); |
| 2676 | + selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line)); |
| 2677 | + } |
| 2678 | + cm.setSelection(selectionStart, selectionEnd); |
2637 | 2679 | } |
| 2680 | + return [selectionStart, selectionEnd]; |
| 2681 | + }; |
| 2682 | + if (!vim.visualMode) { |
| 2683 | + // In case of replaying the action. |
| 2684 | + return getLastSelectedAreaRange(); |
2638 | 2685 | } else { |
2639 | | - if (cursorIsBefore(selectionEnd, selectionStart)) { |
2640 | | - var tmp = selectionStart; |
2641 | | - selectionStart = selectionEnd; |
2642 | | - selectionEnd = tmp; |
2643 | | - } |
2644 | | - exitVisualMode(cm); |
| 2686 | + return getCurrentSelectedAreaRange(); |
2645 | 2687 | } |
2646 | | - return [selectionStart, selectionEnd]; |
2647 | 2688 | } |
2648 | 2689 | function updateLastSelection(cm, vim, selectionStart, selectionEnd) { |
2649 | 2690 | if (!selectionStart || !selectionEnd) { |
|
0 commit comments