Skip to content

Commit

Permalink
update README. modify wordPattern so completion works for relativePat…
Browse files Browse the repository at this point in the history
…hs and cmd+shift+f tag search works
  • Loading branch information
kortina committed Feb 20, 2020
1 parent 9f03a3e commit 00b0ac9
Show file tree
Hide file tree
Showing 14 changed files with 91 additions and 53 deletions.
1 change: 1 addition & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.vscode-test/**
.gitignore
vsc-extension-quickstart.md
demo/**
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,47 @@ A popular feature in [Roam Research](https://roamresearch.com/) and [Bear](https

VS Code Markdown notes provides syntax highlighting, auto-complete, Go to Definition (`editor.action.revealDefinition`), and Peek Definition (`editor.action.peekDefinition`) support for wiki-links to notes in a workspace.

... TODO - screenshots ...

By default, the extension assumes each markdown file in a workspace has a unique name, so that `note.md` will resolve to the file with this name, regardless of whether or not this file exists in any subdirectory path. This tends to be a bit cleaner, but if you want support for multiple files with the same name, in `settings.json` set `"vscodeMarkdownNotes.workspaceFilenameConvention": "relativePaths"`, and you'll get completions like `note1/note.md` and `../note2/note.md`.

### Screenshots

#### Intellisense Completion for Wiki Links, `uniqueFilenames`

![completion-unique-filenames](demo/completion-unique-filenames.gif)

#### Intellisense Completion for Wiki Links, `relativePaths`

![completion-relative-paths](demo/completion-unique-relative-paths.gif)

#### Syntax Highlighting for Tags and Wiki Links

![syntax-highlighting](demo/syntax-highlighting.png)

#### Peek and Go to Definition for Wiki Links

![peek-and-to-to-definition](demo/peek-and-go-to-definition.gif)

#### `cmd+shift+f` to Search Workspace for Notes with #tag

![tag-search](demo/tag-search.gif)

## dev

Run `npm install` first.

### Known Issues

- The `ctrl+o` VSCodeVim jumplist shortcut does not return you to the correct place after using "Go to Definition" (`ctrl+]`): https://github.com/VSCodeVim/Vim/issues/3277 (The VSCode `Go Back` command (`ctrl+-`) does work, however.)
- This extension sets the `wordPattern` for 'markdown' in order to (1) enable proper completion of relative paths and (2) make it such that if you `cmd+shift+f` on a `#tag` the search will prefill with "#tag" and not just "tag":
<br />`vscode.languages.setLanguageConfiguration('markdown', { wordPattern: /([\#\.\/\\\w_]+)/ });`

### TODO

- Provide better support for ignore patterns, eg, don't complete `file.md` if it is within `ignored_dir/`
- Should we support filename without extension, eg, assume `[[file]]` is a reference to `file.md`?
- Should we support links to headings? eg, `file.md#heading-text`?
- Add syntax highlighting and search for `#tags`. See [also](https://stackoverflow.com/questions/60293955/is-cmdshiftf-in-vscode-supposed-to-respect-the-editor-wordseparators-setting)
- command to create file based on name in the wiki-link under the cursor

### Development and Release

Expand Down
Binary file added demo/completion-relative-paths.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/completion-unique-filenames.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/peek-and-go-to-definition.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/syntax-highlighting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/tag-search.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 30 additions & 29 deletions language-configuration.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
{
"comments": {
// symbol used for single line comment. Remove this entry if your language does not support line comments
"lineComment": "//",
// symbols used for start and end a block comment. Remove this entry if your language does not support block comments
"blockComment": [ "/*", "*/" ]
},
// symbols used as brackets
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
],
// symbols that are auto closed when typing
"autoClosingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""],
["'", "'"]
],
// symbols that that can be used to surround a selection
"surroundingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""],
["'", "'"]
]
}
// "wordPattern": "([\\.\\w_]+)", // https://github.com/microsoft/vscode/issues/42649 - must do this in `activate`
"comments": {
// symbol used for single line comment. Remove this entry if your language does not support line comments
"lineComment": "//",
// symbols used for start and end a block comment. Remove this entry if your language does not support block comments
"blockComment": ["/*", "*/"]
},
// symbols used as brackets
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
],
// symbols that are auto closed when typing
"autoClosingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""],
["'", "'"]
],
// symbols that that can be used to surround a selection
"surroundingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["\"", "\""],
["'", "'"]
]
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@
"title": "Run in Terminal Configuration",
"properties": {
"vscodeMarkdownNotes.workspaceFilenameConvention": {
"type": "enum",
"type": "string",
"enum": [
"uniqueFilenames",
"relativePaths"
],
"default": "uniqueFilenames",
"description": "By default, expect `uniqueFilenames` for every `.md` file in workspace and treat `file.md` as link to file in any subdirectory. If you expect collisions in filenames for notes (eg, `note1/note.md` `note2/note.md`) use `relativePaths` to render links between files."
"description": "By default, expect 'uniqueFilenames' for every `.md` file in workspace and treat `file.md` as link to file in any subdirectory. If you expect collisions in filenames for notes (eg, `note1/note.md` `note2/note.md`) use 'relativePaths' to render links between files."
}
}
}
Expand Down
40 changes: 23 additions & 17 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { basename, dirname, join, normalize, relative, resolve } from 'path';
import { basename, dirname, normalize, relative, resolve } from 'path';
import { existsSync } from 'fs';
import {
CompletionItemProvider,
Expand All @@ -8,23 +8,25 @@ import {
CancellationToken,
CompletionContext,
workspace,
Range,
CompletionItem,
commands,
CompletionItemKind,
TextEdit,
DocumentSymbol,
Uri,
} from 'vscode';

function uniqueFilenamesConfiguration(): boolean {
function workspaceFilenameConvention(): string | undefined {
let cfg = vscode.workspace.getConfiguration('vscodeMarkdownNotes');
let convention = cfg.get('workspaceFilenameConvention');
return convention == 'uniqueFilenames';
return cfg.get('workspaceFilenameConvention');
}
function useUniqueFilenames(): boolean {
return workspaceFilenameConvention() == 'uniqueFilenames';
}

function useRelativePaths(): boolean {
return workspaceFilenameConvention() == 'relativePaths';
}

function filenameForConvention(uri: Uri, fromDocument: TextDocument): string {
if (uniqueFilenamesConfiguration()) {
if (useUniqueFilenames()) {
return basename(uri.path);
} else {
let toPath = uri.path;
Expand Down Expand Up @@ -93,10 +95,10 @@ class MarkdownFileCompletionItemProvider implements CompletionItemProvider {
_token: CancellationToken,
context: CompletionContext
) {
// console.debug('provideCompletionItems');
console.debug('provideCompletionItems');
const contextWord = getContextWord(document, position);
if (contextWord.type != ContextWordType.WikiLink) {
// console.debug('getContextWord was not WikiLink');
console.debug('getContextWord was not WikiLink');
return [];
}

Expand All @@ -121,31 +123,31 @@ class MarkdownDefinitionProvider implements vscode.DefinitionProvider {
position: vscode.Position,
token: vscode.CancellationToken
) {
// console.debug('provideDefinition');
console.debug('provideDefinition');

const contextWord = getContextWord(document, position);
if (contextWord.type != ContextWordType.WikiLink) {
// console.debug('getContextWord was not WikiLink');
console.debug('getContextWord was not WikiLink');
return [];
}
if (!contextWord.hasExtension) {
// console.debug('getContextWord does not have file extension');
console.debug('getContextWord does not have file extension');
return [];
}

// TODO: parameterize extensions. return if we don't have a filename and we require extensions
// const markdownFileRegex = /[\w\.\-\_\/\\]+\.(md|markdown)/i;
const selectedWord = contextWord.word;
// console.debug('selectedWord', selectedWord);
console.debug('selectedWord', selectedWord);
let files: Array<Uri> = [];
// selectedWord might be either:
// a basename for a unique file in the workspace
// or, a relative path to a file
// Since, selectedWord is just a string of text from a document,
// there is no guarantee uniqueFilenamesConfiguration will tell us
// there is no guarantee useUniqueFilenames will tell us
// it is not a relative path.
// However, only check for basenames in the entire project if:
if (uniqueFilenamesConfiguration()) {
if (useUniqueFilenames()) {
const filename = selectedWord;
// there should be exactly 1 file with name = selecteWord
files = (await workspace.findFiles('**/*')).filter(f => {
Expand All @@ -172,6 +174,10 @@ class MarkdownDefinitionProvider implements vscode.DefinitionProvider {
export function activate(context: vscode.ExtensionContext) {
console.debug('vscode-markdown-notes.activate');
const md = { scheme: 'file', language: 'markdown' };
vscode.languages.setLanguageConfiguration('markdown', { wordPattern: /([\#\.\/\\\w_]+)/ });

// const triggerCharacters = ['.', '#'];
// const triggerCharacters = [];
context.subscriptions.push(
vscode.languages.registerCompletionItemProvider(md, new MarkdownFileCompletionItemProvider())
);
Expand Down
7 changes: 7 additions & 0 deletions test/sub/demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Demo

`⌥F12` (Peek Definition) to preview Wiki Link inline

`F12` (Go to Definition) to open Wiki Link

[[sub.md]]
2 changes: 1 addition & 1 deletion test/sub/sub2.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# sub2

[[sub.md]]
[[demo.md]]
4 changes: 2 additions & 2 deletions test/test.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test #tag
# test

- [[test]] - no extension
- [[test.md]] - extension, exists
Expand All @@ -7,4 +7,4 @@
- [[./sub/sub.md]] - relative path, exists
- [[sub.md]] - exists in sub directory

#tag #tag2
#tag #another_tag
Empty file added test/top.md
Empty file.

0 comments on commit 00b0ac9

Please sign in to comment.