mirror of
https://github.com/c-degni/text-autocomplete.git
synced 2026-07-22 05:49:39 +00:00
Changed custom dict scrollbar and fixed suggestion dropdown
This commit is contained in:
parent
525f3f207e
commit
9a34f12aa7
6 changed files with 46 additions and 158 deletions
|
|
@ -2,6 +2,6 @@ import { Trie } from './trie';
|
|||
import { DEFAULT_WORDS } from './words'
|
||||
|
||||
let DEFAULT_TRIE = new Trie();
|
||||
DEFAULT_WORDS.forEach(word => DEFAULT_TRIE.insert(word.toLowerCase()));
|
||||
DEFAULT_WORDS.forEach(word => DEFAULT_TRIE.insert(word));
|
||||
|
||||
export { DEFAULT_TRIE };
|
||||
155
main.ts
155
main.ts
|
|
@ -41,7 +41,7 @@ export default class TAPlugin extends Plugin {
|
|||
destroyTAUI();
|
||||
}
|
||||
|
||||
// Load respective settings
|
||||
// Load respective plugin data
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
|
|
@ -51,15 +51,10 @@ export default class TAPlugin extends Plugin {
|
|||
this.settings.customDict.forEach(word => this.wordTrie.insert(word));
|
||||
}
|
||||
|
||||
// Save respective settings
|
||||
// Save settings
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
|
||||
// // Save word trie
|
||||
// async saveWordTrie() {
|
||||
// await this.saveData(this.wordTrie);
|
||||
// }
|
||||
|
||||
// Handles event of text being typed in document
|
||||
handleEditorChange(editor: Editor) {
|
||||
|
|
@ -77,17 +72,16 @@ export default class TAPlugin extends Plugin {
|
|||
return;
|
||||
}
|
||||
|
||||
const match = beforeCursor.match(/(\b\w+)$/); // Match contains word at the end of string
|
||||
const match = beforeCursor.match(/(\b[\w']+)$/);; // Match contains word at the end of string
|
||||
// No matches (word at the end of the string)
|
||||
if (!match) {
|
||||
destroyTAUI();
|
||||
return;
|
||||
}
|
||||
|
||||
const word: string = match[1].toLowerCase();
|
||||
const word: string = match[1];
|
||||
const suggestions: string[] = this.wordTrie.findWordsWithPrefix(word, this.settings.maxSuggestions)
|
||||
.filter((w: string) => w !== word);
|
||||
// const suggestions = WORDS.filter(w => w.startsWith(word) && w !== word).slice(0, this.settings.maxSuggestions);
|
||||
|
||||
if (suggestions.length > 0) {
|
||||
updateSuggestions(suggestions, editor, match[1]);
|
||||
|
|
@ -122,143 +116,4 @@ export default class TAPlugin extends Plugin {
|
|||
items.forEach((item, i) => item.classList.toggle('active', i === index)); // Updates which suggestion is tagged active
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// import { App, DropdownComponent, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
|
||||
|
||||
// // Remember to rename these classes and interfaces!
|
||||
|
||||
// interface PluginSettings {
|
||||
// mySetting: string;
|
||||
// }
|
||||
|
||||
// const DEFAULT_SETTINGS: PluginSettings = {
|
||||
// mySetting: 'default'
|
||||
// }
|
||||
|
||||
// export default class TAPlugin extends Plugin {
|
||||
// settings: PluginSettings;
|
||||
|
||||
// async onload() {
|
||||
// await this.loadSettings();
|
||||
|
||||
// // This creates an icon in the left ribbon.
|
||||
// const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
|
||||
// // Called when the user clicks the icon.
|
||||
// new Notice('This is a notice!');
|
||||
// });
|
||||
// // Perform additional things with the ribbon
|
||||
// ribbonIconEl.addClass('my-plugin-ribbon-class');
|
||||
|
||||
// // This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
||||
// const statusBarItemEl = this.addStatusBarItem();
|
||||
// statusBarItemEl.setText('Status Bar Text');
|
||||
|
||||
// // This adds a simple command that can be triggered anywher
|
||||
// this.addCommand({
|
||||
// id: 'open-sample-modal-simple',
|
||||
// name: 'Open sample modal (simple)',
|
||||
// callback: () => {
|
||||
// new SampleModal(this.app).open();
|
||||
// }
|
||||
// });
|
||||
// // This adds an editor command that can perform some operation on the current editor instance
|
||||
// this.addCommand({
|
||||
// id: 'sample-editor-command',
|
||||
// name: 'Sample editor command',
|
||||
// editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
// console.log(editor.getSelection());
|
||||
// editor.replaceSelection('Sample Editor Command');
|
||||
// }
|
||||
// });
|
||||
// // This adds a complex command that can check whether the current state of the app allows execution of the command
|
||||
// this.addCommand({
|
||||
// id: 'open-sample-modal-complex',
|
||||
// name: 'Open sample modal (complex)',
|
||||
// checkCallback: (checking: boolean) => {
|
||||
// // Conditions to check
|
||||
// const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
// if (markdownView) {
|
||||
// // If checking is true, we're simply "checking" if the command can be run.
|
||||
// // If checking is false, then we want to actually perform the operation.
|
||||
// if (!checking) {
|
||||
// new SampleModal(this.app).open();
|
||||
// }
|
||||
|
||||
// // This command will only show up in Command Palette when the check function returns true
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// // This adds a settings tab so the user can configure various aspects of the plugin
|
||||
// this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||
|
||||
// // If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
|
||||
// // Using this function will automatically remove the event listener when this plugin is disabled.
|
||||
// this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
|
||||
// console.log('click', evt);
|
||||
// });
|
||||
|
||||
// // When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||
// this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
|
||||
// }
|
||||
|
||||
// onunload() {
|
||||
|
||||
// }
|
||||
|
||||
// async loadSettings() {
|
||||
// this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
// }
|
||||
|
||||
// async saveSettings() {
|
||||
// await this.saveData(this.settings);
|
||||
// }
|
||||
// }
|
||||
|
||||
// class SuggestedWordDropdown extends DropdownComponent {
|
||||
|
||||
// }
|
||||
|
||||
// class SampleModal extends Modal {
|
||||
// constructor(app: App) {
|
||||
// super(app);
|
||||
// }
|
||||
|
||||
// onOpen() {
|
||||
// const {contentEl} = this;
|
||||
// contentEl.setText('Woah!');
|
||||
// }
|
||||
|
||||
// onClose() {
|
||||
// const {contentEl} = this;
|
||||
// contentEl.empty();
|
||||
// }
|
||||
// }
|
||||
|
||||
// class SampleSettingTab extends PluginSettingTab {
|
||||
// plugin: TAPlugin;
|
||||
|
||||
// constructor(app: App, plugin: TAPlugin) {
|
||||
// super(app, plugin);
|
||||
// this.plugin = plugin;
|
||||
// }
|
||||
|
||||
// display(): void {
|
||||
// const {containerEl} = this;
|
||||
|
||||
// containerEl.empty();
|
||||
|
||||
// new Setting(containerEl)
|
||||
// .setName('Setting #1')
|
||||
// .setDesc('It\'s a secret')
|
||||
// .addText(text => text
|
||||
// .setPlaceholder('Enter your secret')
|
||||
// .setValue(this.plugin.settings.mySetting)
|
||||
// .onChange(async (value) => {
|
||||
// this.plugin.settings.mySetting = value;
|
||||
// await this.plugin.saveSettings();
|
||||
// }));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
15
settings.ts
15
settings.ts
|
|
@ -36,7 +36,7 @@ export class TASettingsTab extends PluginSettingTab {
|
|||
// Autocomplete setting
|
||||
new Setting(containerEl)
|
||||
.setName('Autocomplete')
|
||||
.setDesc('Enable/disable autocomplete feature.')
|
||||
.setDesc('Enable/disable the autocomplete feature.')
|
||||
.addToggle(toggle =>
|
||||
toggle.setValue(this.plugin.settings.enabled)
|
||||
.onChange(async val => {
|
||||
|
|
@ -47,7 +47,7 @@ export class TASettingsTab extends PluginSettingTab {
|
|||
// Language setting
|
||||
new Setting(containerEl)
|
||||
.setName('Language')
|
||||
.setDesc('Specify text language support.')
|
||||
.setDesc('Specify text language support (only English is supported at the moment).')
|
||||
.addDropdown(dropdown =>
|
||||
dropdown.addOption('English', 'English')
|
||||
.setValue(this.plugin.settings.language)
|
||||
|
|
@ -77,7 +77,7 @@ export class TASettingsTab extends PluginSettingTab {
|
|||
text.setPlaceholder('e.g. tiktok');
|
||||
text.inputEl.addEventListener('keydown', async (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
const word = text.getValue().trim().toLowerCase();
|
||||
const word = text.getValue().trim();
|
||||
if (word && !this.plugin.settings.customDict.includes(word)) {
|
||||
this.plugin.settings.customDict.push(word);
|
||||
this.plugin.wordTrie.insert(word);
|
||||
|
|
@ -91,8 +91,15 @@ export class TASettingsTab extends PluginSettingTab {
|
|||
|
||||
// Manage custom dictionary subsetting
|
||||
if (this.plugin.settings.customDict.length > 0) {
|
||||
// containerEl.createEl('h3', { text: 'Custom Dictionary Contents' });
|
||||
const scrollContainer = containerEl.createDiv({ cls: 'custom-word-scroll' });
|
||||
|
||||
scrollContainer.addEventListener('scroll', () => {
|
||||
scrollContainer.classList.add('show');
|
||||
clearTimeout((scrollContainer as any).scrollTimeout);
|
||||
(scrollContainer as any).scrollTimeout = setTimeout(() => {
|
||||
scrollContainer.classList.remove('show');
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
this.plugin.settings.customDict.forEach((word, index) => {
|
||||
const row = new Setting(scrollContainer)
|
||||
|
|
|
|||
26
styles.css
26
styles.css
|
|
@ -12,3 +12,29 @@
|
|||
.autocomplete-dropdown li:hover {
|
||||
background-color: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.custom-word-scroll {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
padding-left: 10px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.custom-word-scroll::-webkit-scrollbar {
|
||||
background-color: transparent;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.custom-word-scroll.show::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(100, 100, 100, 0.5);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.custom-word-scroll:not(.show)::-webkit-scrollbar-thumb {
|
||||
background-color: transparent;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.custom-word-scroll::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
4
ui.ts
4
ui.ts
|
|
@ -30,7 +30,7 @@ export function updateSuggestions(suggestions: string[], editor: Editor, baseWor
|
|||
const cursor = editor.getCursor();
|
||||
const line = editor.getLine(cursor.line);
|
||||
const beforeCursor = line.substring(0, cursor.ch);
|
||||
const match = beforeCursor.match(/(\b\w+)$/);
|
||||
const match = beforeCursor.match(/(\b[\w']+)$/);
|
||||
if (match) {
|
||||
editor.replaceRange(
|
||||
suggestion,
|
||||
|
|
@ -49,7 +49,7 @@ export function updateSuggestions(suggestions: string[], editor: Editor, baseWor
|
|||
position: 'absolute',
|
||||
top: `${coords.bottom + window.scrollY}px`,
|
||||
left: `${coords.left + window.scrollX}px`,
|
||||
zIndex: 1000,
|
||||
zIndex: 50,
|
||||
backgroundColor: 'var(--background-primary)',
|
||||
border: '1px solid var(--divider-color)',
|
||||
borderRadius: '4px',
|
||||
|
|
|
|||
2
words.ts
2
words.ts
|
|
@ -4,7 +4,7 @@ const DEFAULT_WORDS : string[] = [
|
|||
"and",
|
||||
"to",
|
||||
"in",
|
||||
"i",
|
||||
"I",
|
||||
"that",
|
||||
"was",
|
||||
"his",
|
||||
|
|
|
|||
Loading…
Reference in a new issue