| 1532 | } |
| 1533 | |
| 1534 | function expandWordUnderCursor(cm, inclusive, forward, bigWord, noSymbol) { |
| 1535 | var cur = cm.getCursor(); |
| 1536 | var line = cm.getLine(cur.line); |
| 1537 | var idx = cur.ch; |
| 1538 | |
| 1539 | // Seek to first word or non-whitespace character, depending on if |
| 1540 | // noSymbol is true. |
| 1541 | var textAfterIdx = line.substring(idx); |
| 1542 | var firstMatchedChar; |
| 1543 | if (noSymbol) { |
| 1544 | firstMatchedChar = textAfterIdx.search(/\w/); |
| 1545 | } else { |
| 1546 | firstMatchedChar = textAfterIdx.search(/\S/); |
| 1547 | } |
| 1548 | if (firstMatchedChar == -1) { |
| 1549 | return null; |
| 1550 | } |
| 1551 | idx += firstMatchedChar; |
| 1552 | textAfterIdx = line.substring(idx); |
| 1553 | var textBeforeIdx = line.substring(0, idx); |
| 1554 | |
| 1555 | var matchRegex; |
| 1556 | // Greedy matchers for the "word" we are trying to expand. |
| 1557 | if (bigWord) { |
| 1558 | matchRegex = /^\S+/; |
| 1559 | } else { |
| 1560 | if ((/\w/).test(line.charAt(idx))) { |
| 1561 | matchRegex = /^\w+/; |
| 1562 | } else { |
| 1563 | matchRegex = /^[^\w\s]+/; |
| 1564 | } |
| 1565 | } |
| 1566 | |
| 1567 | var wordAfterRegex = matchRegex.exec(textAfterIdx); |
| 1568 | var wordStart = idx; |
| 1569 | var wordEnd = idx + wordAfterRegex[0].length - 1; |
| 1570 | // TODO: Find a better way to do this. It will be slow on very long lines. |
| 1571 | var wordBeforeRegex = matchRegex.exec(reverse(textBeforeIdx)); |
| 1572 | if (wordBeforeRegex) { |
| 1573 | wordStart -= wordBeforeRegex[0].length; |
| 1574 | } |
| 1575 | |
| 1576 | if (inclusive) { |
| 1577 | wordEnd++; |
| 1578 | } |
| 1579 | |
| 1580 | return { start: { line: cur.line, ch: wordStart }, |
| 1581 | end: { line: cur.line, ch: wordEnd }}; |
| 1582 | } |
| 1583 | |
| 1584 | /* |
| 1585 | * Returns the boundaries of the next word. If the cursor in the middle of |