Skip to content

Commit

Permalink
Minor refactor. Fix casing mismatch doing lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
hadynz committed Feb 13, 2022
1 parent 9cf54dc commit 4f61555
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 54 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "obsidian-sidekick",
"name": "Sidekick",
"description": "A companion to identify hidden connections that match your tags and pages",
"version": "1.0.3",
"version": "1.0.4",
"minAppVersion": "0.13.8",
"author": "Hady Osman",
"authorUrl": "https://hady.geek.nz",
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "obsidian-sidekick",
"version": "1.0.3",
"version": "1.0.4",
"description": "A companion to identify hidden connections that match your tags and pages",
"main": "src/index.ts",
"repository": {
Expand Down Expand Up @@ -36,6 +36,7 @@
"@types/faker": "^5.5.8",
"@types/highlight-words-core": "^1.2.1",
"@types/jest": "^26.0.22",
"@types/lodash": "^4.14.178",
"@types/webpack": "^5.28.0",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
Expand Down Expand Up @@ -71,6 +72,7 @@
},
"dependencies": {
"highlight-words-core": "^1.2.2",
"lodash": "^4.17.21",
"tippy.js": "^6.3.7"
}
}
27 changes: 27 additions & 0 deletions src/app-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import _ from 'lodash';
import { App, parseFrontMatterTags, TFile } from 'obsidian';

import { getAliases } from './utils/getAliases';

export class AppHelper {
constructor(private app: App) {}

public get activeFile(): TFile | undefined {
return this.app.workspace.getActiveFile();
}

public getAliases(file: TFile): string[] {
return getAliases(this.app.metadataCache.getFileCache(file));
}

public getTags(file: TFile): string[] {
const tags = this.getFrontMatterTags(file).concat(
this.app.metadataCache.getFileCache(file)?.tags?.map((x) => x.tag) ?? []
);
return _.uniq(tags);
}

private getFrontMatterTags(file: TFile): string[] {
return parseFrontMatterTags(this.app.metadataCache.getFileCache(file)?.frontmatter) ?? [];
}
}
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import { ViewPlugin, PluginValue } from '@codemirror/view';

import Search from './search';
import { Indexer } from './indexing/indexer';
import { AppHelper } from './app-helper';

