mirror of
https://github.com/nathonius/obsidian-github-link.git
synced 2026-07-22 09:20:25 +00:00
Merge pull request #167 from nathonius/feat/155/file-tag
✨ feat: #155 Show the full filename when linking directly to a file
This commit is contained in:
commit
ceab053dca
7 changed files with 76 additions and 6 deletions
|
|
@ -10,6 +10,8 @@ export interface ParsedUrl {
|
|||
code?: {
|
||||
branch?: string;
|
||||
path?: string;
|
||||
filename?: string;
|
||||
line?: string;
|
||||
};
|
||||
commit?: string;
|
||||
}
|
||||
|
|
@ -60,6 +62,8 @@ export function parseUrl(urlString: string): ParsedUrl | null {
|
|||
if (urlParts[5]) {
|
||||
const pathParts = urlParts.slice(5);
|
||||
parsedUrl.code.path = pathParts.join("/");
|
||||
parsedUrl.code.filename = pathParts.last();
|
||||
parsedUrl.code.line = url.hash.slice(1);
|
||||
}
|
||||
break;
|
||||
case "commit":
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ export function setIssueIcon(icon: HTMLElement, status: IssueStatus): void {
|
|||
icon.dataset.status = status;
|
||||
}
|
||||
|
||||
export function setFileIcon(icon: HTMLElement): void {
|
||||
setIcon(icon, "file");
|
||||
}
|
||||
|
||||
export function setPRMergeableIcon(icon: HTMLElement, mergeable: boolean): void {
|
||||
if (PluginSettings.tagTooltips) {
|
||||
icon.setAttribute("aria-label", PRMergeableText[`${mergeable}`]);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ const selectors = {
|
|||
repo: ".github-link-inline-repo",
|
||||
issueTitle: ".github-link-inline-issue-title",
|
||||
prTitle: ".github-link-inline-pr-title",
|
||||
file: ".github-link-inline-file",
|
||||
};
|
||||
|
||||
describe("createTag", () => {
|
||||
|
|
@ -23,7 +24,7 @@ describe("createTag", () => {
|
|||
expect(tag).toBeTruthy();
|
||||
const org = tag?.querySelector(selectors.org) as HTMLSpanElement;
|
||||
expect(org.innerText).toEqual(user);
|
||||
[selectors.repo, selectors.issueTitle, selectors.prTitle].forEach((s) => {
|
||||
[selectors.repo, selectors.issueTitle, selectors.prTitle, selectors.file].forEach((s) => {
|
||||
expect(tag?.querySelector(s)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
|
@ -38,7 +39,7 @@ describe("createTag", () => {
|
|||
const repoEl = tag?.querySelector(selectors.repo) as HTMLSpanElement;
|
||||
expect(org.innerText).toEqual(user);
|
||||
expect(repoEl.innerText).toEqual(repo);
|
||||
[selectors.issueTitle, selectors.prTitle].forEach((s) => {
|
||||
[selectors.issueTitle, selectors.prTitle, selectors.file].forEach((s) => {
|
||||
expect(tag?.querySelector(s)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { setIcon } from "obsidian";
|
||||
import { IssueStatus, getIssueStatus, getPRStatus } from "../github/response";
|
||||
import { setIssueIcon, setPRIcon, setPRMergeableIcon } from "../icon";
|
||||
import { setFileIcon, setIssueIcon, setPRIcon, setPRMergeableIcon } from "../icon";
|
||||
|
||||
import { PluginSettings } from "../plugin";
|
||||
import type { PullResponse } from "../github/response";
|
||||
|
|
@ -20,6 +20,7 @@ export function createTag(href: string): HTMLAnchorElement | null {
|
|||
if (!parsedUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const container = createEl("a", { cls: "github-link-inline", href, attr: { target: "_blank" } });
|
||||
const config: TagConfig = {
|
||||
icon: createSpan({ cls: ["github-link-status-icon", "github-link-inline-icon"] }),
|
||||
|
|
@ -30,8 +31,8 @@ export function createTag(href: string): HTMLAnchorElement | null {
|
|||
createOrgSection(config, parsedUrl);
|
||||
createRepoSection(config, parsedUrl);
|
||||
|
||||
// Add issue OR pr
|
||||
if (parsedUrl.issue !== undefined || parsedUrl.pr !== undefined) {
|
||||
// Add issue OR pr OR file
|
||||
if (parsedUrl.issue !== undefined || parsedUrl.pr !== undefined || parsedUrl.code !== undefined) {
|
||||
// Remove org
|
||||
const orgIndex = config.sections.findIndex((section) => section.classList.contains("github-link-inline-org"));
|
||||
if (orgIndex !== -1) {
|
||||
|
|
@ -42,6 +43,8 @@ export function createTag(href: string): HTMLAnchorElement | null {
|
|||
createIssueSection(config, parsedUrl, container);
|
||||
} else if (parsedUrl.pr !== undefined) {
|
||||
createPullRequestSection(config, parsedUrl, container);
|
||||
} else if (parsedUrl.code !== undefined) {
|
||||
createFileSection(config, parsedUrl, container);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +143,28 @@ function createPullRequestSection(config: TagConfig, parsedUrl: ParsedUrl, conta
|
|||
}
|
||||
}
|
||||
|
||||
function createFileSection(config: TagConfig, parsedUrl: ParsedUrl, _container: HTMLAnchorElement) {
|
||||
if (parsedUrl.code === undefined) {
|
||||
return;
|
||||
}
|
||||
const fileContainer = createSpan({ cls: "github-link-inline-file" });
|
||||
setFileIcon(config.icon);
|
||||
config.sections.push(fileContainer);
|
||||
if (parsedUrl.code.filename) {
|
||||
fileContainer.setText(parsedUrl.code.filename);
|
||||
} else if (parsedUrl.code.path) {
|
||||
fileContainer.setText(parsedUrl.code.path);
|
||||
}
|
||||
if (PluginSettings.tagShowFileLineNumber && parsedUrl.code.line) {
|
||||
fileContainer.appendChild(createSpan({ cls: "github-link-inline-file-line-number", text: parsedUrl.code.line }));
|
||||
}
|
||||
if (PluginSettings.tagShowFileBranchName && parsedUrl.code.branch) {
|
||||
fileContainer.appendChild(
|
||||
createSpan({ cls: "github-link-inline-file-branch", text: `(${parsedUrl.code.branch})` }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that this function is called AFTER the tag has been built, so it adds itself to the dom.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -157,6 +157,28 @@ export class GithubLinkPluginSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("File branch name")
|
||||
.setDesc("Append the branch name to links to an individual file inside a repo")
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(PluginSettings.tagShowFileBranchName);
|
||||
toggle.onChange((value) => {
|
||||
PluginSettings.tagShowFileBranchName = value;
|
||||
void this.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("File line number")
|
||||
.setDesc("Append the line number (if provided) to links to an individual file inside a repo")
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(PluginSettings.tagShowFileLineNumber);
|
||||
toggle.onChange((value) => {
|
||||
PluginSettings.tagShowFileLineNumber = value;
|
||||
void this.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
containerEl.createEl("h3", { text: "Cache settings" });
|
||||
|
||||
new Setting(containerEl)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ export interface GithubLinkPluginSettings {
|
|||
logLevel: LogLevel;
|
||||
tagTooltips: boolean;
|
||||
tagShowPRMergeable: boolean;
|
||||
tagShowFileBranchName: boolean;
|
||||
tagShowFileLineNumber: boolean;
|
||||
cacheIntervalSeconds: number;
|
||||
maxCacheAgeHours: number;
|
||||
minRequestSeconds: number;
|
||||
|
|
@ -41,6 +43,8 @@ export const DEFAULT_SETTINGS: GithubLinkPluginSettings = {
|
|||
logLevel: LogLevel.Error,
|
||||
tagTooltips: false,
|
||||
tagShowPRMergeable: false,
|
||||
tagShowFileBranchName: true,
|
||||
tagShowFileLineNumber: true,
|
||||
cacheIntervalSeconds: 60,
|
||||
maxCacheAgeHours: 120,
|
||||
minRequestSeconds: 60,
|
||||
|
|
|
|||
12
styles.css
12
styles.css
|
|
@ -277,13 +277,23 @@ body.theme-dark {
|
|||
}
|
||||
|
||||
.github-link-inline-pr-title,
|
||||
.github-link-inline-issue-title {
|
||||
.github-link-inline-issue-title,
|
||||
.github-link-inline-file {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-wrap: nowrap;
|
||||
line-height: var(--line-height-normal);
|
||||
}
|
||||
|
||||
.github-link-inline-file {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
.github-link-inline-file > .github-link-inline-file-line-number,
|
||||
.github-link-inline-file > .github-link-inline-file-branch {
|
||||
color: var(--gh-color-fg-muted);
|
||||
}
|
||||
|
||||
.github-link-table-wrapper {
|
||||
margin-block-end: var(--p-spacing);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue