|
1 | | -import App, { SuggestModal, TFile } from "obsidian" |
| 1 | +import App, { SuggestModal, TFile } from 'obsidian' |
| 2 | +import * as PathHelper from 'src/utils/path-helper' |
2 | 3 |
|
3 | 4 | export class FileNameModal extends SuggestModal<string> { |
4 | 5 | parentPath: string |
@@ -37,29 +38,70 @@ export class FileNameModal extends SuggestModal<string> { |
37 | 38 | } |
38 | 39 | } |
39 | 40 |
|
40 | | -export class FileSelectModal extends SuggestModal<TFile> { |
41 | | - files: TFile[] |
| 41 | +export class FileSelectModal extends SuggestModal<string> { |
| 42 | + files: string[] |
| 43 | + suggestNewFile: boolean |
42 | 44 |
|
43 | | - constructor(app: App, extensionsRegex: string) { |
| 45 | + constructor(app: App, extensionsRegex?: RegExp, suggestNewFile: boolean = false) { |
44 | 46 | super(app) |
45 | 47 |
|
46 | | - this.files = this.app.vault.getFiles().filter(f => f.path.match(new RegExp(extensionsRegex))) |
| 48 | + this.files = this.app.vault.getFiles() |
| 49 | + .map(file => file.path) |
| 50 | + .filter(path => PathHelper.extension(path)?.match(extensionsRegex ?? /.*/)) |
| 51 | + this.suggestNewFile = suggestNewFile |
| 52 | + |
| 53 | + this.setPlaceholder('Type to search...') |
| 54 | + this.setInstructions([{ |
| 55 | + command: '↑↓', |
| 56 | + purpose: 'to navigate' |
| 57 | + }, { |
| 58 | + command: '↵', |
| 59 | + purpose: 'to open' |
| 60 | + }, { |
| 61 | + command: 'shift ↵', |
| 62 | + purpose: 'to create' |
| 63 | + }, { |
| 64 | + command: 'esc', |
| 65 | + purpose: 'to dismiss' |
| 66 | + }]) |
| 67 | + |
| 68 | + this.scope.register(['Shift'], 'Enter', ((e) => { |
| 69 | + this.onChooseSuggestion(this.inputEl.value, e) |
| 70 | + this.close() |
| 71 | + })) |
47 | 72 | } |
48 | 73 |
|
49 | | - getSuggestions(query: string): TFile[] { |
50 | | - return this.files |
51 | | - .filter(f => f.name.toLowerCase().includes(query.toLowerCase())) |
| 74 | + getSuggestions(query: string): string[] { |
| 75 | + const suggestions = this.files.filter(path => path.toLowerCase().includes(query.toLowerCase())) |
| 76 | + if (suggestions.length === 0 && this.suggestNewFile) suggestions.push(query) |
| 77 | + |
| 78 | + return suggestions |
52 | 79 | } |
53 | 80 |
|
54 | | - renderSuggestion(file: TFile, el: HTMLElement) { |
55 | | - el.setText(file.extension === 'md' ? file.basename : file.name) |
| 81 | + renderSuggestion(path: string, el: HTMLElement) { |
| 82 | + const simplifiedPath = path.replace(/\.md$/, '') |
| 83 | + el.setText(simplifiedPath) |
56 | 84 | } |
57 | 85 |
|
58 | | - onChooseSuggestion(_file: TFile, _evt: MouseEvent | KeyboardEvent) {} |
| 86 | + onChooseSuggestion(_path: string, _evt: MouseEvent | KeyboardEvent) {} |
59 | 87 |
|
60 | 88 | awaitInput(): Promise<TFile> { |
61 | 89 | return new Promise((resolve, _reject) => { |
62 | | - this.onChooseSuggestion = (file: TFile) => { resolve(file) } |
| 90 | + this.onChooseSuggestion = (path: string, _evt: MouseEvent | KeyboardEvent) => { |
| 91 | + const file = this.app.vault.getAbstractFileByPath(path) |
| 92 | + |
| 93 | + if (file instanceof TFile) { |
| 94 | + resolve(file) |
| 95 | + return |
| 96 | + } |
| 97 | + |
| 98 | + if (!this.suggestNewFile) return |
| 99 | + |
| 100 | + if (PathHelper.extension(path) === undefined) path += '.md' |
| 101 | + const newFile = this.app.vault.create(path, '') |
| 102 | + resolve(newFile) |
| 103 | + } |
| 104 | + |
63 | 105 | this.open() |
64 | 106 | }) |
65 | 107 | } |
|
0 commit comments