mirror of
https://github.com/foambubble/foam.git
synced 2026-01-10 06:28:12 -05:00
Update regex for more robust detection of tags
Update the regex used for more robust detection of tags. Replace the
negative lookahead assertion `\s` with `[ \t]` (allow for `\n`), and
add `#` to the class so that `##` is ignored.
Attempted to add the negation `^[0-9p{L}p{Emoji}p{N}-/]` to the
negative look ahead. This was to exclude items like `#$`, `#&` that
can't be tags. However my regex-fu was insufficient.
Instead, if the regex match is to a single `#`, ensure it is the
character to the left of the cursor. Example
`this is text #%|`
where the `|` represents the cursor. The `TAG_REGEX`
will match the `#` at index 13. However since the cursor is at 15, the
Completion provider will not run.
Update the tests to cover these situations and add them all to a sub-
`describe` block labeled by the bug issue number #1189
This commit is contained in:
@@ -66,36 +66,6 @@ describe('Tag Completion', () => {
|
||||
expect(tags).toBeNull();
|
||||
});
|
||||
|
||||
it('should provide multiple suggestions when typing #, issue #1189', async () => {
|
||||
const { uri } = await createFile(`# Title
|
||||
|
||||
#`);
|
||||
const { doc } = await showInEditor(uri);
|
||||
const provider = new TagCompletionProvider(foamTags);
|
||||
|
||||
const tags = await provider.provideCompletionItems(
|
||||
doc,
|
||||
new vscode.Position(2, 1)
|
||||
);
|
||||
expect(tags.items.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should not provide a suggestion when typing `# `, issue #1189', async () => {
|
||||
const { uri } = await createFile(`# Title
|
||||
|
||||
# `);
|
||||
const { doc } = await showInEditor(uri);
|
||||
const provider = new TagCompletionProvider(foamTags);
|
||||
|
||||
const tags = await provider.provideCompletionItems(
|
||||
doc,
|
||||
new vscode.Position(2, 2)
|
||||
);
|
||||
|
||||
expect(foamTags.tags.get('primary')).toBeTruthy();
|
||||
expect(tags).toBeNull();
|
||||
});
|
||||
|
||||
it('should provide a suggestion when typing #prim', async () => {
|
||||
const { uri } = await createFile('#prim');
|
||||
const { doc } = await showInEditor(uri);
|
||||
@@ -137,4 +107,84 @@ describe('Tag Completion', () => {
|
||||
expect(foamTags.tags.get('primary')).toBeTruthy();
|
||||
expect(tags).toBeNull();
|
||||
});
|
||||
|
||||
describe('has robust triggering #1189', () => {
|
||||
it('should provide multiple suggestions when typing #', async () => {
|
||||
const { uri } = await createFile(`# Title
|
||||
|
||||
#`);
|
||||
const { doc } = await showInEditor(uri);
|
||||
const provider = new TagCompletionProvider(foamTags);
|
||||
|
||||
const tags = await provider.provideCompletionItems(
|
||||
doc,
|
||||
new vscode.Position(2, 1)
|
||||
);
|
||||
expect(tags.items.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should provide multiple suggestions when typing # at EOL', async () => {
|
||||
const { uri } = await createFile(`# Title
|
||||
|
||||
#
|
||||
more text
|
||||
`);
|
||||
const { doc } = await showInEditor(uri);
|
||||
const provider = new TagCompletionProvider(foamTags);
|
||||
|
||||
const tags = await provider.provideCompletionItems(
|
||||
doc,
|
||||
new vscode.Position(2, 1)
|
||||
);
|
||||
expect(tags.items.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should not provide a suggestion when typing `# `', async () => {
|
||||
const { uri } = await createFile(`# Title
|
||||
|
||||
# `);
|
||||
const { doc } = await showInEditor(uri);
|
||||
const provider = new TagCompletionProvider(foamTags);
|
||||
|
||||
const tags = await provider.provideCompletionItems(
|
||||
doc,
|
||||
new vscode.Position(2, 2)
|
||||
);
|
||||
|
||||
expect(foamTags.tags.get('primary')).toBeTruthy();
|
||||
expect(tags).toBeNull();
|
||||
});
|
||||
|
||||
it('should not provide a suggestion when typing `#{non-match}`', async () => {
|
||||
const { uri } = await createFile(`# Title
|
||||
|
||||
#$`);
|
||||
const { doc } = await showInEditor(uri);
|
||||
const provider = new TagCompletionProvider(foamTags);
|
||||
|
||||
const tags = await provider.provideCompletionItems(
|
||||
doc,
|
||||
new vscode.Position(2, 2)
|
||||
);
|
||||
|
||||
expect(foamTags.tags.get('primary')).toBeTruthy();
|
||||
expect(tags).toBeNull();
|
||||
});
|
||||
|
||||
it('should not provide a suggestion when typing `##`', async () => {
|
||||
const { uri } = await createFile(`# Title
|
||||
|
||||
##`);
|
||||
const { doc } = await showInEditor(uri);
|
||||
const provider = new TagCompletionProvider(foamTags);
|
||||
|
||||
const tags = await provider.provideCompletionItems(
|
||||
doc,
|
||||
new vscode.Position(2, 2)
|
||||
);
|
||||
|
||||
expect(foamTags.tags.get('primary')).toBeTruthy();
|
||||
expect(tags).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ import { mdDocSelector } from '../utils';
|
||||
// this regex is different from HASHTAG_REGEX in that it does not look for a
|
||||
// #+character. It uses a negative look-ahead for `# `
|
||||
const TAG_REGEX =
|
||||
/(?<=^|\s)#(?!(\s+))([0-9]*[\p{L}\p{Emoji_Presentation}\p{N}/_-]*)/gmu;
|
||||
/(?<=^|\s)#(?![ \t#])([0-9]*[\p{L}\p{Emoji_Presentation}\p{N}/_-]*)/gu;
|
||||
|
||||
const feature: FoamFeature = {
|
||||
activate: async (
|
||||
@@ -44,6 +44,19 @@ export class TagCompletionProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
// check the match group length.
|
||||
// if the match is only '#', the character to the left of cursor should
|
||||
// also be `#`. If it isn't, we didn't match the
|
||||
// `[0-9]*[\p{L}\p{Emoji_Presentation}\p{N}/_-]` group
|
||||
// This excludes things like `#&`
|
||||
const matchText = requiresAutocomplete[requiresAutocomplete.length - 1];
|
||||
if (
|
||||
matchText === '#' &&
|
||||
cursorPrefix.charAt(position.character - 1) !== '#'
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const completionTags = [];
|
||||
[...this.foamTags.tags].forEach(([tag]) => {
|
||||
const item = new vscode.CompletionItem(
|
||||
|
||||
Reference in New Issue
Block a user