obsidian#Editor TypeScript Examples
The following examples show how to use
obsidian#Editor.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts From obsidian-editor-shortcuts with MIT License | 7 votes |
findAllMatchPositions = ({
editor,
searchText,
searchWithinWords,
documentContent,
}: {
editor: Editor;
searchText: string;
searchWithinWords: boolean;
documentContent: string;
}) => {
const matches = findAllMatches({
searchText,
searchWithinWords,
documentContent,
});
const matchPositions = [];
for (const match of matches) {
matchPositions.push({
anchor: editor.offsetToPos(match.index),
head: editor.offsetToPos(match.index + searchText.length),
});
}
return matchPositions;
}
Example #2
Source File: utils.ts From nldates-obsidian with MIT License | 7 votes |
export function getSelectedText(editor: Editor): string {
if (editor.somethingSelected()) {
return editor.getSelection();
} else {
const wordBoundaries = getWordBoundaries(editor);
editor.setSelection(wordBoundaries.from, wordBoundaries.to); // TODO check if this needs to be updated/improved
return editor.getSelection();
}
}
Example #3
Source File: utils.ts From obsidian-editor-shortcuts with MIT License | 7 votes |
getSearchText = ({
editor,
allSelections,
autoExpand,
}: {
editor: Editor;
allSelections: EditorSelection[];
autoExpand: boolean;
}) => {
// Don't search if multiple selection contents are not identical
const singleSearchText = hasSameSelectionContent(editor, allSelections);
const firstSelection = allSelections[0];
const { from, to } = getSelectionBoundaries(firstSelection);
let searchText = editor.getRange(from, to);
if (searchText.length === 0 && autoExpand) {
const wordRange = wordRangeAtPos(from, editor.getLine(from.line));
searchText = editor.getRange(wordRange.anchor, wordRange.head);
}
return {
searchText,
singleSearchText,
};
}
Example #4
Source File: utils.ts From obsidian-map-view with GNU General Public License v3.0 | 7 votes |
/**
* Go to a character index in the note
* @param editor The Obsidian Editor instance
* @param fileLocation The character index in the file to go to
* @param highlight If true will select the whole line
*/
export async function goToEditorLocation(
editor: Editor,
fileLocation: number,
highlight: boolean
) {
if (fileLocation) {
let pos = editor.offsetToPos(fileLocation);
if (highlight) {
const lineContent = editor.getLine(pos.line);
editor.setSelection(
{ ch: 0, line: pos.line },
{ ch: lineContent.length, line: pos.line }
);
} else {
editor.setCursor(pos);
editor.refresh();
}
}
editor.focus();
}
Example #5
Source File: util.ts From obsidian-charts with GNU Affero General Public License v3.0 | 7 votes |
export async function saveImageToVaultAndPaste(editor: Editor, app: App, renderer: Renderer, source: TFile, settings: ChartPluginSettings) {
const image = await renderer.imageRenderer(editor.getSelection(), settings.imageSettings);
console.log("image converted")
const file = await app.vault.createBinary(
//@ts-ignore
await app.vault.getAvailablePathForAttachments(`Chart ${new Date().toDateString()}`, settings.imageSettings.format.split('/').last(), source),
base64ToArrayBuffer(image)
);
console.log("Image saved")
editor.replaceSelection(app.fileManager.generateMarkdownLink(file, source.path));
}
Example #6
Source File: utils.ts From obsidian-map-view with GNU General Public License v3.0 | 7 votes |
// Creates or modifies a front matter that has the field `fieldName: fieldValue`.
// Returns true if a change to the note was made.
export function verifyOrAddFrontMatter(
editor: Editor,
fieldName: string,
fieldValue: string
): boolean {
const content = editor.getValue();
const frontMatterRegex = /^---(.*?)^---/ms;
const frontMatter = content.match(frontMatterRegex);
const existingFieldRegex = new RegExp(`^---.*${fieldName}:.*^---`, 'ms');
const existingField = content.match(existingFieldRegex);
const cursorLocation = editor.getCursor();
// That's not the best usage of the API, and rather be converted to editor transactions or something else
// that can preserve the cursor position better
if (frontMatter && !existingField) {
const replaced = `---${frontMatter[1]}${fieldName}: ${fieldValue}\n---`;
editor.setValue(content.replace(frontMatterRegex, replaced));
editor.setCursor({
line: cursorLocation.line + 1,
ch: cursorLocation.ch,
});
return true;
} else if (!frontMatter) {
const newFrontMatter = `---\n${fieldName}: ${fieldValue}\n---\n\n`;
editor.setValue(newFrontMatter + content);
editor.setCursor({
line: cursorLocation.line + newFrontMatter.split('\n').length - 1,
ch: cursorLocation.ch,
});
return true;
}
return false;
}
Example #7
Source File: actions.ts From obsidian-editor-shortcuts with MIT License | 6 votes |
joinLines = (editor: Editor, selection: EditorSelection) => {
const { line } = selection.head;
const endOfCurrentLine = getLineEndPos(line, editor);
if (line < editor.lineCount() - 1) {
const endOfNextLine = getLineEndPos(line + 1, editor);
const contentsOfNextLine = editor
.getLine(line + 1)
.replace(/^\s*((-|\+|\*|\d+\.) )?/, '');
editor.replaceRange(
contentsOfNextLine.length > 0
? ' ' + contentsOfNextLine
: contentsOfNextLine,
endOfCurrentLine,
endOfNextLine,
);
}
return { anchor: endOfCurrentLine };
}
Example #8
Source File: main.ts From obsidian-linter with MIT License | 6 votes |
runLinterEditor(editor: Editor) {
console.log('running linter');
const file = this.app.workspace.getActiveFile();
const oldText = editor.getValue();
const newText = this.lintText(oldText, file);
// Replace changed lines
const dmp = new DiffMatchPatch.diff_match_patch(); // eslint-disable-line new-cap
const changes = dmp.diff_main(oldText, newText);
let curText = '';
changes.forEach((change) => {
function endOfDocument(doc: string) {
const lines = doc.split('\n');
return {line: lines.length - 1, ch: lines[lines.length - 1].length};
}
const [type, value] = change;
if (type == DiffMatchPatch.DIFF_INSERT) {
editor.replaceRange(value, endOfDocument(curText));
curText += value;
} else if (type == DiffMatchPatch.DIFF_DELETE) {
const start = endOfDocument(curText);
let tempText = curText;
tempText += value;
const end = endOfDocument(tempText);
editor.replaceRange('', start, end);
} else {
curText += value;
}
});
const charsAdded = changes.map((change) => change[0] == DiffMatchPatch.DIFF_INSERT ? change[1].length : 0).reduce((a, b) => a + b, 0);
const charsRemoved = changes.map((change) => change[0] == DiffMatchPatch.DIFF_DELETE ? change[1].length : 0).reduce((a, b) => a + b, 0);
this.displayChangedMessage(charsAdded, charsRemoved);
}
Example #9
Source File: main.ts From obsidian-emoji-shortcodes with MIT License | 6 votes |
onTrigger(cursor: EditorPosition, editor: Editor, _: TFile): EditorSuggestTriggerInfo | null {
if (this.plugin.settings.suggester) {
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
const match = sub.match(/:\S+$/)?.first();
if (match) {
return {
end: cursor,
start: {
ch: sub.lastIndexOf(match),
line: cursor.line,
},
query: match,
}
}
}
return null;
}
Example #10
Source File: customContextMenu.ts From obsidian-dictionary with GNU Affero General Public License v3.0 | 6 votes |
export default function handleContextMenu(menu: Menu, instance: Editor, plugin: DictionaryPlugin): void {
if (!plugin.settings.shouldShowCustomContextMenu) {
return;
}
const selection = instance.getSelection();
if (selection && selection.trim().split(" ").length === 1) {
if (!plugin.settings.shouldShowSynonymPopover) {
menu.addItem((item) => {
item.setTitle(t('Show Synonyms'))
.setIcon('synonyms')
.onClick(async (_) => {
plugin.handlePointerUp();
});
});
}
menu.addItem((item) => {
item.setTitle(t('Look up'))
.setIcon('quote-glyph')
.onClick(async (_) => {
let leaf: WorkspaceLeaf = plugin.app.workspace.getLeavesOfType(VIEW_TYPE).first();
if(!leaf){
leaf = plugin.app.workspace.getRightLeaf(false);
await leaf.setViewState({
type: VIEW_TYPE,
});
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
leaf.view.query(selection.trim());
plugin.app.workspace.revealLeaf(leaf);
});
});
}
}
Example #11
Source File: chartFromTable.ts From obsidian-charts with GNU Affero General Public License v3.0 | 6 votes |
export async function chartFromTable(editor: Editor, layout: 'columns' | 'rows') {
const {labels, dataFields} = generateTableData(editor.getSelection(), layout);
const chart = `\`\`\`chart
type: bar
labels: [${labels}]
series:
${dataFields
.map((data) => ` - title: ${data.dataTitle}\n data: [${data.data}]`)
.join("\n")}
width: 80%
beginAtZero: true
\`\`\``;
editor.replaceSelection(chart);
}
Example #12
Source File: main.ts From quick_latex_obsidian with MIT License | 6 votes |
private readonly withinAnyBrackets_document = (
editor: Editor,
open_symbol: string,
close_symbol: string
): Boolean => {
const document_text = editor.getValue()
const cursorPos = editor.getCursor()
const cursor_index = editor.posToOffset(cursorPos)
// count open symbols
let from = 0;
let found = document_text.indexOf(open_symbol, from);
let count = 0;
while (found != -1 && found < cursor_index) {
count += 1;
from = found + 1;
found = document_text.indexOf(open_symbol, from);
}
const open_symbol_counts = count
// count close symbols
from = 0;
found = document_text.indexOf(close_symbol, from);
count = 0;
while (found != -1 && found < cursor_index) {
count += 1;
from = found + 1;
found = document_text.indexOf(close_symbol, from);
}
const close_symbol_counts = count
return open_symbol_counts > close_symbol_counts;
};
Example #13
Source File: actions.ts From obsidian-editor-shortcuts with MIT License | 6 votes |
copyLine = (
editor: Editor,
selection: EditorSelection,
direction: 'up' | 'down',
) => {
const { from, to } = getSelectionBoundaries(selection);
const fromLineStart = getLineStartPos(from.line);
const toLineEnd = getLineEndPos(to.line, editor);
const contentsOfSelectedLines = editor.getRange(fromLineStart, toLineEnd);
if (direction === 'up') {
editor.replaceRange('\n' + contentsOfSelectedLines, toLineEnd);
return selection;
} else {
editor.replaceRange(contentsOfSelectedLines + '\n', fromLineStart);
const linesSelected = to.line - from.line + 1;
return {
anchor: { line: to.line + 1, ch: from.ch },
head: { line: to.line + linesSelected, ch: to.ch },
};
}
}
Example #14
Source File: main.ts From quick_latex_obsidian with MIT License | 6 votes |
//utility functions
private readonly unclosed_bracket = (
editor: Editor,
open_symbol: string,
close_symbol: string,
before: number,
after: number,
unclosed_open_symbol: boolean = true //false for unclosed_close_symbol
): [boolean, number[]] => {
// determine if there are unclosed bracket within the range specified by before and after
const position = editor.getCursor();
const text = editor.getRange(
{ line: position.line, ch: after },
{ line: position.line, ch: before });
let open_array: number[] = []
let close_array: number[] = []
for (let i = 0; i < text.length; i++) {
switch (text[i]) {
case open_symbol:
open_array.push(after + i);
break;
case close_symbol:
if (open_array.length > 0) {
open_array.pop()
} else {
close_array.push(after + i);
}
break;
}
}
if (unclosed_open_symbol) {
return [open_array.length > 0, open_array];
} else {
return [close_array.length > 0, close_array];
}
};
Example #15
Source File: actions.ts From obsidian-editor-shortcuts with MIT License | 6 votes |
navigateLine = (
editor: Editor,
selection: EditorSelection,
direction: 'up' | 'down',
) => {
const pos = selection.head;
let line: number;
if (direction === 'up') {
line = Math.max(pos.line - 1, 0);
} else {
line = Math.min(pos.line + 1, editor.lineCount() - 1);
}
const endOfLine = getLineEndPos(line, editor);
const ch = Math.min(pos.ch, endOfLine.ch);
return { anchor: { line, ch } };
}
Example #16
Source File: suggest.ts From obsidian-admonition with MIT License | 6 votes |
onTrigger(
cursor: EditorPosition,
editor: Editor,
file: TFile
): EditorSuggestTriggerInfo {
const line = editor.getLine(cursor.line);
//not inside the bracket
if (/> \[!\w+\]/.test(line.slice(0, cursor.ch))) return null;
if (!/> \[!\w*/.test(line)) return null;
const match = line.match(/> \[!(\w*)\]?/);
if (!match) return null;
const [_, query] = match;
if (
!query ||
Object.keys(this.plugin.admonitions).find(
(p) => p.toLowerCase() == query.toLowerCase()
)
) {
return null;
}
const matchData = {
end: cursor,
start: {
ch: match.index + 4,
line: cursor.line
},
query
};
return matchData;
}
Example #17
Source File: locationSuggest.ts From obsidian-map-view with GNU General Public License v3.0 | 6 votes |
onTrigger(
cursor: EditorPosition,
editor: Editor,
file: TFile
): EditorSuggestTriggerInfo | null {
const currentLink = this.getGeolinkOfCursor(cursor, editor);
if (currentLink)
return {
start: { line: cursor.line, ch: currentLink.index },
end: { line: cursor.line, ch: currentLink.linkEnd },
query: currentLink.name,
};
return null;
}
Example #18
Source File: main.ts From quick_latex_obsidian with MIT License | 6 votes |
private addCasesBlock(editor: Editor) {
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (!view) return;
if (!this.settings.addCasesBlock_toggle) return;
const selected_text = editor.getSelection()
editor.replaceSelection(
'\\begin{cases}\n' +
selected_text +
'\n\\end{cases}'
);
const position = editor.getCursor();
editor.setCursor({ line: position.line - 1, ch: editor.getLine(position.line - 1).length })
}
Example #19
Source File: urlConvertor.ts From obsidian-map-view with GNU General Public License v3.0 | 6 votes |
/**
* Insert a geo link into the editor at the cursor position
* @param location The geolocation to convert to text and insert
* @param editor The Obsidian Editor instance
* @param replaceStart The EditorPosition to start the replacement at. If null will replace any text selected
* @param replaceLength The EditorPosition to stop the replacement at. If null will replace any text selected
*/
insertLocationToEditor(
location: leaflet.LatLng,
editor: Editor,
replaceStart?: EditorPosition,
replaceLength?: number
) {
const locationString = `[](geo:${location.lat},${location.lng})`;
const cursor = editor.getCursor();
if (replaceStart && replaceLength) {
editor.replaceRange(locationString, replaceStart, {
line: replaceStart.line,
ch: replaceStart.ch + replaceLength,
});
} else editor.replaceSelection(locationString);
// We want to put the cursor right after the beginning of the newly-inserted link
const newCursorPos = replaceStart ? replaceStart.ch + 1 : cursor.ch + 1;
editor.setCursor({ line: cursor.line, ch: newCursorPos });
utils.verifyOrAddFrontMatter(editor, 'locations', '');
}
Example #20
Source File: main.ts From obsidian-consistent-attachments-and-links with MIT License | 6 votes |
async collectAttachmentsCurrentNote(editor: Editor, view: MarkdownView) {
let note = view.file;
if (this.isPathIgnored(note.path)) {
new Notice("Note path is ignored");
return;
}
let result = await this.fh.collectAttachmentsForCachedNote(
note.path,
this.settings.attachmentsSubfolder,
this.settings.deleteExistFilesWhenMoveNote);
if (result && result.movedAttachments && result.movedAttachments.length > 0) {
await this.lh.updateChangedPathsInNote(note.path, result.movedAttachments)
}
if (result.movedAttachments.length == 0)
new Notice("No files found that need to be moved");
else
new Notice("Moved " + result.movedAttachments.length + " attachment" + (result.movedAttachments.length > 1 ? "s" : ""));
}
Example #21
Source File: fixtureUtils.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 6 votes |
export function makeLeaf(sourceFile?: TFile): MockProxy<WorkspaceLeaf> {
const mockView = mock<MarkdownView>({
file: sourceFile ?? new TFile(),
editor: mock<Editor>(),
});
mockView.getViewType.mockReturnValue('markdown');
return mock<WorkspaceLeaf>({
view: mockView,
});
}
Example #22
Source File: tools.ts From obsidian-chartsview-plugin with MIT License | 6 votes |
export function insertEditor(editor: Editor, data: string): void {
editor.somethingSelected
?
editor.replaceSelection(data)
:
editor.setLine(
editor.getCursor().line,
data
);
}
Example #23
Source File: date-suggest.ts From nldates-obsidian with MIT License | 6 votes |
onTrigger(
cursor: EditorPosition,
editor: Editor,
file: TFile
): EditorSuggestTriggerInfo {
if (!this.plugin.settings.isAutosuggestEnabled) {
return null;
}
const triggerPhrase = this.plugin.settings.autocompleteTriggerPhrase;
const startPos = this.context?.start || {
line: cursor.line,
ch: cursor.ch - triggerPhrase.length,
};
if (!editor.getRange(startPos, cursor).startsWith(triggerPhrase)) {
return null;
}
const precedingChar = editor.getRange(
{
line: startPos.line,
ch: startPos.ch - 1,
},
startPos
);
// Short-circuit if `@` as a part of a word (e.g. part of an email address)
if (precedingChar && /[`a-zA-Z0-9]/.test(precedingChar)) {
return null;
}
return {
start: startPos,
end: cursor,
query: editor.getRange(startPos, cursor).substring(triggerPhrase.length),
};
}
Example #24
Source File: Autocomplete.ts From Templater with GNU Affero General Public License v3.0 | 6 votes |
onTrigger(
cursor: EditorPosition,
editor: Editor,
file: TFile
): EditorSuggestTriggerInfo | null {
const range = editor.getRange(
{ line: cursor.line, ch: 0 },
{ line: cursor.line, ch: cursor.ch }
);
const match = this.tp_keyword_regex.exec(range);
if (!match) {
return null;
}
let query: string;
const module_name = match.groups["module"] || "";
this.module_name = module_name;
if (match.groups["fn_trigger"]) {
if (module_name == "" || !is_module_name(module_name)) {
return;
}
this.function_trigger = true;
this.function_name = match.groups["fn"] || "";
query = this.function_name;
} else {
this.function_trigger = false;
query = this.module_name;
}
const trigger_info: EditorSuggestTriggerInfo = {
start: { line: cursor.line, ch: cursor.ch - query.length },
end: { line: cursor.line, ch: cursor.ch },
query: query,
};
this.latest_trigger_info = trigger_info;
return trigger_info;
}
Example #25
Source File: main.ts From obsidian-custom-attachment-location with GNU General Public License v3.0 | 6 votes |
async handleDrop(event: DragEvent, editor: Editor, view: MarkdownView){
console.log('Handle Drop');
let mdFileName = view.file.basename;
let mdFolderPath: string = Path.dirname(view.file.path);
let path = this.getAttachmentFolderPath(mdFileName);
let fullPath = this.getAttachmentFolderFullPath(mdFolderPath, mdFileName);
if(!this.useRelativePath && !await this.adapter.exists(fullPath))
await this.app.vault.createFolder(fullPath);
this.updateAttachmentFolderConfig(path);
}
Example #26
Source File: ImgurPlugin.ts From obsidian-imgur-plugin with MIT License | 6 votes |
private static replaceFirstOccurrence(
editor: Editor,
target: string,
replacement: string
) {
const lines = editor.getValue().split("\n");
for (let i = 0; i < lines.length; i += 1) {
const ch = lines[i].indexOf(target);
if (ch !== -1) {
const from = { line: i, ch };
const to = { line: i, ch: ch + target.length };
editor.replaceRange(replacement, from, to);
break;
}
}
}
Example #27
Source File: main.ts From quick_latex_obsidian with MIT License | 6 votes |
private addMatrixBlock(editor: Editor) {
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (!view) return;
if (!this.settings.addMatrixBlock_toggle) return;
editor.replaceSelection(
'\\begin{' + this.settings.addMatrixBlock_parameter + '}' +
'\\end{' + this.settings.addMatrixBlock_parameter + '}'
);
const position = editor.getCursor();
const retract_length = ('\\end{' + this.settings.addMatrixBlock_parameter + '}').length
editor.setCursor({ line: position.line, ch: position.ch - retract_length })
}
Example #28
Source File: plugin-callback.ts From obsidian-imgur-plugin with MIT License | 6 votes |
editorCheckCallbackFor =
(size: ImgurSize) => (checking: boolean, editor: Editor) => {
const lineNumber = editor.getCursor().line;
const match = findImgurMarkdownImage(
editor.getLine(lineNumber),
editor.getCursor().ch
);
if (!match.exists) return false;
if (checking && match.exists) return true;
let replacement;
try {
replacement = resizeTo(size)(match.mdImagePieces);
} catch (e) {
if (e instanceof Error)
// eslint-disable-next-line no-new
new Notice(e.message);
// eslint-disable-next-line no-console
else console.error(e);
return false;
}
editor.replaceRange(
replacement.content,
{ line: lineNumber, ch: replacement.from },
{ line: lineNumber, ch: replacement.to }
);
return true;
}
Example #29
Source File: main.ts From quick_latex_obsidian with MIT License | 6 votes |
private addAlignBlock(editor: Editor) {
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (!view) return;
if (!this.settings.addAlignBlock_toggle) return;
const selected_text = editor.getSelection()
editor.replaceSelection(
'\\begin{' + this.settings.addAlignBlock_parameter + '}\n' +
selected_text +
'\n\\end{' + this.settings.addAlignBlock_parameter + '}'
);
const position = editor.getCursor();
editor.setCursor({ line: position.line - 1, ch: editor.getLine(position.line - 1).length })
}