refactor and improve selectTokenOnDoubleclick logic

This commit is contained in:
tophf 2017-12-23 04:42:20 +03:00
parent a249167539
commit 8c96165fb4

View File

@ -168,44 +168,52 @@
function selectTokenOnDoubleclick(cm, pos) { function selectTokenOnDoubleclick(cm, pos) {
let {ch} = pos; let {ch} = pos;
const {line} = pos; const {line, sticky} = pos;
const text = cm.getLine(line); const {text, styles} = cm.getLineHandle(line);
const type = cm.getTokenTypeAt(pos) ||
cm.getTokenTypeAt({line, ch: ch += 1}) || const execAt = (rx, i) => (rx.lastIndex = i) && null || rx.exec(text);
cm.getTokenTypeAt({line, ch: ch -= 2}); const at = (rx, i) => (rx.lastIndex = i) && null || rx.test(text);
const atWord = ch => at(/\w/uy, ch);
const atSpace = ch => at(/\s/uy, ch);
const atTokenEnd = styles.indexOf(ch, 1);
ch += atTokenEnd < 0 ? 0 : sticky === 'before' && atWord(ch - 1) ? 0 : atSpace(ch + 1) ? 0 : 1;
ch = Math.min(text.length, ch);
const type = cm.getTokenTypeAt({line, ch: ch + (sticky === 'after' ? 1 : 0)});
if (atTokenEnd > 0) ch--;
const isCss = type && !/^(comment|string)/.test(type); const isCss = type && !/^(comment|string)/.test(type);
const isNumber = type === 'number'; const isNumber = type === 'number';
const isSpace = atSpace(ch);
let wordChars =
isNumber ? /[-+\w.]/uy :
isCss ? /[-\w@]/uy :
isSpace ? /\s/uy :
atWord(ch) ? /\w/uy : /[^\w\s]/uy;
let wordChars = isNumber ? /[-+\w.]/uy : isCss ? /[-\w]/uy : /\w/uy; let a = ch;
let i = ch; while (a && at(wordChars, a)) a--;
while (i >= 0) { a += !a && at(wordChars, a) || isCss && at(/[.!#@]/uy, a) ? 0 : at(wordChars, a + 1);
wordChars.lastIndex = i;
if (!wordChars.test(text)) break; let b, found;
i--;
}
i += !i && wordChars.test(text[i]) || /[.!#]/.test(text[i]) ? 0 : 1;
let j;
if (isNumber) { if (isNumber) {
const numChars = /[+-]?[\d.]+(e\d+)?|$/uyi; b = a + execAt(/[+-]?[\d.]+(e\d+)?|$/uyi, a)[0].length;
numChars.lastIndex = i; found = b >= ch;
j = i + numChars.exec(text)[0].length; if (!found) {
if (j >= ch) { a = b;
return { ch = a;
from: {line, ch: i},
to: {line, ch: j},
};
} }
i = j;
ch = i;
} }
wordChars = isCss ? /[-\w]*/uy : /\w*/uy;
wordChars.lastIndex = ch; if (!found) {
j = ch + wordChars.exec(text)[0].length; wordChars = isCss ? /[-\w]*/uy : new RegExp(wordChars.source + '*', 'uy');
b = ch + execAt(wordChars, ch)[0].length;
}
return { return {
from: {line, ch: i}, from: {line, ch: a},
to: {line, ch: j}, to: {line, ch: b},
}; };
} }
})(); })();