Skip to content

Commit

Permalink
Update ID and rename files.
Browse files Browse the repository at this point in the history
  • Loading branch information
flengyel committed Jun 25, 2023
1 parent 8e07455 commit f49493f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 30 deletions.
13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
"group": "navigation"
}
],
"explorer/context": [
{
"command": "zettelView.renameEntry",
"when": "resourceExtname == .md",
"group": "1_modification"
}
],
"viewItem": [
{
"command": "zettelView.renameEntry",
Expand All @@ -58,11 +65,7 @@
},
{
"command": "zettelView.renameEntry",
"title": "Rename and replace links",
"icon": {
"light": "resources/light/rename.svg",
"dark": "resources/dark/rename.svg"
}
"title": "Rename and replace links"
}
],
"configuration": {
Expand Down
25 changes: 14 additions & 11 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as fs from 'fs';
import * as path from 'path';
import * as readline from 'readline';

import { myLogger,id } from './util';
import { myLogger,id, IDregex } from './util';
import { replaceLinks } from './replaceLinks';

class AsyncZettelViewTreeItem extends vscode.TreeItem {
Expand All @@ -19,7 +19,7 @@ class AsyncZettelViewTreeItem extends vscode.TreeItem {
public readonly command?: vscode.Command,
) {
super(basename, collapsibleState);
this.contextValue = "zettelItem"; // this is the key to the context menu
//this.contextValue = "zettelItem"; // this is the key to the context menu
this.label = basename; // assume the label is the basename

// myLogger.logMsg(`Regex: ${id.regex}`);
Expand All @@ -42,9 +42,9 @@ class AsyncZettelViewTreeItem extends vscode.TreeItem {

for await (const line of rl) {

//const match = line?.match(/^# ((\w{1,4}\.){2,}\d\w{3}) (.+)$/);
//const match = line?.match(/^# ((\w{1,4}\.){2,}\d\w{3})/);
// id is non-local
const match = id.re.exec(line);
const match = id.h1re.exec(line);
if (match) {
// check if basename == match[1].md
if (basename !== `${match[1]}.md`) {
Expand Down Expand Up @@ -117,6 +117,8 @@ class ZettelViewTreeDataProvider implements vscode.TreeDataProvider<AsyncZettelV
arguments: [vscode.Uri.file(path.join(this.workspaceRoot, file))],
}
);
// Set the contextValue
obj.contextValue = 'zettelItem';
return obj;
}
)();
Expand Down Expand Up @@ -149,25 +151,26 @@ export function activate(context: vscode.ExtensionContext): void {
vscode.commands.registerCommand('zettelView.renameEntry', async (node) => {

// Prompt the user for the new name
const newName = await vscode.window.showInputBox({ prompt: 'Enter the new ID' });

if (newName && node) {
// Validate the new name against the regex
if (!id.re.test(newName)) {
vscode.window.showErrorMessage('The new ID is invalid. Please try again.');
const newID = await vscode.window.showInputBox({ prompt: 'Enter the new ID' });
if (newID && node) {
// Validate the new ID against the regex
myLogger.logMsg(`New name: ${newID}`);
if (!id.idre.test(newID)) {
vscode.window.showErrorMessage(`The new ID ${newID} does not match ${id.idregex}. Please try again.`);
return;
}

try {
// Assume node.fsPath is the file path of the file to be renamed
const oldPath = node.fsPath;
//concatenate the new ID with the extension ".md"
const newName = `${newID}.md`;
const newPath = path.join(path.dirname(oldPath), newName);

// Rename the file
await fs.promises.rename(oldPath, newPath);

// Now find and replace all the links in the workspace
// Assume that we have a function findAndReplaceAllLinks(oldPath, newPath)
await replaceLinks(oldPath, newPath);

// Refresh the tree view
Expand Down
10 changes: 5 additions & 5 deletions src/replaceLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);

export async function replaceLinks(oldPath: string, newPath: string): Promise<void> {
const oldFilename = path.basename(oldPath, '.md');
const newFilename = path.basename(newPath, '.md');
const oldID = path.basename(oldPath, '.md');
const newID = path.basename(newPath, '.md');
const dirPath = path.dirname(oldPath);

// Get all markdown files in the root directory
Expand All @@ -24,10 +24,10 @@ export async function replaceLinks(oldPath: string, newPath: string): Promise<vo
const content = await readFile(filePath, 'utf-8');

// Create a regex to match the old filename
const regex = new RegExp(`\\[\\[${oldFilename}\\]\\]`, 'g');
const regex = new RegExp(`\\[\\[${oldID}\\]\\]`, 'g');

// Replace the old filename with the new filename
const newContent = content.replace(regex, `[[${newFilename}]]`);
// Replace the old ID with the new ID
const newContent = content.replace(regex, `[[${newID}]]`);

// Write the new content back to the file
await writeFile(filePath, newContent, 'utf-8');
Expand Down
25 changes: 16 additions & 9 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,27 @@ export class myLogger {

export class IDregex {
// The ID regex is a configuration contribution point, with a default value
private _re: RegExp; // save the compiled regex
private _regex: string; // save the pattern as a string
private _h1re: RegExp; // save the compiled regex
private _h1regex: string; // save the pattern as a string
private _idre: RegExp; // save the compiled regex
private _idregex: string; // save the first pattern group as a string
constructor() {
const regex = vscode.workspace.getConfiguration().get('zettelView.regex');
this._regex = regex as string;
if (!this._regex) {
this._regex = '^# ((\\w{1,4}\\.){2,}\\d\\w{3}) (.+)$'; // set the default regex if undefined
vscode.window.showInformationMessage(`No regex found in settings. Using default: ${this._regex}`);
this._h1regex = regex as string;
if (!this._h1regex) {
this._h1regex = '^# ((\\w{1,4}\\.){2,}\\d\\w{3})'; // set the default regex if undefined
vscode.window.showInformationMessage(`No regex found in settings. Using default: ${this._h1regex}`);
}
this._re = new RegExp(this._regex);
this._h1re = new RegExp(this._h1regex);
this._idregex = this._h1re.source.slice(3); // remove the ^# from the front
this._idre = new RegExp(this._idregex);

}

get re(): RegExp { return this._re; }
get regex(): string { return this._regex; }
get h1re(): RegExp { return this._h1re; }
get h1regex(): string { return this._h1regex; }
get idre(): RegExp { return this._idre; }
get idregex(): string { return this._idregex; }
}

// sadly, an object for compiled RegExp is needed by each ZettelViewTreeItem
Expand Down

0 comments on commit f49493f

Please sign in to comment.