Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit 73269f8

Browse files
committed
Merge branch '107-fr-add-support-for-autocomplete-of-tags-and-links'
2 parents 2907869 + f6a7b3f commit 73269f8

File tree

25 files changed

+188
-165
lines changed

25 files changed

+188
-165
lines changed

src/cdm/CellModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Row } from "@tanstack/react-table"
2-
import { RowDataType } from "./FolderModel"
2+
import { RowDataType } from "cdm/FolderModel"
33
import { TableStateInterface } from "cdm/TableStateInterface"
44

55
export type TableCellProps = {

src/cdm/FolderModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { DatabaseView } from "DatabaseView";
22
import StateManager from "StateManager";
33
import { RowSelectOption } from "cdm/ComponentsModel";
4+
import { TableStateInterface } from "cdm/TableStateInterface";
45
import NoteInfo from "services/NoteInfo";
56
import { TFile } from "obsidian";
67
import { Column, ColumnDef, ColumnSort, Header, Table } from "@tanstack/react-table";
78
import { Literal } from "obsidian-dataview/lib/data-model/value";
8-
import { TableStateInterface } from "./TableStateInterface";
99

1010
export type Group = Parameter | Parameters | FolderModel | Models;
1111
type Parameter = {

src/components/Columns.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { DataviewService } from "services/DataviewService";
1616
import { Literal } from "obsidian-dataview/lib/data-model/value";
1717
import { DatabaseView } from "DatabaseView";
1818
import { obtainAllPossibleRows } from "helpers/VaultManagement";
19-
import rowContextMenuColumn from "./RowContextMenu";
19+
import rowContextMenuColumn from "components/RowContextMenu";
2020

2121
/**
2222
* Add mandatory and configured metadata columns of the table

src/components/cellTypes/Editor/MarkdownEditor.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { DatabaseView } from "DatabaseView";
2-
import { c } from "helpers/StylesHelper";
32
import React, {
43
AllHTMLAttributes,
54
DetailedHTMLProps,
@@ -21,12 +20,11 @@ interface MarkdownEditorProps
2120
extends DetailedHTMLProps<AllHTMLAttributes<HTMLInputElement>, any> {
2221
onEnter: (e: KeyboardEvent) => void;
2322
onEscape: (e: KeyboardEvent) => void;
24-
onSubmit: () => void;
2523
view: DatabaseView;
2624
}
2725

2826
export const MarkdownEditor = forwardRef(function MarkdownEditor(
29-
{ onEnter, onEscape, onSubmit, view, ...textareaProps }: MarkdownEditorProps,
27+
{ onEnter, onEscape, view, ...inputProps }: MarkdownEditorProps,
3028
ref: Ref<HTMLInputElement>
3129
) {
3230
const shouldAutoPairMarkdown = (app.vault as any).getConfig(
@@ -114,7 +112,7 @@ export const MarkdownEditor = forwardRef(function MarkdownEditor(
114112
return (
115113
<input
116114
rows={1}
117-
{...textareaProps}
115+
{...inputProps}
118116
{...autocompleteProps}
119117
ref={(c: HTMLInputElement) => {
120118
autocompleteProps.ref.current = c;

src/components/cellTypes/Editor/autocomplete.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ import {
1010
getBlockSearchConfig,
1111
getFileSearchConfig,
1212
getHeadingSearchConfig,
13-
} from "./filepicker";
14-
import { getTagSearchConfig } from "./tagpicker";
15-
import { StrategyProps, Textcomplete } from "./textcomplete/textcomplete-core";
16-
import { TextareaEditor } from "./textcomplete/textcomplete-textarea";
13+
} from "components/cellTypes/Editor/filepicker";
14+
import { getTagSearchConfig } from "components/cellTypes/Editor/tagpicker";
15+
import {
16+
StrategyProps,
17+
Textcomplete,
18+
} from "components/cellTypes/Editor/textcomplete/textcomplete-core";
19+
import { InputEditor } from "components/cellTypes/Editor/textcomplete/textcomplete-input";
1720

1821
export interface ConstructAutocompleteParams {
1922
inputRef: RefObject<HTMLInputElement>;
@@ -71,7 +74,7 @@ export function constructAutocomplete({
7174
),
7275
];
7376

74-
const editor = new TextareaEditor(inputRef.current);
77+
const editor = new InputEditor(inputRef.current);
7578
const autocomplete = new Textcomplete(editor, configs, {
7679
dropdown: {
7780
parent: getParentBodyElement(inputRef.current),

src/components/cellTypes/Editor/commands.ts

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { insertTextAtCursor } from './insertTextAtCursor';
1+
import { insertTextAtCursor } from 'components/cellTypes/Editor/insertTextAtCursor';
22
import {
33
applyWrappingFormatting,
44
expandSelectionToLineBoundaries,
5-
getStateFromTextarea,
5+
getStateFromInput,
66
replaceSelection,
77
setSelectionRange,
88
toggleLineFormatting,
99
toggleWrappingFormattingCommand,
10-
} from './helpers';
10+
} from 'components/cellTypes/Editor/helpers';
1111

1212
export const commandIds = [
1313
'editor:toggle-blockquote',
@@ -251,56 +251,56 @@ function removeBullet(str: string) {
251251
}
252252

253253
export const commands: Record<string, (ta: HTMLInputElement) => void> = {
254-
'editor:toggle-bold': (textarea: HTMLInputElement) => {
255-
toggleWrappingFormattingCommand(textarea, isBoldedRegEx, unBold, '**');
254+
'editor:toggle-bold': (input: HTMLInputElement) => {
255+
toggleWrappingFormattingCommand(input, isBoldedRegEx, unBold, '**');
256256
},
257-
'editor:toggle-code': (textarea: HTMLInputElement) => {
258-
toggleWrappingFormattingCommand(textarea, isCodeRegEx, unCode, '`');
257+
'editor:toggle-code': (input: HTMLInputElement) => {
258+
toggleWrappingFormattingCommand(input, isCodeRegEx, unCode, '`');
259259
},
260-
'editor:toggle-italics': (textarea: HTMLInputElement) => {
260+
'editor:toggle-italics': (input: HTMLInputElement) => {
261261
toggleWrappingFormattingCommand(
262-
textarea,
262+
input,
263263
isItalicizedRegEx,
264264
unItalicize,
265265
'*'
266266
);
267267
},
268-
'editor:toggle-highlight': (textarea: HTMLInputElement) => {
268+
'editor:toggle-highlight': (input: HTMLInputElement) => {
269269
toggleWrappingFormattingCommand(
270-
textarea,
270+
input,
271271
isHighlightedRegEx,
272272
unHighlight,
273273
'=='
274274
);
275275
},
276-
'editor:toggle-strikethrough': (textarea: HTMLInputElement) => {
277-
toggleWrappingFormattingCommand(textarea, isStrikedRegEx, unStrike, '~~');
276+
'editor:toggle-strikethrough': (input: HTMLInputElement) => {
277+
toggleWrappingFormattingCommand(input, isStrikedRegEx, unStrike, '~~');
278278
},
279-
'editor:toggle-blockquote': (textarea: HTMLInputElement) => {
280-
toggleLineFormatting(textarea, isQuoted, applyQuote, removeQuote);
279+
'editor:toggle-blockquote': (input: HTMLInputElement) => {
280+
toggleLineFormatting(input, isQuoted, applyQuote, removeQuote);
281281
},
282-
'editor:toggle-bullet-list': (textarea: HTMLInputElement) => {
283-
toggleLineFormatting(textarea, isBulleted, applyBullet, removeBullet);
282+
'editor:toggle-bullet-list': (input: HTMLInputElement) => {
283+
toggleLineFormatting(input, isBulleted, applyBullet, removeBullet);
284284
},
285-
'editor:toggle-numbered-list': (textarea: HTMLInputElement) => {
285+
'editor:toggle-numbered-list': (input: HTMLInputElement) => {
286286
toggleLineFormatting(
287-
textarea,
287+
input,
288288
isOrderedList,
289289
applyOrderedList,
290290
removeOrderedList
291291
);
292292
},
293293

294-
'editor:toggle-checklist-status': (textarea: HTMLInputElement) => {
295-
const state = getStateFromTextarea(textarea);
294+
'editor:toggle-checklist-status': (input: HTMLInputElement) => {
295+
const state = getStateFromInput(input);
296296
const isEmptySelection = state.selection.end === state.selection.start;
297297

298298
const lineRange = expandSelectionToLineBoundaries({
299299
text: state.text,
300300
selection: state.selection,
301301
});
302302

303-
const selection = setSelectionRange(textarea, lineRange);
303+
const selection = setSelectionRange(input, lineRange);
304304

305305
let newLines = selection.selectedText;
306306

@@ -327,17 +327,17 @@ export const commands: Record<string, (ta: HTMLInputElement) => void> = {
327327
}
328328
}
329329

330-
const newState = replaceSelection(textarea, newLines);
330+
const newState = replaceSelection(input, newLines);
331331

332332
if (isEmptySelection) {
333333
const diff = newLines.length - selection.selectedText.length;
334334

335-
setSelectionRange(textarea, {
335+
setSelectionRange(input, {
336336
start: state.selection.start + diff,
337337
end: state.selection.end + diff,
338338
});
339339
} else {
340-
setSelectionRange(textarea, {
340+
setSelectionRange(input, {
341341
start: selection.selection.start,
342342
end: newState.selection.end,
343343
});
@@ -349,24 +349,24 @@ export const autoPairBracketsCommands: Record<
349349
string,
350350
(ta: HTMLInputElement) => boolean
351351
> = {
352-
'(': (textarea) => applyWrappingFormatting(textarea, '(', ')', false),
353-
'[': (textarea) => applyWrappingFormatting(textarea, '[', ']', false, true),
354-
'{': (textarea) => applyWrappingFormatting(textarea, '{', '}', false),
355-
"'": (textarea) => applyWrappingFormatting(textarea, "'", "'", false),
356-
'"': (textarea) => applyWrappingFormatting(textarea, '"', '"', false),
352+
'(': (input) => applyWrappingFormatting(input, '(', ')', false),
353+
'[': (input) => applyWrappingFormatting(input, '[', ']', false, true),
354+
'{': (input) => applyWrappingFormatting(input, '{', '}', false),
355+
"'": (input) => applyWrappingFormatting(input, "'", "'", false),
356+
'"': (input) => applyWrappingFormatting(input, '"', '"', false),
357357
};
358358

359359
export const autoPairMarkdownCommands: Record<
360360
string,
361361
(ta: HTMLInputElement) => boolean
362362
> = {
363-
'*': (textarea) => applyWrappingFormatting(textarea, '*', '*', false),
364-
_: (textarea) => applyWrappingFormatting(textarea, '_', '_', false),
365-
'`': (textarea) => applyWrappingFormatting(textarea, '`', '`', false),
366-
'=': (textarea) => applyWrappingFormatting(textarea, '=', '=', true),
367-
'~': (textarea) => applyWrappingFormatting(textarea, '~', '~', true),
368-
$: (textarea) => applyWrappingFormatting(textarea, '$', '$', true),
369-
'%': (textarea) => applyWrappingFormatting(textarea, '%', '%', true),
363+
'*': (input) => applyWrappingFormatting(input, '*', '*', false),
364+
_: (input) => applyWrappingFormatting(input, '_', '_', false),
365+
'`': (input) => applyWrappingFormatting(input, '`', '`', false),
366+
'=': (input) => applyWrappingFormatting(input, '=', '=', true),
367+
'~': (input) => applyWrappingFormatting(input, '~', '~', true),
368+
$: (input) => applyWrappingFormatting(input, '$', '$', true),
369+
'%': (input) => applyWrappingFormatting(input, '%', '%', true),
370370
};
371371

372372
const pairMap: Record<string, string> = {
@@ -385,10 +385,10 @@ const pairMap: Record<string, string> = {
385385
};
386386

387387
export function unpair(
388-
textarea: HTMLInputElement,
388+
input: HTMLInputElement,
389389
commandList: Record<string, (ta: HTMLInputElement) => boolean>
390390
) {
391-
const state = getStateFromTextarea(textarea);
391+
const state = getStateFromInput(input);
392392

393393
if (
394394
state.selection.end !== state.selection.start ||
@@ -401,23 +401,23 @@ export function unpair(
401401
const next = state.text[state.selection.end];
402402

403403
if (commandList[char] && next === pairMap[char]) {
404-
setSelectionRange(textarea, {
404+
setSelectionRange(input, {
405405
start: state.selection.end,
406406
end: state.selection.end + 1,
407407
});
408408

409-
replaceSelection(textarea, '');
409+
replaceSelection(input, '');
410410

411411
return true;
412412
}
413413
}
414414

415-
export function unpairBrackets(textarea: HTMLInputElement) {
416-
return unpair(textarea, autoPairBracketsCommands);
415+
export function unpairBrackets(input: HTMLInputElement) {
416+
return unpair(input, autoPairBracketsCommands);
417417
}
418418

419-
export function unpairMarkdown(textarea: HTMLInputElement) {
420-
return unpair(textarea, autoPairMarkdownCommands);
419+
export function unpairMarkdown(input: HTMLInputElement) {
420+
return unpair(input, autoPairMarkdownCommands);
421421
}
422422

423423
function applyTab(str: string, useTab: boolean, tabWidth: number) {
@@ -448,26 +448,26 @@ function removeTab(str: string, useTab: boolean, tabWidth: number) {
448448
}
449449

450450
export function handleTab(
451-
textarea: HTMLInputElement,
451+
input: HTMLInputElement,
452452
isShiftPressed: boolean,
453453
useTab: boolean,
454454
tabWidth: number
455455
) {
456-
const initialState = getStateFromTextarea(textarea);
456+
const initialState = getStateFromInput(input);
457457

458458
if (isShiftPressed) {
459459
const lineRange = expandSelectionToLineBoundaries(initialState);
460-
const selection = setSelectionRange(textarea, lineRange);
460+
const selection = setSelectionRange(input, lineRange);
461461

462462
replaceSelection(
463-
textarea,
463+
input,
464464
removeTab(selection.selectedText, useTab, tabWidth)
465465
);
466466

467467
if (initialState.selection.start === initialState.selection.end) {
468468
const selectionAdjust = useTab ? 1 : tabWidth;
469469

470-
setSelectionRange(textarea, {
470+
setSelectionRange(input, {
471471
start: initialState.selection.start - selectionAdjust,
472472
end: initialState.selection.end - selectionAdjust,
473473
});
@@ -477,7 +477,7 @@ export function handleTab(
477477
}
478478

479479
const lineRange = expandSelectionToLineBoundaries(initialState);
480-
const selection = setSelectionRange(textarea, lineRange);
480+
const selection = setSelectionRange(input, lineRange);
481481

482482
const withTab = applyTab(selection.selectedText, useTab, tabWidth);
483483
const withInitializedOrdinal = withTab.replace(
@@ -487,51 +487,51 @@ export function handleTab(
487487
}
488488
);
489489

490-
replaceSelection(textarea, withInitializedOrdinal);
490+
replaceSelection(input, withInitializedOrdinal);
491491

492492
return true;
493493
}
494494

495-
export function handleNewLine(textarea: HTMLInputElement) {
496-
const initialState = getStateFromTextarea(textarea);
495+
export function handleNewLine(input: HTMLInputElement) {
496+
const initialState = getStateFromInput(input);
497497

498498
if (initialState.selection.start !== initialState.selection.end) {
499499
return false;
500500
}
501501

502502
const lineRange = expandSelectionToLineBoundaries(initialState);
503-
const before = textarea.value.slice(
503+
const before = input.value.slice(
504504
lineRange.start,
505505
initialState.selection.end
506506
);
507507

508-
const line = textarea.value.slice(lineRange.start, lineRange.end);
508+
const line = input.value.slice(lineRange.start, lineRange.end);
509509

510510
// Remove bullet list
511511
if (/^(\s*[-*+]\s+(?:\[[^\]]\]\s*)?)$/.test(line)) {
512-
setSelectionRange(textarea, {
512+
setSelectionRange(input, {
513513
start: lineRange.start - 1,
514514
end: lineRange.end,
515515
});
516-
replaceSelection(textarea, '\n');
516+
replaceSelection(input, '\n');
517517
return true;
518518
}
519519

520520
// Remove ordered list
521521
if (/^(\s*\d[.)]\s+(?:\[[^\]]\]\s*)?)$/.test(line)) {
522-
setSelectionRange(textarea, {
522+
setSelectionRange(input, {
523523
start: lineRange.start - 1,
524524
end: lineRange.end,
525525
});
526-
replaceSelection(textarea, '\n');
526+
replaceSelection(input, '\n');
527527
return true;
528528
}
529529

530530
// Maintain bullet list
531531
if (isBulleted.test(before)) {
532532
const pre = before.match(/^(\s*[-*+]\s+(?:\[[^\]]\]\s*)?)/)[1];
533533
insertTextAtCursor(
534-
textarea,
534+
input,
535535
`\n${pre.replace(/^(\s*[-*+]\s+)\[[^\]]\]/, '$1[ ]')}`
536536
);
537537
return true;
@@ -547,7 +547,7 @@ export function handleNewLine(textarea: HTMLInputElement) {
547547
return `${space}${parseInt(number) + 1}`;
548548
}
549549
);
550-
insertTextAtCursor(textarea, `\n${withIncrementedOrdinal}`);
550+
insertTextAtCursor(input, `\n${withIncrementedOrdinal}`);
551551
return true;
552552
}
553553

src/components/cellTypes/Editor/filepicker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { c } from 'helpers/StylesHelper';
44
import { App, TFile, setIcon } from 'obsidian';
55
import StateManager from 'StateManager';
66

7-
import { StrategyProps } from './textcomplete/textcomplete-core';
7+
import { StrategyProps } from 'components/cellTypes/Editor/textcomplete/textcomplete-core';
88

99
const linkRegex = /\B\[\[([^\]]*)$/;
1010
const embedRegex = /\B!\[\[([^\]]*)$/;

0 commit comments

Comments
 (0)