mirror of
https://github.com/ckelsoe/obsidian-shell-path-copy.git
synced 2026-07-22 13:10:27 +00:00
Resolves the parent folder of the copied file (or folder), dirname-style, with root edge cases kept shell-usable (/ and C:\ retained). Desktop tier: inherits the existing mobile blank-and-notify mechanics. The unresolved-token notice wording now names the folder token too. Requested in discussion #17.
89 lines
3.4 KiB
TypeScript
89 lines
3.4 KiB
TypeScript
export type PathWrapping = 'none' | 'double-quotes' | 'single-quotes' | 'backticks';
|
|
export type PathFormat = 'unix' | 'windows';
|
|
export type MarkdownLinkFormat = 'wiki-style' | 'standard-markdown';
|
|
|
|
export function wrapPath(filePath: string, wrapping: PathWrapping): string {
|
|
switch (wrapping) {
|
|
case 'double-quotes': return `"${filePath}"`;
|
|
case 'single-quotes': return `'${filePath}'`;
|
|
case 'backticks': return `\`${filePath}\``;
|
|
case 'none':
|
|
default: return filePath;
|
|
}
|
|
}
|
|
|
|
export function formatRelativePath(filePath: string, format: PathFormat): string {
|
|
if (!filePath) {
|
|
return format === 'windows' ? '.\\' : './';
|
|
}
|
|
if (format === 'windows') {
|
|
const winPath = filePath.replace(/\//g, '\\');
|
|
return winPath.startsWith('.\\') ? winPath : '.\\' + winPath;
|
|
}
|
|
return filePath.startsWith('./') ? filePath : './' + filePath;
|
|
}
|
|
|
|
export function buildFileUrl(absolutePath: string): string {
|
|
if (/^[a-zA-Z]:/.test(absolutePath)) {
|
|
// Windows absolute path (e.g. C:\Users\name\file.md)
|
|
// The drive letter contains a colon that must NOT be encoded.
|
|
// Split on the first '/' after converting backslashes so the drive
|
|
// letter ("C:") is kept intact and only the remaining segments are encoded.
|
|
const forwardSlashed = absolutePath.replace(/\\/g, '/');
|
|
const [drive, ...segments] = forwardSlashed.split('/');
|
|
const encodedSegments = segments.map(seg => seg === '' ? '' : encodeURIComponent(seg));
|
|
return `file:///${drive}/${encodedSegments.join('/')}`;
|
|
} else {
|
|
// Unix/Mac absolute path (e.g. /home/user/file.md)
|
|
const segments = absolutePath.split('/');
|
|
const encodedSegments = segments.map(seg => seg === '' ? '' : encodeURIComponent(seg));
|
|
return `file://${encodedSegments.join('/')}`;
|
|
}
|
|
}
|
|
|
|
export function buildObsidianUrl(vaultName: string, filePath: string, anchor?: string): string {
|
|
const normalizedPath = filePath.endsWith('.md') ? filePath.slice(0, -3) : filePath;
|
|
// Obsidian's open URI has no separate heading or block parameter. The anchor
|
|
// is appended to the file value after "#": a heading name, or "^id" for a
|
|
// block. encodeURIComponent turns "#" into "%23" and "^" into "%5E".
|
|
const fileParam = anchor ? `${normalizedPath}#${anchor}` : normalizedPath;
|
|
return `obsidian://open?vault=${encodeURIComponent(vaultName)}&file=${encodeURIComponent(fileParam)}`;
|
|
}
|
|
|
|
export function extractFilename(fileName: string, includeExtension: boolean): string {
|
|
if (!includeExtension) {
|
|
const lastDot = fileName.lastIndexOf('.');
|
|
if (lastDot > 0) {
|
|
return fileName.substring(0, lastDot);
|
|
}
|
|
}
|
|
return fileName;
|
|
}
|
|
|
|
export function extractParentPath(absolutePath: string): string {
|
|
const lastSep = Math.max(absolutePath.lastIndexOf('/'), absolutePath.lastIndexOf('\\'));
|
|
if (lastSep < 0) {
|
|
return absolutePath;
|
|
}
|
|
const parent = absolutePath.substring(0, lastSep);
|
|
if (parent === '') {
|
|
// Unix root: "/file.md" parents to "/", not "".
|
|
return '/';
|
|
}
|
|
if (/^[a-zA-Z]:$/.test(parent)) {
|
|
// Windows drive root: "C:\file.md" parents to "C:\". A bare "C:" means
|
|
// "current directory on C:" to a shell, which is not the intent.
|
|
return parent + '\\';
|
|
}
|
|
return parent;
|
|
}
|
|
|
|
export function buildMarkdownLink(fileName: string, filePath: string, format: MarkdownLinkFormat): string {
|
|
const fileNameWithoutExt = extractFilename(fileName, false);
|
|
|
|
if (format === 'wiki-style') {
|
|
return `[[${fileNameWithoutExt}]]`;
|
|
}
|
|
|
|
return `[${fileName}](${formatRelativePath(filePath, 'unix')})`;
|
|
}
|