Skip to content

Commit

Permalink
Replace entire term instead of leaving replaced tail in text #163
Browse files Browse the repository at this point in the history
  • Loading branch information
Egor Stambakio committed Aug 19, 2019
1 parent 77f977b commit 83407ad
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import clickOutside from 'react-click-outside';
import AutocompleteWidget from './AutocompleteWidget';
import { getSlateEditor } from '../../utils';
import { getAccents, getPosAfterEmphasis } from '../../slate/transforms';
import { matchUnderCursor } from './utils';

const escapeCode = 27;
const arrowUpCode = 38;
Expand Down Expand Up @@ -170,7 +171,18 @@ class AutocompleteContainer extends PureComponent {

if (extension && item) {
const change = state.change();
change.deleteBackward(term.length).insertText(extension.markdownText(item, term)).focus();

const text = change.anchorText.text
const cursor = change.anchorOffset;

const { start, end } = matchUnderCursor({ text, cursor, regexp: extension.termRegex });

change.
deleteBackward(cursor - start).
deleteForward(end - cursor).
insertText(extension.markdownText(item, term)).
focus();

this.props.onChange(change.state, true);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const matchUnderCursor = ({ text, regexp, cursor }) => {
const result = {
match: '',
start: cursor,
end: cursor
}

for (let start = cursor; start >= 0; start--) {
for (let end = cursor; end <= text.length; end++) {
const chunk = text.slice(start, end);
if (regexp.test(chunk) && chunk.length > result.match.length) {
result.match = chunk;
result.start = start;
result.end = end;
}
}
}

return result;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { expect } from 'chai';

import { matchUnderCursor } from './utils';

describe('matchUnderCursor', () => {
it('should find regexp match under cursor', () => {
const regexp = /^\$(\w*)$/;

const tests = [
// returns match under cursor
{
args: { text: 'abc $def ghi $jkl mno', regexp, cursor: 5 },
want: { match: '$def', start: 4, end: 8 }
},
{
args: { text: 'abc $def ghi $jkl mno', regexp, cursor: 14 },
want: { match: '$jkl', start: 13, end: 17 }
},
// move cursor left to right to test all cases
...('abc $def ghi'.split('').reduce((acc, ch, cursor) => {
return [
...acc,
{
args: { text: 'abc $def ghi', regexp, cursor },
...(
// if cursor is out of match then return empty match
(cursor < 4 || cursor > 8) ?
{ want: { match: '', start: cursor, end: cursor } } :
// if cursor is on (or on edges of) match then return match and its boundaries
{ want: { match: '$def', start: 4, end: 8 } }
)
}
]
}, []))
]

tests.forEach(({ args, want }) => {
const got = matchUnderCursor(args)
expect(got).to.deep.equal(want, `input: ${JSON.stringify(args)}`)
})
})
})

0 comments on commit 83407ad

Please sign in to comment.