Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions src/core/Templater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,41 @@ export class Templater {
}
}

get_templates_folders(): Array<string> {
let template_folders: Array<string>;
if (this.plugin.settings.enable_multiple_template_folders) {
template_folders = this.plugin.settings.templates_folders;
} else {
template_folders = [this.plugin.settings.templates_folder];
}

return template_folders.filter((folder: string) => folder !== "");
}

get_templates_folders_shared_path(): string {
if (this.plugin.templater.get_templates_folders().length === 0) {
return "";
}

let common_template_folder_path = this.plugin.templater
.get_templates_folders()
.reduce((shared_path: string, folder: string) => {
let i = 0;
while (i < Math.min(shared_path.length, folder.length)) {
if (shared_path[i] != folder[i]) {
break;
}
i++;
}
return folder.substring(0, i);
});
common_template_folder_path = common_template_folder_path.substring(
0,
common_template_folder_path.lastIndexOf("/")
);
return common_template_folder_path;
}

static async on_file_creation(
templater: Templater,
app: App,
Expand All @@ -472,10 +507,16 @@ export class Templater {
}

// Avoids template replacement when syncing template files
const template_folder = normalizePath(
templater.plugin.settings.templates_folder
);
if (file.path.includes(template_folder) && template_folder !== "/") {
if (
templater
.get_templates_folders()
.map(normalizePath)
.some(
(template_folder: string) =>
file.path.includes(template_folder) &&
template_folder !== "/"
)
) {
return;
}

Expand Down
40 changes: 21 additions & 19 deletions src/handlers/FuzzySuggester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,37 @@ export class FuzzySuggester extends FuzzySuggestModal<TFile> {
}

getItems(): TFile[] {
if (!this.plugin.settings.templates_folder) {
if (this.plugin.templater.get_templates_folders().length === 0) {
return this.app.vault.getMarkdownFiles();
}
const files = errorWrapperSync(
() =>
get_tfiles_from_folder(
this.plugin.app,
this.plugin.settings.templates_folder
),
`Couldn't retrieve template files from templates folder ${this.plugin.settings.templates_folder}`
);
if (!files) {
return [];
}

const files = this.plugin.templater
.get_templates_folders()
.map((folder: string) => {
return errorWrapperSync(
() => get_tfiles_from_folder(this.plugin.app, folder),
`Couldn't retrieve template files from templates folder ${folder}`
);
})
.flat();

return files;
}

getItemText(item: TFile): string {
const templates_folders_shared_path =
this.plugin.templater.get_templates_folders_shared_path();
let relativePath = item.path;
if (
item.path.startsWith(this.plugin.settings.templates_folder) &&
normalizePath(this.plugin.settings.templates_folder) != "/"
item.path.startsWith(templates_folders_shared_path) &&
normalizePath(templates_folders_shared_path) != "/"
) {
// Modify splice position if folder has a trailing slash
const folderLength = this.plugin.settings.templates_folder.length
const position = this.plugin.settings.templates_folder.endsWith('/') ? folderLength : folderLength + 1
relativePath = item.path.slice(
position
);
const folderLength = templates_folders_shared_path.length;
const position = templates_folders_shared_path.endsWith("/")
? folderLength
: folderLength + 1;
relativePath = item.path.slice(position);
}
return relativePath.split(".").slice(0, -1).join(".");
}
Expand Down
164 changes: 162 additions & 2 deletions src/settings/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export interface FileTemplate {

export const DEFAULT_SETTINGS: Settings = {
command_timeout: 5,
enable_multiple_template_folders: false,
templates_folder: "",
templates_folders: [""],
templates_pairs: [["", ""]],
trigger_on_file_creation: false,
auto_jump_to_cursor: false,
Expand All @@ -37,7 +39,9 @@ export const DEFAULT_SETTINGS: Settings = {

export interface Settings {
command_timeout: number;
enable_multiple_template_folders: boolean;
templates_folder: string;
templates_folders: Array<string>;
templates_pairs: Array<[string, string]>;
trigger_on_file_creation: boolean;
auto_jump_to_cursor: boolean;
Expand All @@ -62,7 +66,12 @@ export class TemplaterSettingTab extends PluginSettingTab {
display(): void {
this.containerEl.empty();

this.add_template_folder_setting();
if (this.plugin.settings.enable_multiple_template_folders) {
this.add_multiple_template_folder_setting();
} else {
this.add_template_folder_setting();
}
this.add_toggle_allow_multiple_template_folders();
this.add_internal_functions_setting();
this.add_syntax_highlighting_settings();
this.add_auto_jump_to_cursor();
Expand All @@ -78,6 +87,157 @@ export class TemplaterSettingTab extends PluginSettingTab {
this.add_donating_setting();
}

add_toggle_allow_multiple_template_folders(): void {
const desc = document.createDocumentFragment();
desc.append(
"Adds support for having multiple distinct template folders"
);

new Setting(this.containerEl)
.setName("Multiple Template Folders")
.setDesc(desc)
.addToggle((toggle) => {
toggle
.setValue(
this.plugin.settings.enable_multiple_template_folders
)
.onChange((allow_multiple_template_folders) => {
this.plugin.settings.enable_multiple_template_folders =
allow_multiple_template_folders;
this.plugin.save_settings();
// Force refresh
this.display();
});
});
}

add_multiple_template_folder_setting(): void {
new Setting(this.containerEl).setName("Template Folders").setHeading();

const desc = document.createDocumentFragment();
desc.append("Files in these folders will be available as templates.");

new Setting(this.containerEl).setDesc(desc);

this.plugin.settings.templates_folders.forEach(
(template_folder, index) => {
const s = new Setting(this.containerEl)
.addSearch((cb) => {
new FolderSuggest(this.app, cb.inputEl);
cb.setPlaceholder("Example: folder1/folder2")
.setValue(template_folder)
.onChange((new_folder) => {
// Trim folder and Strip ending slash if there
new_folder = new_folder.trim();
new_folder = new_folder.replace(/\/$/, "");

const new_folders = [
...this.plugin.settings.templates_folders,
];
new_folders.splice(index, 1);

if (
new_folder &&
new_folders.contains(new_folder)
) {
log_error(
new TemplaterError(
"This folder is already a template folder"
)
);
// Force refresh so you don't see "ghost"
// folder selection.
this.display();
return;
}

if (
new_folder &&
new_folders
.filter(
(folder: string) => folder !== ""
)
.some(
(folder: string) =>
new_folder.startsWith(
folder + "/"
) ||
folder.startsWith(
new_folder + "/"
)
)
) {
log_error(
new TemplaterError(
"No folder can be parent/child of other template folders"
)
);
this.display();
return;
}

this.plugin.settings.templates_folders[index] =
new_folder;
this.plugin.save_settings();
});
// @ts-ignore
cb.containerEl.addClass("templater_search");
})
.addExtraButton((cb) => {
cb.setIcon("up-chevron-glyph")
.setTooltip("Move up")
.onClick(() => {
arraymove(
this.plugin.settings.templates_folders,
index,
index - 1
);
this.plugin.save_settings();
this.display();
});
})
.addExtraButton((cb) => {
cb.setIcon("down-chevron-glyph")
.setTooltip("Move down")
.onClick(() => {
arraymove(
this.plugin.settings.templates_folders,
index,
index + 1
);
this.plugin.save_settings();
this.display();
});
})
.addExtraButton((cb) => {
cb.setIcon("cross")
.setTooltip("Delete")
.onClick(() => {
this.plugin.settings.templates_folders.splice(
index,
1
);
this.plugin.save_settings();
// Force refresh
this.display();
});
});
s.infoEl.remove();
}
);

new Setting(this.containerEl).addButton((cb) => {
cb.setButtonText("Add new folder for templates")
.setCta()
.onClick(() => {
this.plugin.settings.templates_folders.push("");
this.plugin.save_settings();
// Force refresh
this.display();
});
});
}

add_template_folder_setting(): void {
new Setting(this.containerEl)
.setName("Template folder location")
Expand All @@ -88,7 +248,7 @@ export class TemplaterSettingTab extends PluginSettingTab {
.setValue(this.plugin.settings.templates_folder)
.onChange((new_folder) => {
// Trim folder and Strip ending slash if there
new_folder = new_folder.trim()
new_folder = new_folder.trim();
new_folder = new_folder.replace(/\/$/, "");

this.plugin.settings.templates_folder = new_folder;
Expand Down