Resolve Khoj Obsidian Plugin feedback

### Details
- b415f87 Split find and jump to notes code in `onChooseSuggestion' method
- 37063f6 Truncate query to 8k chars for find similar notes from Obsidian plugin
- 4456cf5 No need to use `then' or `finally' in `async' functions after an `await'
- 4070be6 Pass app object from plugin instance to child objects and functions
- c203c6a Use Sentence case for Find similar mote Obsidian command name
This commit is contained in:
Debanjum
2023-01-26 18:54:33 -03:00
committed by GitHub
4 changed files with 39 additions and 36 deletions

View File

@@ -24,7 +24,7 @@ export default class Khoj extends Plugin {
// Add similar notes command. It can only be triggered from the editor
this.addCommand({
id: 'similar',
name: 'Find Similar Notes',
name: 'Find similar notes',
editorCheckCallback: (checking) => {
if (!checking && this.settings.connectedToBackend)
new KhojModal(this.app, this.settings, true).open();
@@ -49,11 +49,11 @@ export default class Khoj extends Plugin {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
// Load, configure khoj server settings
await configureKhojBackend(this.settings);
await configureKhojBackend(this.app.vault, this.settings);
}
async saveSettings() {
await configureKhojBackend(this.settings, false)
await configureKhojBackend(this.app.vault, this.settings, false)
.then(() => this.saveData(this.settings));
}
}

View File

@@ -10,9 +10,11 @@ export class KhojModal extends SuggestModal<SearchResult> {
setting: KhojSetting;
rerank: boolean = false;
find_similar_notes: boolean;
app: App;
constructor(app: App, setting: KhojSetting, find_similar_notes: boolean = false) {
super(app);
this.app = app;
this.setting = setting;
this.find_similar_notes = find_similar_notes;
@@ -61,8 +63,9 @@ export class KhojModal extends SuggestModal<SearchResult> {
if (file && file.extension === 'md') {
// Enable rerank of search results
this.rerank = true
// Set contents of active markdown file to input element
this.inputEl.value = await this.app.vault.read(file);
// Set input element to contents of active markdown file
// truncate to first 8,000 characters to avoid hitting query size limits
this.inputEl.value = await this.app.vault.read(file).then(file_str => file_str.slice(0, 8000));
// Trigger search to get and render similar notes from khoj backend
this.inputEl.dispatchEvent(new Event('input'));
this.rerank = false
@@ -76,12 +79,12 @@ export class KhojModal extends SuggestModal<SearchResult> {
async getSuggestions(query: string): Promise<SearchResult[]> {
// Query Khoj backend for search results
let encodedQuery = encodeURIComponent(query);
let searchUrl = `${this.setting.khojUrl}/api/search?q=${encodedQuery}&n=${this.setting.resultsCount}&r=${this.rerank}&t=markdown`
let results = await request(searchUrl)
.then(response => JSON.parse(response))
.then(data => data
.filter((result: any) => !this.find_similar_notes || !result.additional.file.endsWith(this.app.workspace.getActiveFile()?.path))
.map((result: any) => { return { entry: result.entry, file: result.additional.file } as SearchResult; }));
let searchUrl = `${this.setting.khojUrl}/api/search?q=${encodedQuery}&n=${this.setting.resultsCount}&r=${this.rerank}&t=markdown`;
let response = await request(searchUrl);
let data = JSON.parse(response);
let results = data
.filter((result: any) => !this.find_similar_notes || !result.additional.file.endsWith(this.app.workspace.getActiveFile()?.path))
.map((result: any) => { return { entry: result.entry, file: result.additional.file } as SearchResult; });
return results;
}
@@ -98,21 +101,21 @@ export class KhojModal extends SuggestModal<SearchResult> {
// Get all markdown files in vault
const mdFiles = this.app.vault.getMarkdownFiles();
// Find the vault file matching file of result. Open file at result heading
mdFiles
// Find the vault file matching file of chosen search result
let file_match = mdFiles
// Sort by descending length of path
// This finds longest path match when multiple files have same name
.sort((a, b) => b.path.length - a.path.length)
.forEach((file) => {
// Find best file match across operating systems
// E.g Khoj Server on Linux, Obsidian Vault on Android
if (result.file.endsWith(file.path)) {
let resultHeading = result.entry.split('\n', 1)[0];
let linkToEntry = `${file.path}${resultHeading}`
this.app.workspace.openLinkText(linkToEntry, '');
console.log(`Link: ${linkToEntry}, File: ${file.path}, Heading: ${resultHeading}`);
return
}
});
// The first match is the best file match across OS
// e.g Khoj server on Linux, Obsidian vault on Android
.find(file => result.file.endsWith(file.path))
// Open vault file at heading of chosen search result
if (file_match){
let resultHeading = result.entry.split('\n', 1)[0];
let linkToEntry = `${file_match.path}${resultHeading}`
this.app.workspace.openLinkText(linkToEntry, '');
console.log(`Link: ${linkToEntry}, File: ${file_match.path}, Heading: ${resultHeading}`);
}
}
}

View File

@@ -36,8 +36,8 @@ export class KhojSettingTab extends PluginSettingTab {
.setValue(`${this.plugin.settings.khojUrl}`)
.onChange(async (value) => {
this.plugin.settings.khojUrl = value.trim();
await this.plugin.saveSettings()
.finally(() => containerEl.firstElementChild?.setText(this.getBackendStatusMessage()));
await this.plugin.saveSettings();
containerEl.firstElementChild?.setText(this.getBackendStatusMessage());
}));
new Setting(containerEl)
.setName('Results Count')
@@ -60,15 +60,15 @@ export class KhojSettingTab extends PluginSettingTab {
.onClick(async () => {
// Disable button while updating index
button.setButtonText('Updating...');
button.removeCta()
button.removeCta();
indexVaultSetting = indexVaultSetting.setDisabled(true);
await request(`${this.plugin.settings.khojUrl}/api/update?t=markdown&force=true`)
.then(() => new Notice('✅ Updated Khoj index.'));
await request(`${this.plugin.settings.khojUrl}/api/update?t=markdown&force=true`);
new Notice('✅ Updated Khoj index.');
// Re-enable button once index is updated
button.setButtonText('Update');
button.setCta()
button.setCta();
indexVaultSetting = indexVaultSetting.setDisabled(false);
})
);

View File

@@ -1,16 +1,16 @@
import { FileSystemAdapter, Notice, RequestUrlParam, request } from 'obsidian';
import { FileSystemAdapter, Notice, RequestUrlParam, request, Vault } from 'obsidian';
import { KhojSetting } from 'src/settings'
export function getVaultAbsolutePath(): string {
let adaptor = this.app.vault.adapter;
export function getVaultAbsolutePath(vault: Vault): string {
let adaptor = vault.adapter;
if (adaptor instanceof FileSystemAdapter) {
return adaptor.getBasePath();
}
return '';
}
export async function configureKhojBackend(setting: KhojSetting, notify: boolean = true) {
let mdInVault = `${getVaultAbsolutePath()}/**/*.md`;
export async function configureKhojBackend(vault: Vault, setting: KhojSetting, notify: boolean = true) {
let mdInVault = `${getVaultAbsolutePath(vault)}/**/*.md`;
let khojConfigUrl = `${setting.khojUrl}/api/config/data`;
// Check if khoj backend is configured, note if cannot connect to backend
@@ -28,7 +28,7 @@ export async function configureKhojBackend(setting: KhojSetting, notify: boolean
if (!setting.connectedToBackend) return;
// Set index name from the path of the current vault
let indexName = getVaultAbsolutePath().replace(/\//g, '_').replace(/ /g, '_');
let indexName = getVaultAbsolutePath(vault).replace(/\//g, '_').replace(/ /g, '_');
// Get default index directory from khoj backend
let khojDefaultIndexDirectory = await request(`${khojConfigUrl}/default`)
.then(response => JSON.parse(response))