Skip to content

Commit

Permalink
Merge branch 'release/0.1.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
oliveryh committed Dec 5, 2020
2 parents d28e98e + 06dec89 commit 98ab29e
Showing 7 changed files with 196 additions and 249 deletions.
1 change: 1 addition & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
"presets": [
[
"@babel/preset-env",
"@babel/typescript",
{
"targets": {
"electron": "8.2.5"
279 changes: 91 additions & 188 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,212 +1,115 @@
import { Plugin } from 'obsidian';
import { App, FuzzySuggestModal, Plugin, FuzzyMatch, Notice, MarkdownView } from 'obsidian';
import emoji from 'emojilib';

const QUICK_SWITCHER_ID = 'switcher';
const EMOJIPREFIX = '@';

const indicatorStyle =
const indicatorStyle: string =
'color: var(--text-accent); width: 2.5em; text-align: center; float:left; font-weight:800;';

function getQuickSwitcher(app) {
const switcher = app.internalPlugins.getPluginById(QUICK_SWITCHER_ID);
if (!switcher) {
return null;
}

return switcher.instance.modal.constructor;
}

function createEmojiPickerModal(app, emojis) {
const QuickSwitcher = getQuickSwitcher(app);
if (QuickSwitcher === null) {
return null;
}

class EmojiPicker extends QuickSwitcher {
constructor(app) {
super(app);
}

onOpen() {
// force reset suggestions so any suggestions from a previous operation
// won't be incorrectly used for symbol search
this.chooser.setSuggestions([]);
this.isOpen = true;

// prefix inut with @ symbol
this.inputEl.value = EMOJIPREFIX;
this.inputEl.focus();
this.updateSuggestions();
}

getSearchData() {
const {
inputEl: { value },
} = this;
let startIndex = 0;

startIndex = value.indexOf(EMOJIPREFIX) + EMOJIPREFIX.length;

return EmojiPicker.extractTokens(value, startIndex);
}

static extractTokens(str, startIndex = 0) {
// shamelessly stolen directly from Obsidian
const p = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/;
const u = /[\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff66-\uff9f]/;
const b = /\s/;
const query = str.slice(startIndex).toLowerCase();
const tokens = [];
let pos = 0;

for (let i = 0; i < query.length; i++) {
const char = query.charAt(i);

if (b.test(char)) {
if (pos !== i) {
tokens.push(query.slice(pos, i));
}

pos = i + 1;
} else if (p.test(char) || u.test(char)) {
if (pos !== i) {
tokens.push(query.slice(pos, i));
}

tokens.push(char);
pos = i + 1;
}
}

if (pos !== query.length) {
tokens.push(query.slice(pos, query.length));
}

return { query, tokens, fuzzy: query.split('') };
}

updateSuggestions() {
const searchData = this.getSearchData();
const suggestions = this.makeSuggestions(searchData);

this.chooser.setSuggestions(suggestions);
}
export default class MyPlugin extends Plugin {
emojis: EmojiItem[]

makeSuggestions(searchData) {
const suggestions = [];
const hasSearchTerm = searchData.query.length > 0;

emojis.forEach((item) => {
let sugg;

if (hasSearchTerm) {
const match = this.match(searchData, item);

if (match !== null) {
sugg = {
match,
};
}
} else {
sugg = {
match: null,
};
}

if (sugg) {
sugg.item = item;
suggestions.push(sugg);
}
});

if (hasSearchTerm) {
suggestions.sort((a, b) => b.match.score - a.match.score);
loadEmojis(): EmojiItem[] {
function titleCase(string: string) {
let sentence = string.toLowerCase().split('_');
for (let i = 0; i < sentence.length; i++) {
sentence[i] = sentence[i][0].toUpperCase() + sentence[i].slice(1);
}
return suggestions;
}

getItemText(item) {
const { symbol } = item;

let text;
text = symbol.heading;
return text;

return sentence.join(' ');
}

let items = emoji.ordered.map((name) => {
return {
name: titleCase(name),
char: emoji.lib[name].char,
};
});

return items;
}

insertTextAtCursor(editor, text) {
var doc = editor.getDoc();
var cursor = doc.getCursor();
doc.replaceRange(text, cursor);
}
onload() {

this.emojis = this.loadEmojis();

this.addCommand({
id: 'open-sample-modal',
name: 'Open Sample Modal',
hotkeys: [
{
modifiers: ["Mod", "Shift"],
key: "o",
},
],
checkCallback: (checking: boolean) => {
let leaf = this.app.workspace.activeLeaf;
if (leaf) {
if (!checking) {
new EmojiFuzzySuggestModal(this.app, this.emojis).open();
}
return true;
}
return false;
}
});

}

onunload() {
}
}

onChooseOption(suggestionItem) {
let activeLeaf = this.app.workspace.activeLeaf;
let editor = activeLeaf.view.sourceMode.cmEditor;
this.insertTextAtCursor(editor, suggestionItem.symbol.char);
}
interface EmojiItem {
name: string;
char: string;
}

renderSuggestion(sugg, parentEl) {
super.renderSuggestion(sugg, parentEl);
this.updateSuggestionElForMode(sugg, parentEl);
}

updateSuggestionElForMode(sugg, parentEl) {
const { symbol } = sugg.item;
class EmojiFuzzySuggestModal extends FuzzySuggestModal<EmojiItem> {
app: App;
emojis: EmojiItem[];

const indicatorEl = createEl('div', {
text: symbol.char,
attr: { style: indicatorStyle },
});
parentEl.insertAdjacentElement('afterbegin', indicatorEl);
}
constructor(app: App, emojis: EmojiItem[]) {
super(app);
this.app = app;
this.emojis = emojis;
}

return new EmojiPicker(app);
}

function loadEmojis() {
function titleCase(string) {
let sentence = string.toLowerCase().split('_');
for (let i = 0; i < sentence.length; i++) {
sentence[i] = sentence[i][0].toUpperCase() + sentence[i].slice(1);
}
getItems(): EmojiItem[] {
return this.emojis;
}

return sentence.join(' ');
getItemText(item: EmojiItem): string {
return item.name;
}

let items = emoji.ordered.map((name) => {
return {
symbol: {
heading: titleCase(name),
char: emoji.lib[name].char,
},
};
});
renderSuggestion(item: FuzzyMatch<EmojiItem>, el: HTMLElement) {
super.renderSuggestion(item, el);
this.updateSuggestionElForMode(item, el);
}

return items;
}
updateSuggestionElForMode(item: FuzzyMatch<EmojiItem>, el: HTMLElement) {

export default class EmojiPickerPlugin extends Plugin {
onload() {
this.emojis = loadEmojis();
this.addCommand({
id: 'emoji-picker:open-picker',
name: 'Open emoji picker',
hotkeys: [],
checkCallback: (checking) => {
let leaf = this.app.workspace.activeLeaf;
if (leaf) {
if (!checking) {
new createEmojiPickerModal(this.app, this.emojis).open();
}
return true;
}
return false;
},
const indicatorEl = createEl('div', {
text: item.item.char,
attr: { style: indicatorStyle },
});
el.insertAdjacentElement('afterbegin', indicatorEl);
}

onunload() {
this.modal = null;
insertTextAtCursor(view: MarkdownView, text:string): void {
let editor = view.sourceMode.cmEditor
let doc = editor.getDoc();
let cursor = doc.getCursor();
doc.replaceRange(text, cursor);
}
}

onChooseItem(item: EmojiItem, evt: MouseEvent | KeyboardEvent): void {
let activeEditor = this.app.workspace.getActiveViewOfType(MarkdownView)
if (activeEditor) {
this.insertTextAtCursor(activeEditor, item.char)
} else {
new Notice("You'll need to open a markdown editor to insert an emoji");
}
}
}
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "obsidian-emoji-toolbar",
"name": "Emoji Toolbar",
"version": "0.1.0",
"version": "0.1.1",
"description": "Quickly search for an insert emojis into your notes.",
"author": "oliveryh",
"authorUrl": "https://github.com/oliveryh/obsidian-emoji-toolbar",
Loading

0 comments on commit 98ab29e

Please sign in to comment.