Fixes suggestion suffix

This commit is contained in:
Simon Schödler 2023-04-04 13:46:38 +02:00
parent 9c8e3bc33f
commit 5de11933ad
3 changed files with 53 additions and 97 deletions

View file

@ -8,3 +8,4 @@ insert_final_newline = true
indent_style = space
indent_size = 2
tab_width = 2
max_line_length = 120

View file

@ -35,6 +35,7 @@ export abstract class TreeItemBase<TData> extends HTMLElement {
this.inner = this.mainWrapper.createDiv({
cls: 'tree-item-inner tree-item-inner-extensions',
text: this.getCaptionText(),
});
this.flairWrapper = this.mainWrapper.createDiv({
cls: 'tree-item-flair-outer',
@ -48,20 +49,18 @@ export abstract class TreeItemBase<TData> extends HTMLElement {
});
}
public connectedCallback() {
this.inner.setText(this.text);
}
public abstract sortChildren(): void;
public getCaptionText(): string {
return this.text;
}
public setDisable() {
this.mainWrapper.style.textDecoration = 'line-through';
this.buttons.forEach((button) => button.setDisabled(true));
}
public addOnClick(
listener: (this: HTMLDivElement, ev: HTMLElementEventMap['click']) => any
): void {
public addOnClick(listener: (this: HTMLDivElement, ev: HTMLElementEventMap['click']) => any): void {
this.mainWrapper.addEventListener('click', listener);
}
@ -73,11 +72,7 @@ export abstract class TreeItemBase<TData> extends HTMLElement {
this.suffix.innerText = text;
}
public addButton(
label: string,
iconName: string,
onclick: (this: HTMLDivElement, ev: MouseEvent) => any
): void {
public addButton(label: string, iconName: string, onclick: (this: HTMLDivElement, ev: MouseEvent) => any): void {
const button = new ButtonComponent(this.mainWrapper);
button.setTooltip(label);
@ -111,9 +106,7 @@ export abstract class TreeItem<TData> extends TreeItemBase<TData> {
this.mainWrapper.prepend(this.iconWrapper);
// Collapse / Fold
this.mainWrapper.addEventListener('click', () =>
this.isCollapsed() ? this.expand() : this.collapse()
);
this.mainWrapper.addEventListener('click', () => (this.isCollapsed() ? this.expand() : this.collapse()));
}
public abstract getChildren(): TreeItemBase<any>[];
@ -135,9 +128,7 @@ export abstract class TreeItem<TData> extends TreeItemBase<TData> {
public setDisable() {
super.setDisable();
this.mainWrapper.style.textDecoration = 'line-through';
Array.from(this.childrenWrapper.children).forEach((child) =>
(child as TreeItemBase<any>).setDisable()
);
Array.from(this.childrenWrapper.children).forEach((child) => (child as TreeItemBase<any>).setDisable());
}
public addTreeItems(children: TreeItemBase<any>[]) {

View file

@ -46,18 +46,11 @@ export class CrossbowView extends ItemView {
}
private getCurrentSuggestions(): Suggestion[] {
return this.contentEl.children.length > 0
? (Array.from(this.contentEl.children) as Suggestion[])
: [];
return this.contentEl.children.length > 0 ? (Array.from(this.contentEl.children) as Suggestion[]) : [];
}
public updateSuggestions(
suggestions: Suggestion[],
fileHasChanged: boolean
): void {
this.crossbow.debugLog(
`${fileHasChanged ? 'Clearing & adding' : 'Updating'} suggestions`
);
public updateSuggestions(suggestions: Suggestion[], fileHasChanged: boolean): void {
this.crossbow.debugLog(`${fileHasChanged ? 'Clearing & adding' : 'Updating'} suggestions`);
const currentSuggestions = this.getCurrentSuggestions();
@ -69,15 +62,10 @@ export class CrossbowView extends ItemView {
suggestions.sort((a, b) => a.hash.localeCompare(b.hash));
suggestions.forEach((suggestion) => suggestion.sortChildren());
suggestions.forEach((suggestion, index) => {
suggestions.forEach((suggestion) => {
// Find if this Suggestion already exists
const existingSuggestionIndex = currentSuggestions.findIndex(
(item) => item.hash === suggestion.hash
);
const existingSuggestion =
existingSuggestionIndex !== -1
? currentSuggestions.splice(existingSuggestionIndex, 1)[0]
: undefined;
const index = currentSuggestions.findIndex((item) => item.hash === suggestion.hash);
const existingSuggestion = index !== -1 ? currentSuggestions.splice(index, 1)[0] : undefined;
const expandedOccurrencesHashes = existingSuggestion
? existingSuggestion
@ -86,7 +74,6 @@ export class CrossbowView extends ItemView {
.map((item) => item.hash)
: [];
// Configure Occurrences
suggestion.getChildren().forEach((occurrence) => {
// Toggle expanded state, if it was expanded before
if (expandedOccurrencesHashes.includes(occurrence.hash)) {
@ -97,77 +84,61 @@ export class CrossbowView extends ItemView {
// Insert / append the new suggestion, depending on whether it already existed
if (existingSuggestion) {
existingSuggestion.replaceWith(suggestion);
existingSuggestion.isCollapsed()
? suggestion.collapse()
: suggestion.expand();
existingSuggestion.isCollapsed() ? suggestion.collapse() : suggestion.expand();
existingSuggestion?.remove();
} else {
this.contentEl.appendChild(suggestion);
}
// Add flair
const ranks = new Set<CacheMatch['rank']>();
suggestion.cacheMatches.forEach((match) => ranks.add(match.rank));
const availableMatchRanks = Array.from(ranks)
.sort((a, b) => a.codePointAt(0)! - b.codePointAt(0)!)
.join('');
suggestion.addFlair(availableMatchRanks);
suggestion.addTextSuffix(`(${suggestion.children.length.toString()})`);
});
// Now, we're left with the items that we need to remove
// Now, we're left with the existing suggestions that we need to remove
currentSuggestions.forEach((item) => item.remove());
}
public createSuggestion(
word: string,
editorPositions: EditorPosition[],
cacheMatches: CacheMatch[]
): Suggestion {
public createSuggestion(word: string, editorPositions: EditorPosition[], cacheMatches: CacheMatch[]): Suggestion {
const suggestion = new Suggestion(word, cacheMatches);
const occurrences = editorPositions.map((p) => new Occurrence(p));
// Configure Occurrences
occurrences.forEach((occurrence) => {
// Create and add matches to occurrence, always using the **same** cacheMatches array
const matches = suggestion.cacheMatches.map((m) => new Match(m));
occurrence.addTreeItems(matches);
// Scroll into view action
// Scroll into view action...
const scrollIntoView = () => {
const occurrenceEnd = {
ch: occurrence.value.ch + suggestion.hash.length,
line: occurrence.value.line,
} as EditorPosition;
this.crossbow.currentEditor.setSelection(
occurrence.value,
occurrenceEnd
);
this.crossbow.currentEditor.scrollIntoView(
{ from: occurrence.value, to: occurrenceEnd },
true
);
this.crossbow.currentEditor.setSelection(occurrence.value, occurrenceEnd);
this.crossbow.currentEditor.scrollIntoView({ from: occurrence.value, to: occurrenceEnd }, true);
};
// Can be invoked via flair button...
occurrence.addButton(
'Scroll into View',
'lucide-scroll',
(ev: MouseEvent) => {
scrollIntoView();
ev.preventDefault();
ev.stopPropagation();
}
);
// ...Can be invoked via flair button...
occurrence.addButton('Scroll into View', 'lucide-scroll', (ev: MouseEvent) => {
scrollIntoView();
ev.preventDefault();
ev.stopPropagation();
});
// As well as when expanding the suggestions, if it's collapsed. Greatly improves UX
// ...As well as when expanding the suggestions, if it's collapsed. Greatly improves UX
occurrence.addOnClick(() => {
if (!occurrence.isCollapsed()) scrollIntoView();
});
// Configure Matches
occurrence.getChildren().forEach((match) => {
// Add backlink & remove action
const link = match.value.item
? this.app.fileManager.generateMarkdownLink(
match.value.file,
match.value.text,
'#' + match.value.text,
suggestion.hash
)
: this.app.fileManager.generateMarkdownLink(match.value.file, match.value.text, undefined, suggestion.hash);
// 'Use' button inserts backlink & disables the occurrence
match.addButton('Use', 'lucide-inspect', () => {
occurrence.getChildren().forEach((o) => o.setDisable());
@ -176,25 +147,7 @@ export class CrossbowView extends ItemView {
line: occurrence.value.line,
} as EditorPosition;
const link = match.value.item
? this.app.fileManager.generateMarkdownLink(
match.value.file,
match.value.text,
'#' + match.value.text,
suggestion.hash
)
: this.app.fileManager.generateMarkdownLink(
match.value.file,
match.value.text,
undefined,
suggestion.hash
);
this.crossbow.currentEditor.replaceRange(
link,
occurrence.value,
occurrenceEnd
);
this.crossbow.currentEditor.replaceRange(link, occurrence.value, occurrenceEnd);
});
// Go to source action
@ -206,6 +159,17 @@ export class CrossbowView extends ItemView {
suggestion.addTreeItems(occurrences);
// Add flair
const ranks = new Set<CacheMatch['rank']>();
suggestion.cacheMatches.forEach((match) => ranks.add(match.rank));
const availableMatchRanks = Array.from(ranks)
.sort((a, b) => a.codePointAt(0)! - b.codePointAt(0)!)
.join('');
suggestion.addFlair(availableMatchRanks);
suggestion.addTextSuffix(`(${occurrences.length.toString()})`);
return suggestion;
}
}