(cm, head, repeat, dir, inclusive)
| 12752 | } |
| 12753 | |
| 12754 | function findParagraph(cm, head, repeat, dir, inclusive) { |
| 12755 | var line = head.line; |
| 12756 | var min = cm.firstLine(); |
| 12757 | var max = cm.lastLine(); |
| 12758 | var start, end, i = line; |
| 12759 | function isEmpty(i) { return !cm.getLine(i); } |
| 12760 | function isBoundary(i, dir, any) { |
| 12761 | if (any) { return isEmpty(i) != isEmpty(i + dir); } |
| 12762 | return !isEmpty(i) && isEmpty(i + dir); |
| 12763 | } |
| 12764 | if (dir) { |
| 12765 | while (min <= i && i <= max && repeat > 0) { |
| 12766 | if (isBoundary(i, dir)) { repeat--; } |
| 12767 | i += dir; |
| 12768 | } |
| 12769 | return new Pos(i, 0); |
| 12770 | } |
| 12771 | |
| 12772 | var vim = cm.state.vim; |
| 12773 | if (vim.visualLine && isBoundary(line, 1, true)) { |
| 12774 | var anchor = vim.sel.anchor; |
| 12775 | if (isBoundary(anchor.line, -1, true)) { |
| 12776 | if (!inclusive || anchor.line != line) { |
| 12777 | line += 1; |
| 12778 | } |
| 12779 | } |
| 12780 | } |
| 12781 | var startState = isEmpty(line); |
| 12782 | for (i = line; i <= max && repeat; i++) { |
| 12783 | if (isBoundary(i, 1, true)) { |
| 12784 | if (!inclusive || isEmpty(i) != startState) { |
| 12785 | repeat--; |
| 12786 | } |
| 12787 | } |
| 12788 | } |
| 12789 | end = new Pos(i, 0); |
| 12790 | // select boundary before paragraph for the last one |
| 12791 | if (i > max && !startState) { startState = true; } |
| 12792 | else { inclusive = false; } |
| 12793 | for (i = line; i > min; i--) { |
| 12794 | if (!inclusive || isEmpty(i) == startState || i == line) { |
| 12795 | if (isBoundary(i, -1, true)) { break; } |
| 12796 | } |
| 12797 | } |
| 12798 | start = new Pos(i, 0); |
| 12799 | return { start: start, end: end }; |
| 12800 | } |
| 12801 | |
| 12802 | // TODO: perhaps this finagling of start and end positions belonds |
| 12803 | // in codemirror/replaceRange? |
no test coverage detected