Skip to content
Merged
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
70 changes: 70 additions & 0 deletions src/gui/suggesters/genericTextSuggester.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { describe, expect, it, vi } from "vitest";
import { GenericTextSuggester } from "./genericTextSuggester";

describe("GenericTextSuggester", () => {
describe("renderSuggestion", () => {
it("normalizes the query when typing a partial .md extension so highlights still match", () => {
const el = document.createElement("div");
const renderMatch = vi.fn();

GenericTextSuggester.prototype.renderSuggestion.call(
{
getCurrentQuery: () => "note.m",
renderMatch,
} as any,
"note.md",
el,
);

expect(renderMatch).toHaveBeenCalledWith(el, "note", "note");
});

it("treats .md extension matching as case-insensitive", () => {
const el = document.createElement("div");
const renderMatch = vi.fn();

GenericTextSuggester.prototype.renderSuggestion.call(
{
getCurrentQuery: () => "Note.M",
renderMatch,
} as any,
"Note.MD",
el,
);

expect(renderMatch).toHaveBeenCalledWith(el, "Note", "Note");
});

it("normalizes query when suggestion and query casing differ", () => {
const el = document.createElement("div");
const renderMatch = vi.fn();

GenericTextSuggester.prototype.renderSuggestion.call(
{
getCurrentQuery: () => "note.m",
renderMatch,
} as any,
"Note.MD",
el,
);

expect(renderMatch).toHaveBeenCalledWith(el, "Note", "Note");
});

it("does not change query normalization for non-markdown files", () => {
const el = document.createElement("div");
const renderMatch = vi.fn();

GenericTextSuggester.prototype.renderSuggestion.call(
{
getCurrentQuery: () => "note.j",
renderMatch,
} as any,
"note.js",
el,
);

expect(renderMatch).toHaveBeenCalledWith(el, "note.js", "note.j");
});
});
});
16 changes: 14 additions & 2 deletions src/gui/suggesters/genericTextSuggester.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { App } from "obsidian";
import { TextInputSuggest } from "./suggest";
import { normalizeDisplayItem, normalizeQuery } from "./utils";
import {
normalizeDisplayItem,
normalizeQuery,
stripMdExtensionForDisplay,
} from "./utils";

export class GenericTextSuggester extends TextInputSuggest<string> {
constructor(
Expand Down Expand Up @@ -35,7 +39,15 @@ export class GenericTextSuggester extends TextInputSuggest<string> {

renderSuggestion(value: string, el: HTMLElement): void {
if (!value) return;
this.renderMatch(el, value, this.getCurrentQuery());
const displayValue = stripMdExtensionForDisplay(value);
let displayQuery = stripMdExtensionForDisplay(this.getCurrentQuery());
if (
value.toLowerCase().endsWith(".md") &&
displayQuery.toLowerCase().startsWith(`${displayValue.toLowerCase()}.`)
) {
displayQuery = displayValue;
}
this.renderMatch(el, displayValue, displayQuery);
}
Comment thread
chhoumann marked this conversation as resolved.

protected getCurrentQuery(): string {
Expand Down
26 changes: 25 additions & 1 deletion src/gui/suggesters/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
replaceRange,
getTextBeforeCursor,
renderExactHighlight,
renderFuzzyHighlight
renderFuzzyHighlight,
stripMdExtensionForDisplay,
} from "./utils";

// Mock HTMLInputElement for testing
Expand Down Expand Up @@ -155,4 +156,27 @@ describe("Suggester Utils", () => {
expect(el.innerHTML).toBe('&lt;<mark class="qa-highlight">i</mark>mg src=x&gt;');
});
});

describe("stripMdExtensionForDisplay", () => {
it("strips only a trailing .md extension (case-insensitive)", () => {
expect(stripMdExtensionForDisplay("file.md")).toBe("file");
expect(stripMdExtensionForDisplay("folder/file.md")).toBe("folder/file");
expect(stripMdExtensionForDisplay("FILE.MD")).toBe("FILE");
});

it("does not strip other extensions", () => {
expect(stripMdExtensionForDisplay("file.js")).toBe("file.js");
expect(stripMdExtensionForDisplay("file.canvas")).toBe("file.canvas");
});

it("does not strip .md when it is not the final suffix", () => {
expect(stripMdExtensionForDisplay("file.md.backup")).toBe(
"file.md.backup",
);
expect(stripMdExtensionForDisplay("file.md.md")).toBe("file.md");
expect(stripMdExtensionForDisplay("{{TEMPLATE:folder/file.md}}")).toBe(
"{{TEMPLATE:folder/file.md}}",
);
});
});
});
5 changes: 5 additions & 0 deletions src/gui/suggesters/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export function normalizeForSearch(value: string): string {
return value.normalize("NFC").toLowerCase();
}

// Display-only helper: keep stored path intact, but hide trailing ".md" in UI labels.
export function stripMdExtensionForDisplay(value: string): string {
return value.toLowerCase().endsWith(".md") ? value.slice(0, -3) : value;
}

/**
* Insert text at cursor position
*/
Expand Down