export default class TagsAutosuggestPlugin extends Plugin {
currentExtension: ViewPlugin<PluginValue>;

public async onload(): Promise<void> {
console.log('Autosuggest plugin: loading plugin', new Date().toLocaleString());

const indexer = new Indexer(this.app);
const appHelper = new AppHelper(this.app);
const indexer = new Indexer(this.app, appHelper);
const search = new Search(indexer);

indexer.on('updated-index', () => {
Expand Down
32 changes: 16 additions & 16 deletions src/indexing/indexModels.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { TFile } from 'obsidian';

export interface SearchIndex {
text: string;
replaceText: string;
index: string;
displayText: string;
isDefinedInFile: (file: TFile) => boolean;
}

export class TagIndex implements SearchIndex {
public readonly text: string;
public readonly replaceText: string;
public readonly index: string;
public readonly displayText: string;

constructor(private tag: string) {
this.text = tag.toLowerCase();
this.replaceText = `#${this.tag}`;
constructor(tag: string) {
this.index = tag.toLowerCase().replace(/#/, '');
this.displayText = tag;
}

public isDefinedInFile(_file: TFile): boolean {
Expand All @@ -21,12 +21,12 @@ export class TagIndex implements SearchIndex {
}

export class AliasIndex implements SearchIndex {
public readonly text: string;
public readonly replaceText: string;
public readonly index: string;
public readonly displayText: string;

constructor(word: string, private file: TFile) {
this.text = word.toLowerCase();
this.replaceText = `[[${file.basename}|${word}]]`;
constructor(private file: TFile, word: string) {
this.index = word.toLowerCase();
this.displayText = `[[${file.basename}|${word}]]`;
}

public isDefinedInFile(file: TFile): boolean {
Expand All @@ -35,12 +35,12 @@ export class AliasIndex implements SearchIndex {
}

export class PageIndex implements SearchIndex {
public readonly text: string;
public readonly replaceText: string;
public readonly index: string;
public readonly displayText: string;

constructor(private file: TFile) {
this.text = file.basename.toLowerCase();
this.replaceText = `[[${file.basename}]]`;
this.index = file.basename.toLowerCase();
this.displayText = `[[${file.basename}]]`;
}

public isDefinedInFile(file: TFile): boolean {
Expand Down
52 changes: 20 additions & 32 deletions src/indexing/indexer.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import { App, getAllTags, TFile, CachedMetadata } from 'obsidian';
import _ from 'lodash';
import { App, TFile } from 'obsidian';

import { PageIndex, SearchIndex, TagIndex, AliasIndex } from './indexModels';
import { getAliases } from '../utils/getAliases';

type ObsidianCache = {
file: TFile;
metadata: CachedMetadata;
};
import { AppHelper } from '../app-helper';

export class Indexer {
private searchIndex: SearchIndex[] = [];
private callbacks: (() => void)[] = [];

constructor(private app: App) {
constructor(private app: App, private appHelper: AppHelper) {
this.app.workspace.onLayoutReady(() => this.indexAll());
this.app.vault.on('modify', () => this.indexAll());
}

public get index(): readonly SearchIndex[] {
const activeFile = this.app.workspace.getActiveFile();
const activeFile = this.appHelper.activeFile;
return this.searchIndex.filter((index) => !index.isDefinedInFile(activeFile));
}

Expand All @@ -27,40 +23,32 @@ export class Indexer {
}

private indexAll(): void {
this.searchIndex = [];
const allFiles = this.app.vault.getMarkdownFiles();

const cache = this.app.vault.getMarkdownFiles().map((file) => ({
file,
metadata: this.app.metadataCache.getFileCache(file),
}));
const fileIndices = allFiles.map((file) => this.indexFile(file)).flat();

this.indexLinks(cache);
this.indexTags(cache);
this.searchIndex = [...fileIndices, ...this.indexAllTags(allFiles)];

// Notify all listeners that the index has been updated
this.callbacks.forEach((cb) => cb());
}

private indexLinks(cache: ObsidianCache[]): void {
cache.forEach((fileCache) => {
this.searchIndex.push(new PageIndex(fileCache.file));
private indexFile(file: TFile): SearchIndex[] {
const pageIndex = new PageIndex(file);

const aliasIndices = this.appHelper
.getAliases(file)
.map((alias) => new AliasIndex(file, alias));

getAliases(fileCache.metadata).forEach((alias: string) => {
this.searchIndex.push(new AliasIndex(alias, fileCache.file));
});
});
return [pageIndex, ...aliasIndices];
}

private indexTags(cache: ObsidianCache[]): void {
const tags = cache.reduce((acc: string[], fileCache) => {
acc.push(...getAllTags(fileCache.metadata).map((t) => t.substring(1)));
return acc;
private indexAllTags(files: TFile[]): TagIndex[] {
const tagIndices: TagIndex[] = files.reduce((acc, file) => {
const tags = this.appHelper.getTags(file).map((tag) => new TagIndex(tag));
return [...acc, ...tags];
}, []);

const uniqueTags = Array.from(new Set(tags));

for (const tag of uniqueTags) {
this.searchIndex.push(new TagIndex(tag));
}
return _.uniqBy(tagIndices, (x) => x.index);
}
}
4 changes: 2 additions & 2 deletions src/search/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ export default class Search {
constructor(private indexer: Indexer) {}

public getSuggestionReplacement(text: string): string {
return this.indexer.index.find((index) => index.text === text).replaceText;
return this.indexer.index.find((index) => index.index === text.toLowerCase()).displayText;
}

public find(text: string): SearchResult[] {
const searchWords = this.indexer.index.map((index) => {
try {
return index.text;
return index.index;
} catch (err) {
console.error('Cannot return text value of index', index, err);
}
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"~/*": ["src/*"]
},
"resolveJsonModule": true,
"esModuleInterop": true
"esModuleInterop": true,
"downlevelIteration": true
},
// Fixes errors when changing `module` to ES in the above compiler options
// See: https://github.com/webpack/webpack-cli/issues/2458#issuecomment-846635277
Expand Down

0 comments on commit 4f61555

Please sign in to comment.