mirror of
https://github.com/shoedler/crossbow.git
synced 2026-07-22 07:40:26 +00:00
Fixes suggestion suffix
This commit is contained in:
parent
9c8e3bc33f
commit
5de11933ad
3 changed files with 53 additions and 97 deletions
|
|
@ -8,3 +8,4 @@ insert_final_newline = true
|
|||
indent_style = space
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
max_line_length = 120
|
||||
|
|
|
|||
|
|
@ -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>[]) {
|
||||
|
|
|
|||
116
src/view/view.ts
116
src/view/view.ts
|
|
@ -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) => {
|
||||
// ...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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue