├── .github ├── FUNDING.yml └── workflows │ └── documentation.yml ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── docs ├── advanced-guides │ ├── _category_.json │ ├── react.md │ └── svelte.md ├── api │ ├── _category_.json │ ├── classes │ │ ├── AbstractTextComponent.md │ │ ├── App.md │ │ ├── BaseComponent.md │ │ ├── ButtonComponent.md │ │ ├── Component.md │ │ ├── DropdownComponent.md │ │ ├── EditableFileView.md │ │ ├── Editor.md │ │ ├── EditorSuggest.md │ │ ├── Events.md │ │ ├── ExtraButtonComponent.md │ │ ├── FileManager.md │ │ ├── FileSystemAdapter.md │ │ ├── FileView.md │ │ ├── FuzzySuggestModal.md │ │ ├── HoverPopover.md │ │ ├── ItemView.md │ │ ├── Keymap.md │ │ ├── MarkdownEditView.md │ │ ├── MarkdownPreviewRenderer.md │ │ ├── MarkdownPreviewView.md │ │ ├── MarkdownRenderChild.md │ │ ├── MarkdownRenderer.md │ │ ├── MarkdownSourceView.md │ │ ├── MarkdownView.md │ │ ├── Menu.md │ │ ├── MenuItem.md │ │ ├── MetadataCache.md │ │ ├── Modal.md │ │ ├── MomentFormatComponent.md │ │ ├── Notice.md │ │ ├── PluginSettingTab.md │ │ ├── Plugin_2.md │ │ ├── PopoverSuggest.md │ │ ├── Scope.md │ │ ├── SearchComponent.md │ │ ├── Setting.md │ │ ├── SettingTab.md │ │ ├── SliderComponent.md │ │ ├── SuggestModal.md │ │ ├── TAbstractFile.md │ │ ├── TFile.md │ │ ├── TFolder.md │ │ ├── Tasks.md │ │ ├── TextAreaComponent.md │ │ ├── TextComponent.md │ │ ├── TextFileView.md │ │ ├── ToggleComponent.md │ │ ├── ValueComponent.md │ │ ├── Vault.md │ │ ├── View.md │ │ ├── Workspace.md │ │ ├── WorkspaceItem.md │ │ ├── WorkspaceLeaf.md │ │ ├── WorkspaceMobileDrawer.md │ │ ├── WorkspaceParent.md │ │ ├── WorkspaceRibbon.md │ │ ├── WorkspaceSidedock.md │ │ ├── WorkspaceSplit.md │ │ ├── WorkspaceTabs.md │ │ └── _category_.json │ ├── enums │ │ ├── PopoverState.md │ │ └── _category_.json │ ├── functions │ │ ├── _category_.json │ │ ├── addIcon.md │ │ ├── debounce.md │ │ ├── finishRenderMath.md │ │ ├── fuzzySearch.md │ │ ├── getAllTags.md │ │ ├── getLinkpath.md │ │ ├── htmlToMarkdown.md │ │ ├── iterateCacheRefs.md │ │ ├── iterateRefs.md │ │ ├── loadMathJax.md │ │ ├── loadMermaid.md │ │ ├── loadPdfJs.md │ │ ├── loadPrism.md │ │ ├── normalizePath.md │ │ ├── parseFrontMatterAliases.md │ │ ├── parseFrontMatterEntry.md │ │ ├── parseFrontMatterStringArray.md │ │ ├── parseFrontMatterTags.md │ │ ├── parseLinktext.md │ │ ├── parseYaml.md │ │ ├── prepareFuzzySearch.md │ │ ├── prepareQuery.md │ │ ├── prepareSimpleSearch.md │ │ ├── renderMatches.md │ │ ├── renderMath.md │ │ ├── renderResults.md │ │ ├── request.md │ │ ├── requestUrl.md │ │ ├── requireApiVersion.md │ │ ├── resolveSubpath.md │ │ ├── sanitizeHTMLToDom.md │ │ ├── setIcon.md │ │ ├── sortSearchResults.md │ │ ├── stringifyYaml.md │ │ └── stripHeading.md │ ├── interfaces │ │ ├── AjaxOptions.md │ │ ├── BlockCache.md │ │ ├── BlockSubpathResult.md │ │ ├── CacheItem.md │ │ ├── CachedMetadata.md │ │ ├── CloseableComponent.md │ │ ├── Command.md │ │ ├── Constructor.md │ │ ├── DataAdapter.md │ │ ├── DataWriteOptions.md │ │ ├── Debouncer.md │ │ ├── EditorChange.md │ │ ├── EditorPosition.md │ │ ├── EditorRange.md │ │ ├── EditorRangeOrCaret.md │ │ ├── EditorSelection.md │ │ ├── EditorSelectionOrCaret.md │ │ ├── EditorSuggestContext.md │ │ ├── EditorSuggestTriggerInfo.md │ │ ├── EditorTransaction.md │ │ ├── EmbedCache.md │ │ ├── EventListenerInfo.md │ │ ├── EventRef.md │ │ ├── FileStats.md │ │ ├── FrontMatterCache.md │ │ ├── FuzzyMatch.md │ │ ├── HeadingCache.md │ │ ├── HeadingSubpathResult.md │ │ ├── Hotkey.md │ │ ├── HoverParent.md │ │ ├── ISuggestOwner.md │ │ ├── Instruction.md │ │ ├── KeymapContext.md │ │ ├── KeymapEventHandler.md │ │ ├── KeymapInfo.md │ │ ├── LinkCache.md │ │ ├── ListItemCache.md │ │ ├── ListedFiles.md │ │ ├── Loc.md │ │ ├── MarkdownPostProcessor.md │ │ ├── MarkdownPostProcessorContext.md │ │ ├── MarkdownPreviewEvents.md │ │ ├── MarkdownSectionInformation.md │ │ ├── MarkdownSubView.md │ │ ├── ObsidianProtocolData.md │ │ ├── OpenViewState.md │ │ ├── PluginManifest.md │ │ ├── Point.md │ │ ├── Pos.md │ │ ├── PreparedQuery.md │ │ ├── Rect_2.md │ │ ├── ReferenceCache.md │ │ ├── RequestParam.md │ │ ├── RequestUrlParam.md │ │ ├── RequestUrlResponse.md │ │ ├── SearchResult.md │ │ ├── SearchResultContainer.md │ │ ├── SectionCache.md │ │ ├── Stat.md │ │ ├── SubpathResult.md │ │ ├── TagCache.md │ │ ├── ViewState.md │ │ ├── ViewStateResult.md │ │ └── _category_.json │ ├── overview.md │ └── types │ │ ├── EditorCommandName.md │ │ ├── KeymapEventListener.md │ │ ├── MarkdownViewModeType.md │ │ ├── Modifier.md │ │ ├── ObsidianProtocolHandler.md │ │ ├── SearchMatchPart.md │ │ ├── SearchMatches.md │ │ ├── SplitDirection.md │ │ ├── UserEvent.md │ │ ├── ViewCreator.md │ │ └── _category_.json ├── concepts │ ├── _category_.json │ ├── codemirror.md │ ├── plugin-anatomy.md │ ├── vault.md │ └── workspace.md ├── contribute.md ├── examples │ ├── _category_.json │ └── insert-link.md ├── getting-started │ ├── _category_.json │ ├── create-your-first-plugin.md │ └── development-workflow.md ├── guides │ ├── _category_.json │ ├── commands.md │ ├── context-menus.md │ ├── custom-views.md │ ├── editor.md │ ├── events.md │ ├── html-elements.md │ ├── icons.md │ ├── markdown-post-processing.md │ ├── modals.md │ ├── ribbon-actions.md │ ├── settings.md │ └── status-bar.md ├── introduction.md ├── manifest-reference.md └── publishing │ ├── _category_.json │ ├── release-your-plugin-with-github-actions.md │ ├── submission-guidelines.md │ └── submit-your-plugin.md ├── docusaurus.config.js ├── obsidian.d.ts ├── package.json ├── sidebars.js ├── src ├── css │ └── custom.css └── manifest.schema.json ├── static └── img │ ├── command.png │ ├── context-menu-positions.png │ ├── default-violet.webp │ ├── editor-todays-date.gif │ ├── editor-uppercase.gif │ ├── example-insert-link.gif │ ├── fuzzy-suggestion-modal.png │ ├── logo.svg │ ├── modal-input.png │ ├── settings.png │ ├── status-bar.png │ ├── styles.png │ └── suggest-modal.gif └── yarn.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://buymeacoffee.com/marcusolsson 2 | -------------------------------------------------------------------------------- /.github/workflows/documentation.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | gh-release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - uses: actions/setup-node@v1 14 | with: 15 | node-version: "14.x" 16 | 17 | - name: Add key to allow access to repository 18 | env: 19 | SSH_AUTH_SOCK: /tmp/ssh_agent.sock 20 | run: | 21 | mkdir -p ~/.ssh 22 | ssh-keyscan github.com >> ~/.ssh/known_hosts 23 | echo "${{ secrets.GH_PAGES_DEPLOY }}" > ~/.ssh/id_rsa 24 | chmod 600 ~/.ssh/id_rsa 25 | cat <> ~/.ssh/config 26 | Host github.com 27 | HostName github.com 28 | IdentityFile ~/.ssh/id_rsa 29 | EOT 30 | 31 | - name: Setup Git config 32 | run: | 33 | git config --global user.email "marcus.olsson@hey.com" 34 | git config --global user.name "Marcus Olsson" 35 | 36 | - name: Release to GitHub Pages 37 | env: 38 | USE_SSH: true 39 | GIT_USER: git 40 | run: | 41 | yarn install 42 | yarn deploy 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | .obsidian 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Obsidian Plugin Developer Docs 2 | 3 | [![Documentation](https://github.com/marcusolsson/obsidian-plugin-docs/actions/workflows/documentation.yml/badge.svg)](https://github.com/marcusolsson/obsidian-plugin-docs/actions/workflows/documentation.yml) 4 | [![Buy me a coffee](https://img.shields.io/badge/-buy_me_a%C2%A0coffee-gray?logo=buy-me-a-coffee)](https://www.buymeacoffee.com/marcusolsson) 5 | 6 | This is an **unofficial** documentation page for Obsidian plugin development, written using [Docusaurus](https://docusaurus.io/). 7 | 8 | You can see the hosted version on https://marcus.se.net/obsidian-plugin-docs. 9 | 10 | The Obsidian logo is used with permission. 11 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/advanced-guides/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Advanced guides", 3 | "position": 40 4 | } 5 | -------------------------------------------------------------------------------- /docs/advanced-guides/react.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 77 3 | --- 4 | 5 | # React 6 | 7 | In this guide, you'll configure your plugin to use [React](https://reactjs.org/). It assumes that you already have a plugin with a [custom view](../guides/custom-views.md) that you want to convert to use React. 8 | 9 | While you don't need to use a separate framework to build a plugin, there are a few reasons why you'd want to use React: 10 | 11 | - You have existing experience of React and want to use a familiar technology. 12 | - You have existing React components that you want to reuse in your plugin. 13 | - Your plugin requires complex state management or other features that can be cumbersome to implement with regular [HTML element](../guides/html-elements.md). 14 | 15 | ## Configure your plugin 16 | 17 | 1. Add React to your plugin dependencies: 18 | 19 | ```bash 20 | npm install react react-dom 21 | ``` 22 | 23 | 1. Add type definitions for React: 24 | 25 | ```bash 26 | npm install --save-dev @types/react @types/react-dom 27 | ``` 28 | 29 | 1. In `tsconfig.json`, enable JSX support on the `compilerOptions` object: 30 | 31 | ```ts title="tsconfig.json" 32 | { 33 | "compilerOptions": { 34 | "jsx": "react" 35 | } 36 | } 37 | ``` 38 | 39 | ## Create a React component 40 | 41 | Create a new file called `ReactView.tsx` in the plugin root directory, with the following content: 42 | 43 | ```tsx title="ReactView.tsx" 44 | import * as React from "react"; 45 | 46 | export const ReactView = () => { 47 | return

Hello, React!

; 48 | }; 49 | ``` 50 | 51 | ## Mount the React component 52 | 53 | To use the React component, it needs to be mounted on a [HTML element](../guides/html-elements.md). The following example mounts the `ReactView` component on the `this.containerEl.children[1]` element: 54 | 55 | ```tsx title="view.tsx" {2-4,22-25,29} 56 | import { ItemView, WorkspaceLeaf } from "obsidian"; 57 | import * as React from "react"; 58 | import * as ReactDOM from "react-dom"; 59 | import { ReactView } from "./ReactView"; 60 | 61 | const VIEW_TYPE_EXAMPLE = "example-view"; 62 | 63 | class ExampleView extends ItemView { 64 | constructor(leaf: WorkspaceLeaf) { 65 | super(leaf); 66 | } 67 | 68 | getViewType() { 69 | return VIEW_TYPE_EXAMPLE; 70 | } 71 | 72 | getDisplayText() { 73 | return "Example view"; 74 | } 75 | 76 | async onOpen() { 77 | ReactDOM.render( 78 | , 79 | this.containerEl.children[1] 80 | ); 81 | } 82 | 83 | async onClose() { 84 | ReactDOM.unmountComponentAtNode(this.containerEl.children[1]); 85 | } 86 | } 87 | ``` 88 | 89 | For more information on `ReactDOM.render()` and `ReactDOM.unmountComponentAtNode()`, refer to the documentation on [ReactDOM](https://reactjs.org/docs/react-dom.html). 90 | 91 | You can mount your React component on any `HTMLElement`, for example [status bar items](../guides/status-bar.md). Just make sure to clean up properly by calling `ReactDOM.unmountComponentAtNode()` when you're done. 92 | 93 | ## Create an App context 94 | 95 | If you want to access the [`App`](../api/classes/App.md) object from one of your React components, you need to pass it as a dependency. As your plugin grows, even though you're only using the `App` object in a few places, you start passing it through the whole component tree. 96 | 97 | Another alternative is to create a React context for the app to make it globally available to all components inside your React view. 98 | 99 | 1. Use `React.createContext()` to create a new app context. 100 | 101 | ```tsx title="context.ts" 102 | export const AppContext = React.createContext(undefined); 103 | ``` 104 | 105 | 1. Wrap the `ReactView` with a context provider and pass the app as the value. 106 | 107 | ```tsx title="view.tsx" 108 | ReactDOM.render( 109 | 110 | 111 | , 112 | this.containerEl.children[1] 113 | ); 114 | ``` 115 | 116 | 1. Create a custom hook to make it easier to use the context in your components. 117 | 118 | ```tsx title="hooks.ts" 119 | import { AppContext } from "./context"; 120 | 121 | export const useApp = (): App | undefined => { 122 | return React.useContext(AppContext); 123 | }; 124 | ``` 125 | 126 | 1. Use the hook in any React component within `ReactView` to access the app. 127 | 128 | ```tsx title="ReactView.tsx" 129 | import * as React from "react"; 130 | import { useApp } from "./hooks"; 131 | 132 | export const ReactView = () => { 133 | const { vault } = useApp(); 134 | 135 | return

{vault.getName()}

; 136 | }; 137 | ``` 138 | 139 | For more information, refer to the React documentation for [Context](https://reactjs.org/docs/context.html) and [Building Your Own Hooks](https://reactjs.org/docs/hooks-custom.html). 140 | -------------------------------------------------------------------------------- /docs/advanced-guides/svelte.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 78 3 | --- 4 | 5 | # Svelte 6 | 7 | :::info 8 | This guide is written for an older version of the sample plugin that uses Rollup. If you know how to adapt it for ESBuild, consider [contributing](../contribute.md) the changes. 9 | ::: 10 | 11 | This guide explains how to configure your plugin to use [Svelte](https://svelte.dev/), a light-weight alternative to traditional frameworks like React and Vue. 12 | 13 | Svelte is built around a compiler that preprocesses your code and outputs vanilla JavaScript, which means it doesn't need to load any libraries at run time. This also means that it doesn't need a virtual DOM to track state changes, which allows your plugin to run with minimal additional overhead. 14 | 15 | If you want to learn more about Svelte, and how to use it, refer to the [tutorial](https://svelte.dev/tutorial/basics) and the [documentation](https://svelte.dev/docs). 16 | 17 | This guide assumes that you've finished [Create your first plugin](../getting-started/create-your-first-plugin). 18 | 19 | :::tip Visual Studio Code 20 | Svelte has an [official Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) that enables syntax highlighting and rich IntelliSense in Svelte components. 21 | ::: 22 | 23 | ## Configure your plugin 24 | 25 | To build a Svelte application, you need to install the dependencies and configure your plugin to compile code written using Svelte. 26 | 27 | 1. Add Svelte to your plugin dependencies: 28 | 29 | ```bash 30 | npm install --save-dev svelte svelte-preprocess @tsconfig/svelte rollup-plugin-svelte 31 | ``` 32 | 33 | 1. Extend the `tsconfig.json` to enable additional type checking for common Svelte issues. The `types` property is important for TypeScript to recognize `.svelte` files. 34 | 35 | ```json title="tsconfig.json" 36 | { 37 | "extends": "@tsconfig/svelte/tsconfig.json", 38 | "compilerOptions": { 39 | "types": ["svelte", "node"], 40 | 41 | // ... 42 | } 43 | } 44 | ``` 45 | 46 | 1. Remove the following line from your `tsconfig.json` as it conflicts with the Svelte configuration. 47 | 48 | ```json title="tsconfig.json" 49 | "inlineSourceMap": true, 50 | ``` 51 | 52 | 1. In `rollup.config.js`, add the following imports to the top of the file: 53 | 54 | ```js title="rollup.config.js" 55 | import svelte from "rollup-plugin-svelte"; 56 | import sveltePreprocess from "svelte-preprocess"; 57 | ``` 58 | 59 | 1. Add Svelte to the list of plugins. 60 | 61 | ```js title="rollup.config.js" {14} 62 | export default { 63 | input: 'main.ts', 64 | output: { 65 | dir: '.', 66 | sourcemap: 'inline', 67 | sourcemapExcludeSources: isProd, 68 | format: 'cjs', 69 | exports: 'default', 70 | banner, 71 | }, 72 | external: ['obsidian'], 73 | plugins: [ 74 | typescript(), 75 | svelte({ emitCss: false, preprocess: sveltePreprocess() }), 76 | nodeResolve({browser: true}), 77 | commonjs(), 78 | ] 79 | }; 80 | ``` 81 | 82 | ## Create a Svelte component 83 | 84 | In the root directory of the plugin, create a new file called `Component.svelte`: 85 | 86 | ```tsx title="Component.svelte" 87 | 90 | 91 |
92 | My number is {variable}! 93 |
94 | 95 | 100 | ``` 101 | 102 | ## Mount the Svelte component 103 | 104 | To use the Svelte component, it needs to be mounted on an existing [HTML element](../guides/html-elements.md). For example, if you are mounting on a custom [`ItemView`](../api/classes/ItemView.md) in Obsidian: 105 | 106 | ```ts 107 | import { ItemView, WorkspaceLeaf } from "obsidian"; 108 | 109 | import Component from "./Component.svelte"; 110 | 111 | const VIEW_TYPE_EXAMPLE = "example-view"; 112 | 113 | class ExampleView extends ItemView { 114 | component: Component; 115 | 116 | constructor(leaf: WorkspaceLeaf) { 117 | super(leaf); 118 | } 119 | 120 | getViewType() { 121 | return VIEW_TYPE_EXAMPLE; 122 | } 123 | 124 | getDisplayText() { 125 | return "Example view"; 126 | } 127 | 128 | async onOpen() { 129 | this.component = new Component({ 130 | target: this.contentEl, 131 | props: { 132 | variable: 1 133 | } 134 | }); 135 | } 136 | 137 | async onClose() { 138 | this.component.$destroy(); 139 | } 140 | } 141 | ``` 142 | 143 | ## Create a Svelte store 144 | 145 | To create a store for your plugin and access it from within a generic Svelte component instead of passing the plugin as a prop, follow these steps: 146 | 147 | 1. Create a file called `store.ts`: 148 | 149 | ```jsx title="store.ts" 150 | import { writable } from "svelte/store"; 151 | import type ExamplePlugin from "./main"; 152 | 153 | const plugin = writable(); 154 | export default { plugin }; 155 | ``` 156 | 157 | 1. Configure the store: 158 | 159 | ```ts title="view.ts" {} 160 | import { ItemView, WorkspaceLeaf } from "obsidian"; 161 | import type ExamplePlugin from "./main"; 162 | import store from "./store"; 163 | import Component from "./Component.svelte"; 164 | 165 | const VIEW_TYPE_EXAMPLE = "example-view"; 166 | 167 | class ExampleView extends ItemView { 168 | // ... 169 | 170 | async onOpen() { 171 | store.plugin.set(this.plugin); 172 | 173 | this.component = new Component({ 174 | target: this.contentEl, 175 | props: { 176 | variable: 1 177 | } 178 | }); 179 | } 180 | } 181 | ``` 182 | 183 | 1. To use the store in your component: 184 | 185 | ```jsx title="Component.svelte" {} 186 | 192 | ``` 193 | -------------------------------------------------------------------------------- /docs/api/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "API reference", 3 | "position": 70 4 | } 5 | -------------------------------------------------------------------------------- /docs/api/classes/AbstractTextComponent.md: -------------------------------------------------------------------------------- 1 | # AbstractTextComponent 2 | 3 | Extends `ValueComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(inputEl: T); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### inputEl 14 | 15 | ```ts 16 | inputEl: T 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### setDisabled 22 | 23 | ```ts 24 | setDisabled(disabled: boolean): this; 25 | ``` 26 | 27 | ### getValue 28 | 29 | ```ts 30 | getValue(): string; 31 | ``` 32 | 33 | ### setValue 34 | 35 | ```ts 36 | setValue(value: string): this; 37 | ``` 38 | 39 | ### setPlaceholder 40 | 41 | ```ts 42 | setPlaceholder(placeholder: string): this; 43 | ``` 44 | 45 | ### onChanged 46 | 47 | ```ts 48 | onChanged(): void; 49 | ``` 50 | 51 | ### onChange 52 | 53 | ```ts 54 | onChange(callback: (value: string) => any): this; 55 | ``` 56 | -------------------------------------------------------------------------------- /docs/api/classes/App.md: -------------------------------------------------------------------------------- 1 | # App 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Properties 10 | 11 | ### keymap 12 | 13 | ```ts 14 | keymap: Keymap 15 | ``` 16 | 17 | ### scope 18 | 19 | ```ts 20 | scope: Scope 21 | ``` 22 | 23 | ### workspace 24 | 25 | ```ts 26 | workspace: Workspace 27 | ``` 28 | 29 | ### vault 30 | 31 | ```ts 32 | vault: Vault 33 | ``` 34 | 35 | ### metadataCache 36 | 37 | ```ts 38 | metadataCache: MetadataCache 39 | ``` 40 | 41 | ### fileManager 42 | 43 | ```ts 44 | fileManager: FileManager 45 | ``` 46 | 47 | ### lastEvent 48 | 49 | ```ts 50 | lastEvent: UserEvent 51 | ``` 52 | 53 | The last known user interaction event, to help commands find out what modifier keys are pressed. 54 | -------------------------------------------------------------------------------- /docs/api/classes/BaseComponent.md: -------------------------------------------------------------------------------- 1 | # BaseComponent 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Properties 10 | 11 | ### disabled 12 | 13 | ```ts 14 | disabled: boolean 15 | ``` 16 | 17 | ## Methods 18 | 19 | ### then 20 | 21 | ```ts 22 | then(cb: (component: this) => any): this; 23 | ``` 24 | 25 | Facilitates chaining 26 | 27 | ### setDisabled 28 | 29 | ```ts 30 | setDisabled(disabled: boolean): this; 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/api/classes/ButtonComponent.md: -------------------------------------------------------------------------------- 1 | # ButtonComponent 2 | 3 | Extends `BaseComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### buttonEl 14 | 15 | ```ts 16 | buttonEl: HTMLButtonElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### setDisabled 22 | 23 | ```ts 24 | setDisabled(disabled: boolean): this; 25 | ``` 26 | 27 | ### setCta 28 | 29 | ```ts 30 | setCta(): this; 31 | ``` 32 | 33 | ### removeCta 34 | 35 | ```ts 36 | removeCta(): this; 37 | ``` 38 | 39 | ### setWarning 40 | 41 | ```ts 42 | setWarning(): this; 43 | ``` 44 | 45 | ### setTooltip 46 | 47 | ```ts 48 | setTooltip(tooltip: string): this; 49 | ``` 50 | 51 | ### setButtonText 52 | 53 | ```ts 54 | setButtonText(name: string): this; 55 | ``` 56 | 57 | ### setIcon 58 | 59 | ```ts 60 | setIcon(icon: string): this; 61 | ``` 62 | 63 | ### setClass 64 | 65 | ```ts 66 | setClass(cls: string): this; 67 | ``` 68 | 69 | ### onClick 70 | 71 | ```ts 72 | onClick(callback: (evt: MouseEvent) => any): this; 73 | ``` 74 | -------------------------------------------------------------------------------- /docs/api/classes/Component.md: -------------------------------------------------------------------------------- 1 | # Component 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### load 12 | 13 | ```ts 14 | load(): void; 15 | ``` 16 | 17 | Load this component and its children 18 | 19 | ### onload 20 | 21 | ```ts 22 | onload(): void; 23 | ``` 24 | 25 | Override this to load your component 26 | 27 | ### unload 28 | 29 | ```ts 30 | unload(): void; 31 | ``` 32 | 33 | Unload this component and its children 34 | 35 | ### onunload 36 | 37 | ```ts 38 | onunload(): void; 39 | ``` 40 | 41 | Override this to unload your component 42 | 43 | ### addChild 44 | 45 | ```ts 46 | addChild(component: T): T; 47 | ``` 48 | 49 | Adds a child component, loading it if this component is loaded 50 | 51 | ### removeChild 52 | 53 | ```ts 54 | removeChild(component: T): T; 55 | ``` 56 | 57 | Removes a child component, unloading it 58 | 59 | ### register 60 | 61 | ```ts 62 | register(cb: () => any): void; 63 | ``` 64 | 65 | Registers a callback to be called when unloading 66 | 67 | ### registerEvent 68 | 69 | ```ts 70 | registerEvent(eventRef: EventRef): void; 71 | ``` 72 | 73 | Registers an event to be detached when unloading 74 | 75 | ### registerDomEvent 76 | 77 | ```ts 78 | registerDomEvent(el: Window, type: K, callback: (this: HTMLElement, ev: WindowEventMap[K]) => any): void; 79 | ``` 80 | 81 | Registers an DOM event to be detached when unloading 82 | 83 | ### registerDomEvent 84 | 85 | ```ts 86 | registerDomEvent(el: Document, type: K, callback: (this: HTMLElement, ev: DocumentEventMap[K]) => any): void; 87 | ``` 88 | 89 | Registers an DOM event to be detached when unloading 90 | 91 | ### registerDomEvent 92 | 93 | ```ts 94 | registerDomEvent(el: HTMLElement, type: K, callback: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any): void; 95 | ``` 96 | 97 | Registers an DOM event to be detached when unloading 98 | 99 | ### registerScopeEvent 100 | 101 | ```ts 102 | registerScopeEvent(keyHandler: KeymapEventHandler): void; 103 | ``` 104 | 105 | Registers an key event to be detached when unloading 106 | 107 | ### registerInterval 108 | 109 | ```ts 110 | registerInterval(id: number): number; 111 | ``` 112 | 113 | Registers an interval (from setInterval) to be cancelled when unloading 114 | Use {@link window.setInterval} instead of {@link setInterval} to avoid TypeScript confusing between NodeJS vs Browser API 115 | -------------------------------------------------------------------------------- /docs/api/classes/DropdownComponent.md: -------------------------------------------------------------------------------- 1 | # DropdownComponent 2 | 3 | Extends `ValueComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### selectEl 14 | 15 | ```ts 16 | selectEl: HTMLSelectElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### setDisabled 22 | 23 | ```ts 24 | setDisabled(disabled: boolean): this; 25 | ``` 26 | 27 | ### addOption 28 | 29 | ```ts 30 | addOption(value: string, display: string): this; 31 | ``` 32 | 33 | ### addOptions 34 | 35 | ```ts 36 | addOptions(options: Record): this; 37 | ``` 38 | 39 | ### getValue 40 | 41 | ```ts 42 | getValue(): string; 43 | ``` 44 | 45 | ### setValue 46 | 47 | ```ts 48 | setValue(value: string): this; 49 | ``` 50 | 51 | ### onChange 52 | 53 | ```ts 54 | onChange(callback: (value: string) => any): this; 55 | ``` 56 | -------------------------------------------------------------------------------- /docs/api/classes/EditableFileView.md: -------------------------------------------------------------------------------- 1 | # EditableFileView 2 | 3 | Extends `FileView` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(leaf: WorkspaceLeaf); 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/classes/Editor.md: -------------------------------------------------------------------------------- 1 | # Editor 2 | 3 | A common interface that bridges the gap between CodeMirror 5 and CodeMirror 6. 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### getDoc 14 | 15 | ```ts 16 | getDoc(): this; 17 | ``` 18 | 19 | ### refresh 20 | 21 | ```ts 22 | abstract refresh(): void; 23 | ``` 24 | 25 | ### getValue 26 | 27 | ```ts 28 | abstract getValue(): string; 29 | ``` 30 | 31 | ### setValue 32 | 33 | ```ts 34 | abstract setValue(content: string): void; 35 | ``` 36 | 37 | ### getLine 38 | 39 | ```ts 40 | abstract getLine(line: number): string; 41 | ``` 42 | 43 | Get the text at line (0-indexed) 44 | 45 | ### setLine 46 | 47 | ```ts 48 | setLine(n: number, text: string): void; 49 | ``` 50 | 51 | ### lineCount 52 | 53 | ```ts 54 | abstract lineCount(): number; 55 | ``` 56 | 57 | Gets the number of lines in the document 58 | 59 | ### lastLine 60 | 61 | ```ts 62 | abstract lastLine(): number; 63 | ``` 64 | 65 | ### getSelection 66 | 67 | ```ts 68 | abstract getSelection(): string; 69 | ``` 70 | 71 | ### somethingSelected 72 | 73 | ```ts 74 | somethingSelected(): boolean; 75 | ``` 76 | 77 | ### getRange 78 | 79 | ```ts 80 | abstract getRange(from: EditorPosition, to: EditorPosition): string; 81 | ``` 82 | 83 | ### replaceSelection 84 | 85 | ```ts 86 | abstract replaceSelection(replacement: string, origin?: string): void; 87 | ``` 88 | 89 | ### replaceRange 90 | 91 | ```ts 92 | abstract replaceRange(replacement: string, from: EditorPosition, to?: EditorPosition, origin?: string): void; 93 | ``` 94 | 95 | ### getCursor 96 | 97 | ```ts 98 | abstract getCursor(string?: 'from' | 'to' | 'head' | 'anchor'): EditorPosition; 99 | ``` 100 | 101 | ### listSelections 102 | 103 | ```ts 104 | abstract listSelections(): EditorSelection[]; 105 | ``` 106 | 107 | ### setCursor 108 | 109 | ```ts 110 | setCursor(pos: EditorPosition | number, ch?: number): void; 111 | ``` 112 | 113 | ### setSelection 114 | 115 | ```ts 116 | abstract setSelection(anchor: EditorPosition, head?: EditorPosition): void; 117 | ``` 118 | 119 | ### setSelections 120 | 121 | ```ts 122 | abstract setSelections(ranges: EditorSelectionOrCaret[], main?: number): void; 123 | ``` 124 | 125 | ### focus 126 | 127 | ```ts 128 | abstract focus(): void; 129 | ``` 130 | 131 | ### blur 132 | 133 | ```ts 134 | abstract blur(): void; 135 | ``` 136 | 137 | ### hasFocus 138 | 139 | ```ts 140 | abstract hasFocus(): boolean; 141 | ``` 142 | 143 | ### getScrollInfo 144 | 145 | ```ts 146 | abstract getScrollInfo(): { 147 | top: number; 148 | left: number; 149 | }; 150 | ``` 151 | 152 | ### scrollTo 153 | 154 | ```ts 155 | abstract scrollTo(x?: number | null, y?: number | null): void; 156 | ``` 157 | 158 | ### scrollIntoView 159 | 160 | ```ts 161 | abstract scrollIntoView(range: EditorRange, center?: boolean): void; 162 | ``` 163 | 164 | ### undo 165 | 166 | ```ts 167 | abstract undo(): void; 168 | ``` 169 | 170 | ### redo 171 | 172 | ```ts 173 | abstract redo(): void; 174 | ``` 175 | 176 | ### exec 177 | 178 | ```ts 179 | abstract exec(command: EditorCommandName): void; 180 | ``` 181 | 182 | ### transaction 183 | 184 | ```ts 185 | abstract transaction(tx: EditorTransaction, origin?: string): void; 186 | ``` 187 | 188 | ### wordAt 189 | 190 | ```ts 191 | abstract wordAt(pos: EditorPosition): EditorRange | null; 192 | ``` 193 | 194 | ### posToOffset 195 | 196 | ```ts 197 | abstract posToOffset(pos: EditorPosition): number; 198 | ``` 199 | 200 | ### offsetToPos 201 | 202 | ```ts 203 | abstract offsetToPos(offset: number): EditorPosition; 204 | ``` 205 | 206 | ### processLines 207 | 208 | ```ts 209 | processLines(read: (line: number, lineText: string) => T | null, write: (line: number, lineText: string, value: T | null) => EditorChange | void, ignoreEmpty?: boolean): void; 210 | ``` 211 | -------------------------------------------------------------------------------- /docs/api/classes/EditorSuggest.md: -------------------------------------------------------------------------------- 1 | # EditorSuggest 2 | 3 | Extends `PopoverSuggest` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(app: App); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### context 14 | 15 | ```ts 16 | context: EditorSuggestContext 17 | ``` 18 | 19 | Current suggestion context, containing the result of `onTrigger`. 20 | This will be null any time the EditorSuggest is not supposed to run. 21 | 22 | ### limit 23 | 24 | ```ts 25 | limit: number 26 | ``` 27 | 28 | Override this to use a different limit for suggestion items 29 | 30 | ## Methods 31 | 32 | ### setInstructions 33 | 34 | ```ts 35 | setInstructions(instructions: Instruction[]): void; 36 | ``` 37 | 38 | ### onTrigger 39 | 40 | ```ts 41 | abstract onTrigger(cursor: EditorPosition, editor: Editor, file: TFile): EditorSuggestTriggerInfo | null; 42 | ``` 43 | 44 | Based on the editor line and cursor position, determine if this EditorSuggest should be triggered at this moment. 45 | Typically, you would run a regular expression on the current line text before the cursor. 46 | Return null to indicate that this editor suggest is not supposed to be triggered. 47 | 48 | Please be mindful of performance when implementing this function, as it will be triggered very often (on each keypress). 49 | Keep it simple, and return null as early as possible if you determine that it is not the right time. 50 | 51 | ### getSuggestions 52 | 53 | ```ts 54 | abstract getSuggestions(context: EditorSuggestContext): T[] | Promise; 55 | ``` 56 | 57 | Generate suggestion items based on this context. Can be async, but preferably sync. 58 | When generating async suggestions, you should pass the context along. 59 | -------------------------------------------------------------------------------- /docs/api/classes/Events.md: -------------------------------------------------------------------------------- 1 | # Events 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### on 12 | 13 | ```ts 14 | on(name: string, callback: (...data: any) => any, ctx?: any): EventRef; 15 | ``` 16 | 17 | ### off 18 | 19 | ```ts 20 | off(name: string, callback: (...data: any) => any): void; 21 | ``` 22 | 23 | ### offref 24 | 25 | ```ts 26 | offref(ref: EventRef): void; 27 | ``` 28 | 29 | ### trigger 30 | 31 | ```ts 32 | trigger(name: string, ...data: any[]): void; 33 | ``` 34 | 35 | ### tryTrigger 36 | 37 | ```ts 38 | tryTrigger(evt: EventRef, args: any[]): void; 39 | ``` 40 | -------------------------------------------------------------------------------- /docs/api/classes/ExtraButtonComponent.md: -------------------------------------------------------------------------------- 1 | # ExtraButtonComponent 2 | 3 | Extends `BaseComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### extraSettingsEl 14 | 15 | ```ts 16 | extraSettingsEl: HTMLElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### setDisabled 22 | 23 | ```ts 24 | setDisabled(disabled: boolean): this; 25 | ``` 26 | 27 | ### setTooltip 28 | 29 | ```ts 30 | setTooltip(tooltip: string): this; 31 | ``` 32 | 33 | ### setIcon 34 | 35 | ```ts 36 | setIcon(icon: string): this; 37 | ``` 38 | 39 | ### onClick 40 | 41 | ```ts 42 | onClick(callback: () => any): this; 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/api/classes/FileManager.md: -------------------------------------------------------------------------------- 1 | # FileManager 2 | 3 | Manage the creation, deletion and renaming of files from the UI. 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### getNewFileParent 14 | 15 | ```ts 16 | getNewFileParent(sourcePath: string): TFolder; 17 | ``` 18 | 19 | Gets the folder that new files should be saved to, given the user's preferences. 20 | 21 | ### renameFile 22 | 23 | ```ts 24 | renameFile(file: TAbstractFile, newPath: string): Promise; 25 | ``` 26 | 27 | Rename or move a file safely, and update all links to it depending on the user's preferences. 28 | 29 | ### generateMarkdownLink 30 | 31 | ```ts 32 | generateMarkdownLink(file: TFile, sourcePath: string, subpath?: string, alias?: string): string; 33 | ``` 34 | 35 | Generate a markdown link based on the user's preferences. 36 | -------------------------------------------------------------------------------- /docs/api/classes/FileSystemAdapter.md: -------------------------------------------------------------------------------- 1 | # FileSystemAdapter 2 | 3 | Implements `DataAdapter` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### getName 14 | 15 | ```ts 16 | getName(): string; 17 | ``` 18 | 19 | ### getBasePath 20 | 21 | ```ts 22 | getBasePath(): string; 23 | ``` 24 | 25 | ### mkdir 26 | 27 | ```ts 28 | mkdir(normalizedPath: string): Promise; 29 | ``` 30 | 31 | ### trashSystem 32 | 33 | ```ts 34 | trashSystem(normalizedPath: string): Promise; 35 | ``` 36 | 37 | ### trashLocal 38 | 39 | ```ts 40 | trashLocal(normalizedPath: string): Promise; 41 | ``` 42 | 43 | ### rmdir 44 | 45 | ```ts 46 | rmdir(normalizedPath: string, recursive: boolean): Promise; 47 | ``` 48 | 49 | ### read 50 | 51 | ```ts 52 | read(normalizedPath: string): Promise; 53 | ``` 54 | 55 | ### readBinary 56 | 57 | ```ts 58 | readBinary(normalizedPath: string): Promise; 59 | ``` 60 | 61 | ### write 62 | 63 | ```ts 64 | write(normalizedPath: string, data: string, options?: DataWriteOptions): Promise; 65 | ``` 66 | 67 | ### writeBinary 68 | 69 | ```ts 70 | writeBinary(normalizedPath: string, data: ArrayBuffer, options?: DataWriteOptions): Promise; 71 | ``` 72 | 73 | ### append 74 | 75 | ```ts 76 | append(normalizedPath: string, data: string, options?: DataWriteOptions): Promise; 77 | ``` 78 | 79 | ### getResourcePath 80 | 81 | ```ts 82 | getResourcePath(normalizedPath: string): string; 83 | ``` 84 | 85 | ### remove 86 | 87 | ```ts 88 | remove(normalizedPath: string): Promise; 89 | ``` 90 | 91 | ### rename 92 | 93 | ```ts 94 | rename(normalizedPath: string, normalizedNewPath: string): Promise; 95 | ``` 96 | 97 | ### copy 98 | 99 | ```ts 100 | copy(normalizedPath: string, normalizedNewPath: string): Promise; 101 | ``` 102 | 103 | ### exists 104 | 105 | ```ts 106 | exists(normalizedPath: string, sensitive?: boolean): Promise; 107 | ``` 108 | 109 | ### stat 110 | 111 | ```ts 112 | stat(normalizedPath: string): Promise; 113 | ``` 114 | 115 | ### list 116 | 117 | ```ts 118 | list(normalizedPath: string): Promise; 119 | ``` 120 | 121 | ### getFullPath 122 | 123 | ```ts 124 | getFullPath(normalizedPath: string): string; 125 | ``` 126 | 127 | ### readLocalFile 128 | 129 | ```ts 130 | static readLocalFile(path: string): Promise; 131 | ``` 132 | 133 | ### mkdir 134 | 135 | ```ts 136 | static mkdir(path: string): Promise; 137 | ``` 138 | -------------------------------------------------------------------------------- /docs/api/classes/FileView.md: -------------------------------------------------------------------------------- 1 | # FileView 2 | 3 | Extends `ItemView` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(leaf: WorkspaceLeaf); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### allowNoFile 14 | 15 | ```ts 16 | allowNoFile: boolean 17 | ``` 18 | 19 | ### file 20 | 21 | ```ts 22 | file: TFile 23 | ``` 24 | 25 | ## Methods 26 | 27 | ### getDisplayText 28 | 29 | ```ts 30 | getDisplayText(): string; 31 | ``` 32 | 33 | ### onload 34 | 35 | ```ts 36 | onload(): void; 37 | ``` 38 | 39 | Override this to load your component 40 | 41 | ### getState 42 | 43 | ```ts 44 | getState(): any; 45 | ``` 46 | 47 | ### setState 48 | 49 | ```ts 50 | setState(state: any, result: ViewStateResult): Promise; 51 | ``` 52 | 53 | ### onLoadFile 54 | 55 | ```ts 56 | onLoadFile(file: TFile): Promise; 57 | ``` 58 | 59 | ### onUnloadFile 60 | 61 | ```ts 62 | onUnloadFile(file: TFile): Promise; 63 | ``` 64 | 65 | ### onMoreOptionsMenu 66 | 67 | ```ts 68 | onMoreOptionsMenu(menu: Menu): void; 69 | ``` 70 | 71 | ### onHeaderMenu 72 | 73 | ```ts 74 | onHeaderMenu(menu: Menu): void; 75 | ``` 76 | 77 | ### canAcceptExtension 78 | 79 | ```ts 80 | canAcceptExtension(extension: string): boolean; 81 | ``` 82 | -------------------------------------------------------------------------------- /docs/api/classes/FuzzySuggestModal.md: -------------------------------------------------------------------------------- 1 | # FuzzySuggestModal 2 | 3 | Extends `SuggestModal>` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(app: App); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### getSuggestions 14 | 15 | ```ts 16 | getSuggestions(query: string): FuzzyMatch[]; 17 | ``` 18 | 19 | ### renderSuggestion 20 | 21 | ```ts 22 | renderSuggestion(item: FuzzyMatch, el: HTMLElement): void; 23 | ``` 24 | 25 | Render the suggestion item into DOM. 26 | 27 | ### onChooseSuggestion 28 | 29 | ```ts 30 | onChooseSuggestion(item: FuzzyMatch, evt: MouseEvent | KeyboardEvent): void; 31 | ``` 32 | 33 | ### getItems 34 | 35 | ```ts 36 | abstract getItems(): T[]; 37 | ``` 38 | 39 | ### getItemText 40 | 41 | ```ts 42 | abstract getItemText(item: T): string; 43 | ``` 44 | 45 | ### onChooseItem 46 | 47 | ```ts 48 | abstract onChooseItem(item: T, evt: MouseEvent | KeyboardEvent): void; 49 | ``` 50 | -------------------------------------------------------------------------------- /docs/api/classes/HoverPopover.md: -------------------------------------------------------------------------------- 1 | # HoverPopover 2 | 3 | Extends `Component` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(parent: HoverParent, targetEl: HTMLElement, waitTime: number); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### state 14 | 15 | ```ts 16 | state: PopoverState 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/api/classes/ItemView.md: -------------------------------------------------------------------------------- 1 | # ItemView 2 | 3 | Extends `View` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(leaf: WorkspaceLeaf); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### contentEl 14 | 15 | ```ts 16 | contentEl: HTMLElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### onMoreOptionsMenu 22 | 23 | ```ts 24 | onMoreOptionsMenu(menu: Menu): void; 25 | ``` 26 | 27 | ### addAction 28 | 29 | ```ts 30 | addAction(icon: string, title: string, callback: (evt: MouseEvent) => any, size?: number): HTMLElement; 31 | ``` 32 | 33 | ### onHeaderMenu 34 | 35 | ```ts 36 | onHeaderMenu(menu: Menu): void; 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/api/classes/Keymap.md: -------------------------------------------------------------------------------- 1 | # Keymap 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### pushScope 12 | 13 | ```ts 14 | pushScope(scope: Scope): void; 15 | ``` 16 | 17 | ### popScope 18 | 19 | ```ts 20 | popScope(scope: Scope): void; 21 | ``` 22 | 23 | ### isModifier 24 | 25 | ```ts 26 | static isModifier(evt: MouseEvent | TouchEvent | KeyboardEvent, modifier: Modifier): boolean; 27 | ``` 28 | 29 | Checks whether the modifier key is pressed during this event 30 | 31 | ### isModEvent 32 | 33 | ```ts 34 | static isModEvent(evt?: UserEvent | null): boolean; 35 | ``` 36 | 37 | Returns true if the modifier key Cmd/Ctrl is pressed OR if this is a middle-click MouseEvent. 38 | -------------------------------------------------------------------------------- /docs/api/classes/MarkdownEditView.md: -------------------------------------------------------------------------------- 1 | # MarkdownEditView 2 | 3 | Implements `MarkdownSubView`, `HoverParent` 4 | 5 | This is the editor for Obsidian Mobile as well as the upcoming WYSIWYG editor. 6 | 7 | ## Constructor 8 | 9 | ```ts 10 | constructor(view: MarkdownView); 11 | ``` 12 | 13 | ## Properties 14 | 15 | ### hoverPopover 16 | 17 | ```ts 18 | hoverPopover: HoverPopover 19 | ``` 20 | 21 | ## Methods 22 | 23 | ### clear 24 | 25 | ```ts 26 | clear(): void; 27 | ``` 28 | 29 | ### get 30 | 31 | ```ts 32 | get(): string; 33 | ``` 34 | 35 | ### set 36 | 37 | ```ts 38 | set(data: string, clear: boolean): void; 39 | ``` 40 | 41 | ### getSelection 42 | 43 | ```ts 44 | getSelection(): string; 45 | ``` 46 | 47 | ### getScroll 48 | 49 | ```ts 50 | getScroll(): number; 51 | ``` 52 | 53 | ### applyScroll 54 | 55 | ```ts 56 | applyScroll(scroll: number): void; 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/api/classes/MarkdownPreviewRenderer.md: -------------------------------------------------------------------------------- 1 | # MarkdownPreviewRenderer 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### registerPostProcessor 12 | 13 | ```ts 14 | static registerPostProcessor(postProcessor: MarkdownPostProcessor, sortOrder?: number): void; 15 | ``` 16 | 17 | ### unregisterPostProcessor 18 | 19 | ```ts 20 | static unregisterPostProcessor(postProcessor: MarkdownPostProcessor): void; 21 | ``` 22 | 23 | ### createCodeBlockPostProcessor 24 | 25 | ```ts 26 | static createCodeBlockPostProcessor(language: string, handler: (source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => Promise | void): (el: HTMLElement, ctx: MarkdownPostProcessorContext) => void; 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/api/classes/MarkdownPreviewView.md: -------------------------------------------------------------------------------- 1 | # MarkdownPreviewView 2 | 3 | Extends `MarkdownRenderer` 4 | 5 | Implements `MarkdownSubView`, `MarkdownPreviewEvents` 6 | 7 | ## Constructor 8 | 9 | ```ts 10 | constructor(containerEl: HTMLElement); 11 | ``` 12 | 13 | ## Properties 14 | 15 | ### containerEl 16 | 17 | ```ts 18 | containerEl: HTMLElement 19 | ``` 20 | 21 | ## Methods 22 | 23 | ### get 24 | 25 | ```ts 26 | get(): string; 27 | ``` 28 | 29 | ### set 30 | 31 | ```ts 32 | set(data: string, clear: boolean): void; 33 | ``` 34 | 35 | ### clear 36 | 37 | ```ts 38 | clear(): void; 39 | ``` 40 | 41 | ### rerender 42 | 43 | ```ts 44 | rerender(full?: boolean): void; 45 | ``` 46 | 47 | ### getScroll 48 | 49 | ```ts 50 | getScroll(): number; 51 | ``` 52 | 53 | ### applyScroll 54 | 55 | ```ts 56 | applyScroll(scroll: number): void; 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/api/classes/MarkdownRenderChild.md: -------------------------------------------------------------------------------- 1 | # MarkdownRenderChild 2 | 3 | Extends `Component` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### containerEl 14 | 15 | ```ts 16 | containerEl: HTMLElement 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/api/classes/MarkdownRenderer.md: -------------------------------------------------------------------------------- 1 | # MarkdownRenderer 2 | 3 | Extends `MarkdownRenderChild` 4 | 5 | Implements `MarkdownPreviewEvents`, `HoverParent` 6 | 7 | ## Constructor 8 | 9 | ```ts 10 | constructor(containerEl: HTMLElement); 11 | ``` 12 | 13 | ## Properties 14 | 15 | ### hoverPopover 16 | 17 | ```ts 18 | hoverPopover: HoverPopover 19 | ``` 20 | 21 | ## Methods 22 | 23 | ### renderMarkdown 24 | 25 | ```ts 26 | static renderMarkdown(markdown: string, el: HTMLElement, sourcePath: string, component: Component): Promise; 27 | ``` 28 | 29 | Renders markdown string to an HTML element. 30 | -------------------------------------------------------------------------------- /docs/api/classes/MarkdownSourceView.md: -------------------------------------------------------------------------------- 1 | # MarkdownSourceView 2 | 3 | Implements `MarkdownSubView`, `HoverParent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(view: MarkdownView); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### cmEditor 14 | 15 | ```ts 16 | cmEditor: any 17 | ``` 18 | 19 | ### hoverPopover 20 | 21 | ```ts 22 | hoverPopover: HoverPopover 23 | ``` 24 | 25 | ## Methods 26 | 27 | ### clear 28 | 29 | ```ts 30 | clear(): void; 31 | ``` 32 | 33 | ### get 34 | 35 | ```ts 36 | get(): string; 37 | ``` 38 | 39 | ### set 40 | 41 | ```ts 42 | set(data: string, clear: boolean): void; 43 | ``` 44 | 45 | ### getSelection 46 | 47 | ```ts 48 | getSelection(): string; 49 | ``` 50 | 51 | ### getScroll 52 | 53 | ```ts 54 | getScroll(): number; 55 | ``` 56 | 57 | ### applyScroll 58 | 59 | ```ts 60 | applyScroll(scroll: number): void; 61 | ``` 62 | -------------------------------------------------------------------------------- /docs/api/classes/MarkdownView.md: -------------------------------------------------------------------------------- 1 | # MarkdownView 2 | 3 | Extends `TextFileView` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(leaf: WorkspaceLeaf); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### editor 14 | 15 | ```ts 16 | editor: Editor 17 | ``` 18 | 19 | ### previewMode 20 | 21 | ```ts 22 | previewMode: MarkdownPreviewView 23 | ``` 24 | 25 | ### currentMode 26 | 27 | ```ts 28 | currentMode: MarkdownSubView 29 | ``` 30 | 31 | ## Methods 32 | 33 | ### getViewType 34 | 35 | ```ts 36 | getViewType(): string; 37 | ``` 38 | 39 | ### getMode 40 | 41 | ```ts 42 | getMode(): MarkdownViewModeType; 43 | ``` 44 | 45 | ### getViewData 46 | 47 | ```ts 48 | getViewData(): string; 49 | ``` 50 | 51 | Gets the data from the editor. This will be called to save the editor contents to the file. 52 | 53 | ### clear 54 | 55 | ```ts 56 | clear(): void; 57 | ``` 58 | 59 | Clear the editor. This is usually called when we're about to open a completely 60 | different file, so it's best to clear any editor states like undo-redo history, 61 | and any caches/indexes associated with the previous file contents. 62 | 63 | ### setViewData 64 | 65 | ```ts 66 | setViewData(data: string, clear: boolean): void; 67 | ``` 68 | 69 | Set the data to the editor. This is used to load the file contents. 70 | 71 | If clear is set, then it means we're opening a completely different file. 72 | In that case, you should call clear(), or implement a slightly more efficient 73 | clearing mechanism given the new data to be set. 74 | 75 | ### showSearch 76 | 77 | ```ts 78 | showSearch(replace?: boolean): void; 79 | ``` 80 | -------------------------------------------------------------------------------- /docs/api/classes/Menu.md: -------------------------------------------------------------------------------- 1 | # Menu 2 | 3 | Extends `Component` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(app: App); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### setNoIcon 14 | 15 | ```ts 16 | setNoIcon(): this; 17 | ``` 18 | 19 | ### addItem 20 | 21 | ```ts 22 | addItem(cb: (item: MenuItem) => any): this; 23 | ``` 24 | 25 | ### addSeparator 26 | 27 | ```ts 28 | addSeparator(): this; 29 | ``` 30 | 31 | ### showAtMouseEvent 32 | 33 | ```ts 34 | showAtMouseEvent(evt: MouseEvent): this; 35 | ``` 36 | 37 | ### showAtPosition 38 | 39 | ```ts 40 | showAtPosition(position: Point): this; 41 | ``` 42 | 43 | ### hide 44 | 45 | ```ts 46 | hide(): this; 47 | ``` 48 | 49 | ### onHide 50 | 51 | ```ts 52 | onHide(callback: () => any): void; 53 | ``` 54 | -------------------------------------------------------------------------------- /docs/api/classes/MenuItem.md: -------------------------------------------------------------------------------- 1 | # MenuItem 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(menu: Menu); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### setTitle 12 | 13 | ```ts 14 | setTitle(title: string | DocumentFragment): this; 15 | ``` 16 | 17 | ### setIcon 18 | 19 | ```ts 20 | setIcon(icon: string | null, size?: number): this; 21 | ``` 22 | 23 | ### setActive 24 | 25 | ```ts 26 | setActive(active: boolean): this; 27 | ``` 28 | 29 | ### setDisabled 30 | 31 | ```ts 32 | setDisabled(disabled: boolean): this; 33 | ``` 34 | 35 | ### setIsLabel 36 | 37 | ```ts 38 | setIsLabel(isLabel: boolean): this; 39 | ``` 40 | 41 | ### onClick 42 | 43 | ```ts 44 | onClick(callback: (evt: MouseEvent | KeyboardEvent) => any): this; 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/api/classes/MetadataCache.md: -------------------------------------------------------------------------------- 1 | # MetadataCache 2 | 3 | Extends `Events` 4 | 5 | Linktext is any internal link that is composed of a path and a subpath, such as "My note#Heading" 6 | Linkpath (or path) is the path part of a linktext 7 | Subpath is the heading/block ID part of a linktext. 8 | 9 | ## Constructor 10 | 11 | ```ts 12 | constructor(); 13 | ``` 14 | 15 | ## Properties 16 | 17 | ### resolvedLinks 18 | 19 | ```ts 20 | resolvedLinks: Record> 21 | ``` 22 | 23 | Contains all resolved links. This object maps each source file's path to an object of destination file paths with the link count. 24 | Source and destination paths are all vault absolute paths that comes from `TFile.path` and can be used with `Vault.getAbstractFileByPath(path)`. 25 | 26 | ### unresolvedLinks 27 | 28 | ```ts 29 | unresolvedLinks: Record> 30 | ``` 31 | 32 | Contains all unresolved links. This object maps each source file to an object of unknown destinations with count. 33 | Source paths are all vault absolute paths, similar to `resolvedLinks`. 34 | 35 | ## Methods 36 | 37 | ### getFirstLinkpathDest 38 | 39 | ```ts 40 | getFirstLinkpathDest(linkpath: string, sourcePath: string): TFile | null; 41 | ``` 42 | 43 | Get the best match for a linkpath. 44 | 45 | ### getFileCache 46 | 47 | ```ts 48 | getFileCache(file: TFile): CachedMetadata | null; 49 | ``` 50 | 51 | ### getCache 52 | 53 | ```ts 54 | getCache(path: string): CachedMetadata; 55 | ``` 56 | 57 | ### fileToLinktext 58 | 59 | ```ts 60 | fileToLinktext(file: TFile, sourcePath: string, omitMdExtension?: boolean): string; 61 | ``` 62 | 63 | Generates a linktext for a file. 64 | 65 | If file name is unique, use the filename. 66 | If not unique, use full path. 67 | 68 | ### on 69 | 70 | ```ts 71 | on(name: 'changed', callback: (file: TFile, data: string, cache: CachedMetadata) => any, ctx?: any): EventRef; 72 | ``` 73 | 74 | Called when a file has been indexed, and its (updated) cache is now available. 75 | Called when a file has been deleted. A best-effort previous version of the cached metadata is presented, 76 | but it could be null in case the file was not successfully cached previously. 77 | Called when a file has been resolved for `resolvedLinks` and `unresolvedLinks`. 78 | This happens sometimes after a file has been indexed. 79 | Called when all files has been resolved. This will be fired each time files get modified after the initial load. 80 | 81 | ### on 82 | 83 | ```ts 84 | on(name: 'deleted', callback: (file: TFile, prevCache: CachedMetadata | null) => any, ctx?: any): EventRef; 85 | ``` 86 | 87 | Called when a file has been indexed, and its (updated) cache is now available. 88 | Called when a file has been deleted. A best-effort previous version of the cached metadata is presented, 89 | but it could be null in case the file was not successfully cached previously. 90 | Called when a file has been resolved for `resolvedLinks` and `unresolvedLinks`. 91 | This happens sometimes after a file has been indexed. 92 | Called when all files has been resolved. This will be fired each time files get modified after the initial load. 93 | 94 | ### on 95 | 96 | ```ts 97 | on(name: 'resolve', callback: (file: TFile) => any, ctx?: any): EventRef; 98 | ``` 99 | 100 | Called when a file has been indexed, and its (updated) cache is now available. 101 | Called when a file has been deleted. A best-effort previous version of the cached metadata is presented, 102 | but it could be null in case the file was not successfully cached previously. 103 | Called when a file has been resolved for `resolvedLinks` and `unresolvedLinks`. 104 | This happens sometimes after a file has been indexed. 105 | Called when all files has been resolved. This will be fired each time files get modified after the initial load. 106 | 107 | ### on 108 | 109 | ```ts 110 | on(name: 'resolved', callback: () => any, ctx?: any): EventRef; 111 | ``` 112 | 113 | Called when a file has been indexed, and its (updated) cache is now available. 114 | Called when a file has been deleted. A best-effort previous version of the cached metadata is presented, 115 | but it could be null in case the file was not successfully cached previously. 116 | Called when a file has been resolved for `resolvedLinks` and `unresolvedLinks`. 117 | This happens sometimes after a file has been indexed. 118 | Called when all files has been resolved. This will be fired each time files get modified after the initial load. 119 | -------------------------------------------------------------------------------- /docs/api/classes/Modal.md: -------------------------------------------------------------------------------- 1 | # Modal 2 | 3 | Implements `CloseableComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(app: App); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### app 14 | 15 | ```ts 16 | app: App 17 | ``` 18 | 19 | ### scope 20 | 21 | ```ts 22 | scope: Scope 23 | ``` 24 | 25 | ### containerEl 26 | 27 | ```ts 28 | containerEl: HTMLElement 29 | ``` 30 | 31 | ### modalEl 32 | 33 | ```ts 34 | modalEl: HTMLElement 35 | ``` 36 | 37 | ### titleEl 38 | 39 | ```ts 40 | titleEl: HTMLElement 41 | ``` 42 | 43 | ### contentEl 44 | 45 | ```ts 46 | contentEl: HTMLElement 47 | ``` 48 | 49 | ### shouldRestoreSelection 50 | 51 | ```ts 52 | shouldRestoreSelection: boolean 53 | ``` 54 | 55 | ## Methods 56 | 57 | ### open 58 | 59 | ```ts 60 | open(): void; 61 | ``` 62 | 63 | ### close 64 | 65 | ```ts 66 | close(): void; 67 | ``` 68 | 69 | ### onOpen 70 | 71 | ```ts 72 | onOpen(): void; 73 | ``` 74 | 75 | ### onClose 76 | 77 | ```ts 78 | onClose(): void; 79 | ``` 80 | -------------------------------------------------------------------------------- /docs/api/classes/MomentFormatComponent.md: -------------------------------------------------------------------------------- 1 | # MomentFormatComponent 2 | 3 | Extends `TextComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### sampleEl 14 | 15 | ```ts 16 | sampleEl: HTMLElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### setDefaultFormat 22 | 23 | ```ts 24 | setDefaultFormat(defaultFormat: string): this; 25 | ``` 26 | 27 | Sets the default format when input is cleared. Also used for placeholder. 28 | 29 | ### setSampleEl 30 | 31 | ```ts 32 | setSampleEl(sampleEl: HTMLElement): this; 33 | ``` 34 | 35 | ### setValue 36 | 37 | ```ts 38 | setValue(value: string): this; 39 | ``` 40 | 41 | ### onChanged 42 | 43 | ```ts 44 | onChanged(): void; 45 | ``` 46 | 47 | ### updateSample 48 | 49 | ```ts 50 | updateSample(): void; 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/api/classes/Notice.md: -------------------------------------------------------------------------------- 1 | # Notice 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(message: string | DocumentFragment, timeout: number); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### setMessage 12 | 13 | ```ts 14 | setMessage(message: string | DocumentFragment): this; 15 | ``` 16 | 17 | Change the message of this notice. 18 | 19 | ### hide 20 | 21 | ```ts 22 | hide(): void; 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/api/classes/PluginSettingTab.md: -------------------------------------------------------------------------------- 1 | # PluginSettingTab 2 | 3 | Extends `SettingTab` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(app: App, plugin: Plugin_2); 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/classes/Plugin_2.md: -------------------------------------------------------------------------------- 1 | # Plugin_2 2 | 3 | Extends `Component` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(app: App, manifest: PluginManifest); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### app 14 | 15 | ```ts 16 | app: App 17 | ``` 18 | 19 | ### manifest 20 | 21 | ```ts 22 | manifest: PluginManifest 23 | ``` 24 | 25 | ## Methods 26 | 27 | ### addRibbonIcon 28 | 29 | ```ts 30 | addRibbonIcon(icon: string, title: string, callback: (evt: MouseEvent) => any): HTMLElement; 31 | ``` 32 | 33 | Adds a ribbon icon to the left bar. 34 | 35 | ### addStatusBarItem 36 | 37 | ```ts 38 | addStatusBarItem(): HTMLElement; 39 | ``` 40 | 41 | ### addCommand 42 | 43 | ```ts 44 | addCommand(command: Command): Command; 45 | ``` 46 | 47 | Register a command globally. The command id and name will be automatically prefixed with this plugin's id and name. 48 | 49 | ### addSettingTab 50 | 51 | ```ts 52 | addSettingTab(settingTab: PluginSettingTab): void; 53 | ``` 54 | 55 | ### registerView 56 | 57 | ```ts 58 | registerView(type: string, viewCreator: ViewCreator): void; 59 | ``` 60 | 61 | ### registerExtensions 62 | 63 | ```ts 64 | registerExtensions(extensions: string[], viewType: string): void; 65 | ``` 66 | 67 | ### registerMarkdownPostProcessor 68 | 69 | ```ts 70 | registerMarkdownPostProcessor(postProcessor: MarkdownPostProcessor, sortOrder?: number): MarkdownPostProcessor; 71 | ``` 72 | 73 | ### registerMarkdownCodeBlockProcessor 74 | 75 | ```ts 76 | registerMarkdownCodeBlockProcessor(language: string, handler: (source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => Promise | void, sortOrder?: number): MarkdownPostProcessor; 77 | ``` 78 | 79 | Register a special post processor that handles fenced code given a language and a handler. 80 | This special post processor takes care of removing the <pre><code> and create a <div> that 81 | will be passed to your handler, and is expected to be filled with your custom elements. 82 | 83 | ### registerCodeMirror 84 | 85 | ```ts 86 | registerCodeMirror(callback: (cm: CodeMirror.Editor) => any): void; 87 | ``` 88 | 89 | Runs callback on all currently loaded instances of CodeMirror, 90 | then registers the callback for all future CodeMirror instances. 91 | 92 | ### registerEditorExtension 93 | 94 | ```ts 95 | registerEditorExtension(extension: Extension): void; 96 | ``` 97 | 98 | Registers a CodeMirror 6 extension. 99 | To reconfigure cm6 extensions for your plugin on the fly, you can pass an array here and dynamically 100 | modify it. Once this array is modified, call `Workspace.updateOptions()` to have the changes applied. 101 | 102 | ### registerObsidianProtocolHandler 103 | 104 | ```ts 105 | registerObsidianProtocolHandler(action: string, handler: ObsidianProtocolHandler): void; 106 | ``` 107 | 108 | Register a handler for obsidian:// URLs. 109 | 110 | ### registerEditorSuggest 111 | 112 | ```ts 113 | registerEditorSuggest(editorSuggest: EditorSuggest): void; 114 | ``` 115 | 116 | Register an EditorSuggest which can provide live suggestions while the user is typing. 117 | 118 | ### loadData 119 | 120 | ```ts 121 | loadData(): Promise; 122 | ``` 123 | 124 | ### saveData 125 | 126 | ```ts 127 | saveData(data: any): Promise; 128 | ``` 129 | -------------------------------------------------------------------------------- /docs/api/classes/PopoverSuggest.md: -------------------------------------------------------------------------------- 1 | # PopoverSuggest 2 | 3 | Implements `ISuggestOwner`, `CloseableComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(app: App, scope: Scope); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### open 14 | 15 | ```ts 16 | open(): void; 17 | ``` 18 | 19 | ### close 20 | 21 | ```ts 22 | close(): void; 23 | ``` 24 | 25 | ### renderSuggestion 26 | 27 | ```ts 28 | abstract renderSuggestion(value: T, el: HTMLElement): void; 29 | ``` 30 | 31 | Render the suggestion item into DOM. 32 | 33 | ### selectSuggestion 34 | 35 | ```ts 36 | abstract selectSuggestion(value: T, evt: MouseEvent | KeyboardEvent): void; 37 | ``` 38 | 39 | Called when the user makes a selection. 40 | -------------------------------------------------------------------------------- /docs/api/classes/Scope.md: -------------------------------------------------------------------------------- 1 | # Scope 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(parent: Scope); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### register 12 | 13 | ```ts 14 | register(modifiers: Modifier[], key: string | null, func: KeymapEventListener): KeymapEventHandler; 15 | ``` 16 | 17 | ### unregister 18 | 19 | ```ts 20 | unregister(handler: KeymapEventHandler): void; 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/api/classes/SearchComponent.md: -------------------------------------------------------------------------------- 1 | # SearchComponent 2 | 3 | Extends `AbstractTextComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### clearButtonEl 14 | 15 | ```ts 16 | clearButtonEl: HTMLElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### onChanged 22 | 23 | ```ts 24 | onChanged(): void; 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/api/classes/Setting.md: -------------------------------------------------------------------------------- 1 | # Setting 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(containerEl: HTMLElement); 7 | ``` 8 | 9 | ## Properties 10 | 11 | ### settingEl 12 | 13 | ```ts 14 | settingEl: HTMLElement 15 | ``` 16 | 17 | ### infoEl 18 | 19 | ```ts 20 | infoEl: HTMLElement 21 | ``` 22 | 23 | ### nameEl 24 | 25 | ```ts 26 | nameEl: HTMLElement 27 | ``` 28 | 29 | ### descEl 30 | 31 | ```ts 32 | descEl: HTMLElement 33 | ``` 34 | 35 | ### controlEl 36 | 37 | ```ts 38 | controlEl: HTMLElement 39 | ``` 40 | 41 | ### components 42 | 43 | ```ts 44 | components: BaseComponent[] 45 | ``` 46 | 47 | ## Methods 48 | 49 | ### setName 50 | 51 | ```ts 52 | setName(name: string | DocumentFragment): this; 53 | ``` 54 | 55 | ### setDesc 56 | 57 | ```ts 58 | setDesc(desc: string | DocumentFragment): this; 59 | ``` 60 | 61 | ### setClass 62 | 63 | ```ts 64 | setClass(cls: string): this; 65 | ``` 66 | 67 | ### setTooltip 68 | 69 | ```ts 70 | setTooltip(tooltip: string): this; 71 | ``` 72 | 73 | ### setHeading 74 | 75 | ```ts 76 | setHeading(): this; 77 | ``` 78 | 79 | ### setDisabled 80 | 81 | ```ts 82 | setDisabled(disabled: boolean): this; 83 | ``` 84 | 85 | ### addButton 86 | 87 | ```ts 88 | addButton(cb: (component: ButtonComponent) => any): this; 89 | ``` 90 | 91 | ### addExtraButton 92 | 93 | ```ts 94 | addExtraButton(cb: (component: ExtraButtonComponent) => any): this; 95 | ``` 96 | 97 | ### addToggle 98 | 99 | ```ts 100 | addToggle(cb: (component: ToggleComponent) => any): this; 101 | ``` 102 | 103 | ### addText 104 | 105 | ```ts 106 | addText(cb: (component: TextComponent) => any): this; 107 | ``` 108 | 109 | ### addSearch 110 | 111 | ```ts 112 | addSearch(cb: (component: SearchComponent) => any): this; 113 | ``` 114 | 115 | ### addTextArea 116 | 117 | ```ts 118 | addTextArea(cb: (component: TextAreaComponent) => any): this; 119 | ``` 120 | 121 | ### addMomentFormat 122 | 123 | ```ts 124 | addMomentFormat(cb: (component: MomentFormatComponent) => any): this; 125 | ``` 126 | 127 | ### addDropdown 128 | 129 | ```ts 130 | addDropdown(cb: (component: DropdownComponent) => any): this; 131 | ``` 132 | 133 | ### addSlider 134 | 135 | ```ts 136 | addSlider(cb: (component: SliderComponent) => any): this; 137 | ``` 138 | 139 | ### then 140 | 141 | ```ts 142 | then(cb: (setting: this) => any): this; 143 | ``` 144 | 145 | Facilitates chaining 146 | 147 | ### clear 148 | 149 | ```ts 150 | clear(): this; 151 | ``` 152 | -------------------------------------------------------------------------------- /docs/api/classes/SettingTab.md: -------------------------------------------------------------------------------- 1 | # SettingTab 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Properties 10 | 11 | ### app 12 | 13 | ```ts 14 | app: App 15 | ``` 16 | 17 | ### containerEl 18 | 19 | ```ts 20 | containerEl: HTMLElement 21 | ``` 22 | 23 | ## Methods 24 | 25 | ### display 26 | 27 | ```ts 28 | abstract display(): any; 29 | ``` 30 | 31 | ### hide 32 | 33 | ```ts 34 | hide(): any; 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/api/classes/SliderComponent.md: -------------------------------------------------------------------------------- 1 | # SliderComponent 2 | 3 | Extends `ValueComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### sliderEl 14 | 15 | ```ts 16 | sliderEl: HTMLInputElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### setDisabled 22 | 23 | ```ts 24 | setDisabled(disabled: boolean): this; 25 | ``` 26 | 27 | ### setLimits 28 | 29 | ```ts 30 | setLimits(min: number, max: number, step: number | 'any'): this; 31 | ``` 32 | 33 | ### getValue 34 | 35 | ```ts 36 | getValue(): number; 37 | ``` 38 | 39 | ### setValue 40 | 41 | ```ts 42 | setValue(value: number): this; 43 | ``` 44 | 45 | ### getValuePretty 46 | 47 | ```ts 48 | getValuePretty(): string; 49 | ``` 50 | 51 | ### setDynamicTooltip 52 | 53 | ```ts 54 | setDynamicTooltip(): this; 55 | ``` 56 | 57 | ### showTooltip 58 | 59 | ```ts 60 | showTooltip(): void; 61 | ``` 62 | 63 | ### onChange 64 | 65 | ```ts 66 | onChange(callback: (value: number) => any): this; 67 | ``` 68 | -------------------------------------------------------------------------------- /docs/api/classes/SuggestModal.md: -------------------------------------------------------------------------------- 1 | # SuggestModal 2 | 3 | Extends `Modal` 4 | 5 | Implements `ISuggestOwner` 6 | 7 | ## Constructor 8 | 9 | ```ts 10 | constructor(app: App); 11 | ``` 12 | 13 | ## Properties 14 | 15 | ### limit 16 | 17 | ```ts 18 | limit: number 19 | ``` 20 | 21 | ### emptyStateText 22 | 23 | ```ts 24 | emptyStateText: string 25 | ``` 26 | 27 | ### inputEl 28 | 29 | ```ts 30 | inputEl: HTMLInputElement 31 | ``` 32 | 33 | ### resultContainerEl 34 | 35 | ```ts 36 | resultContainerEl: HTMLElement 37 | ``` 38 | 39 | ## Methods 40 | 41 | ### setPlaceholder 42 | 43 | ```ts 44 | setPlaceholder(placeholder: string): void; 45 | ``` 46 | 47 | ### setInstructions 48 | 49 | ```ts 50 | setInstructions(instructions: Instruction[]): void; 51 | ``` 52 | 53 | ### onNoSuggestion 54 | 55 | ```ts 56 | onNoSuggestion(): void; 57 | ``` 58 | 59 | ### selectSuggestion 60 | 61 | ```ts 62 | selectSuggestion(value: T, evt: MouseEvent | KeyboardEvent): void; 63 | ``` 64 | 65 | Called when the user makes a selection. 66 | 67 | ### getSuggestions 68 | 69 | ```ts 70 | abstract getSuggestions(query: string): T[] | Promise; 71 | ``` 72 | 73 | ### renderSuggestion 74 | 75 | ```ts 76 | abstract renderSuggestion(value: T, el: HTMLElement): any; 77 | ``` 78 | 79 | Render the suggestion item into DOM. 80 | 81 | ### onChooseSuggestion 82 | 83 | ```ts 84 | abstract onChooseSuggestion(item: T, evt: MouseEvent | KeyboardEvent): any; 85 | ``` 86 | -------------------------------------------------------------------------------- /docs/api/classes/TAbstractFile.md: -------------------------------------------------------------------------------- 1 | # TAbstractFile 2 | 3 | This can be either a `TFile` or a `TFolder`. 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### vault 14 | 15 | ```ts 16 | vault: Vault 17 | ``` 18 | 19 | ### path 20 | 21 | ```ts 22 | path: string 23 | ``` 24 | 25 | ### name 26 | 27 | ```ts 28 | name: string 29 | ``` 30 | 31 | ### parent 32 | 33 | ```ts 34 | parent: TFolder 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/api/classes/TFile.md: -------------------------------------------------------------------------------- 1 | # TFile 2 | 3 | Extends `TAbstractFile` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### stat 14 | 15 | ```ts 16 | stat: FileStats 17 | ``` 18 | 19 | ### basename 20 | 21 | ```ts 22 | basename: string 23 | ``` 24 | 25 | ### extension 26 | 27 | ```ts 28 | extension: string 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/api/classes/TFolder.md: -------------------------------------------------------------------------------- 1 | # TFolder 2 | 3 | Extends `TAbstractFile` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### children 14 | 15 | ```ts 16 | children: TAbstractFile[] 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### isRoot 22 | 23 | ```ts 24 | isRoot(): boolean; 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/api/classes/Tasks.md: -------------------------------------------------------------------------------- 1 | # Tasks 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | 9 | ## Methods 10 | 11 | ### add 12 | 13 | ```ts 14 | add(callback: () => Promise): void; 15 | ``` 16 | 17 | ### addPromise 18 | 19 | ```ts 20 | addPromise(promise: Promise): void; 21 | ``` 22 | 23 | ### isEmpty 24 | 25 | ```ts 26 | isEmpty(): boolean; 27 | ``` 28 | 29 | ### promise 30 | 31 | ```ts 32 | promise(): Promise; 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/api/classes/TextAreaComponent.md: -------------------------------------------------------------------------------- 1 | # TextAreaComponent 2 | 3 | Extends `AbstractTextComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/classes/TextComponent.md: -------------------------------------------------------------------------------- 1 | # TextComponent 2 | 3 | Extends `AbstractTextComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/classes/TextFileView.md: -------------------------------------------------------------------------------- 1 | # TextFileView 2 | 3 | Extends `EditableFileView` 4 | 5 | This class implements a plaintext-based editable file view, which can be loaded and saved given an editor. 6 | 7 | Note that by default, this view only saves when it's closing. To implement auto-save, your editor should 8 | call `this.requestSave()` when the content is changed. 9 | 10 | ## Constructor 11 | 12 | ```ts 13 | constructor(leaf: WorkspaceLeaf); 14 | ``` 15 | 16 | ## Properties 17 | 18 | ### data 19 | 20 | ```ts 21 | data: string 22 | ``` 23 | 24 | In memory data 25 | 26 | ### requestSave 27 | 28 | ```ts 29 | requestSave: () => void 30 | ``` 31 | 32 | Debounced save in 2 seconds from now 33 | 34 | ## Methods 35 | 36 | ### onUnloadFile 37 | 38 | ```ts 39 | onUnloadFile(file: TFile): Promise; 40 | ``` 41 | 42 | ### onLoadFile 43 | 44 | ```ts 45 | onLoadFile(file: TFile): Promise; 46 | ``` 47 | 48 | ### save 49 | 50 | ```ts 51 | save(clear?: boolean): Promise; 52 | ``` 53 | 54 | ### getViewData 55 | 56 | ```ts 57 | abstract getViewData(): string; 58 | ``` 59 | 60 | Gets the data from the editor. This will be called to save the editor contents to the file. 61 | 62 | ### setViewData 63 | 64 | ```ts 65 | abstract setViewData(data: string, clear: boolean): void; 66 | ``` 67 | 68 | Set the data to the editor. This is used to load the file contents. 69 | 70 | If clear is set, then it means we're opening a completely different file. 71 | In that case, you should call clear(), or implement a slightly more efficient 72 | clearing mechanism given the new data to be set. 73 | 74 | ### clear 75 | 76 | ```ts 77 | abstract clear(): void; 78 | ``` 79 | 80 | Clear the editor. This is usually called when we're about to open a completely 81 | different file, so it's best to clear any editor states like undo-redo history, 82 | and any caches/indexes associated with the previous file contents. 83 | -------------------------------------------------------------------------------- /docs/api/classes/ToggleComponent.md: -------------------------------------------------------------------------------- 1 | # ToggleComponent 2 | 3 | Extends `ValueComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(containerEl: HTMLElement); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### toggleEl 14 | 15 | ```ts 16 | toggleEl: HTMLElement 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### setDisabled 22 | 23 | ```ts 24 | setDisabled(disabled: boolean): this; 25 | ``` 26 | 27 | ### getValue 28 | 29 | ```ts 30 | getValue(): boolean; 31 | ``` 32 | 33 | ### setValue 34 | 35 | ```ts 36 | setValue(on: boolean): this; 37 | ``` 38 | 39 | ### setTooltip 40 | 41 | ```ts 42 | setTooltip(tooltip: string): this; 43 | ``` 44 | 45 | ### onClick 46 | 47 | ```ts 48 | onClick(): void; 49 | ``` 50 | 51 | ### onChange 52 | 53 | ```ts 54 | onChange(callback: (value: boolean) => any): this; 55 | ``` 56 | -------------------------------------------------------------------------------- /docs/api/classes/ValueComponent.md: -------------------------------------------------------------------------------- 1 | # ValueComponent 2 | 3 | Extends `BaseComponent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### registerOptionListener 14 | 15 | ```ts 16 | registerOptionListener(listeners: Record T>, key: string): this; 17 | ``` 18 | 19 | ### getValue 20 | 21 | ```ts 22 | abstract getValue(): T; 23 | ``` 24 | 25 | ### setValue 26 | 27 | ```ts 28 | abstract setValue(value: T): this; 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/api/classes/Vault.md: -------------------------------------------------------------------------------- 1 | # Vault 2 | 3 | Extends `Events` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### adapter 14 | 15 | ```ts 16 | adapter: DataAdapter 17 | ``` 18 | 19 | ### configDir 20 | 21 | ```ts 22 | configDir: string 23 | ``` 24 | 25 | Gets the path to the config folder. 26 | This value is typically `.obsidian` but it could be different. 27 | 28 | ## Methods 29 | 30 | ### getName 31 | 32 | ```ts 33 | getName(): string; 34 | ``` 35 | 36 | Gets the name of the vault 37 | 38 | ### getAbstractFileByPath 39 | 40 | ```ts 41 | getAbstractFileByPath(path: string): TAbstractFile | null; 42 | ``` 43 | 44 | ### getRoot 45 | 46 | ```ts 47 | getRoot(): TFolder; 48 | ``` 49 | 50 | ### create 51 | 52 | ```ts 53 | create(path: string, data: string, options?: DataWriteOptions): Promise; 54 | ``` 55 | 56 | ### createBinary 57 | 58 | ```ts 59 | createBinary(path: string, data: ArrayBuffer, options?: DataWriteOptions): Promise; 60 | ``` 61 | 62 | ### createFolder 63 | 64 | ```ts 65 | createFolder(path: string): Promise; 66 | ``` 67 | 68 | ### read 69 | 70 | ```ts 71 | read(file: TFile): Promise; 72 | ``` 73 | 74 | ### cachedRead 75 | 76 | ```ts 77 | cachedRead(file: TFile): Promise; 78 | ``` 79 | 80 | ### readBinary 81 | 82 | ```ts 83 | readBinary(file: TFile): Promise; 84 | ``` 85 | 86 | ### getResourcePath 87 | 88 | ```ts 89 | getResourcePath(file: TFile): string; 90 | ``` 91 | 92 | ### delete 93 | 94 | ```ts 95 | delete(file: TAbstractFile, force?: boolean): Promise; 96 | ``` 97 | 98 | ### trash 99 | 100 | ```ts 101 | trash(file: TAbstractFile, system: boolean): Promise; 102 | ``` 103 | 104 | Tries to move to system trash. If that isn't successful/allowed, use local trash 105 | 106 | ### rename 107 | 108 | ```ts 109 | rename(file: TAbstractFile, newPath: string): Promise; 110 | ``` 111 | 112 | ### modify 113 | 114 | ```ts 115 | modify(file: TFile, data: string, options?: DataWriteOptions): Promise; 116 | ``` 117 | 118 | ### modifyBinary 119 | 120 | ```ts 121 | modifyBinary(file: TFile, data: ArrayBuffer, options?: DataWriteOptions): Promise; 122 | ``` 123 | 124 | ### append 125 | 126 | ```ts 127 | append(file: TFile, data: string, options?: DataWriteOptions): Promise; 128 | ``` 129 | 130 | ### copy 131 | 132 | ```ts 133 | copy(file: TFile, newPath: string): Promise; 134 | ``` 135 | 136 | ### getAllLoadedFiles 137 | 138 | ```ts 139 | getAllLoadedFiles(): TAbstractFile[]; 140 | ``` 141 | 142 | ### recurseChildren 143 | 144 | ```ts 145 | static recurseChildren(root: TFolder, cb: (file: TAbstractFile) => any): void; 146 | ``` 147 | 148 | ### getMarkdownFiles 149 | 150 | ```ts 151 | getMarkdownFiles(): TFile[]; 152 | ``` 153 | 154 | ### getFiles 155 | 156 | ```ts 157 | getFiles(): TFile[]; 158 | ``` 159 | 160 | ### on 161 | 162 | ```ts 163 | on(name: 'create', callback: (file: TAbstractFile) => any, ctx?: any): EventRef; 164 | ``` 165 | 166 | ### on 167 | 168 | ```ts 169 | on(name: 'modify', callback: (file: TAbstractFile) => any, ctx?: any): EventRef; 170 | ``` 171 | 172 | ### on 173 | 174 | ```ts 175 | on(name: 'delete', callback: (file: TAbstractFile) => any, ctx?: any): EventRef; 176 | ``` 177 | 178 | ### on 179 | 180 | ```ts 181 | on(name: 'rename', callback: (file: TAbstractFile, oldPath: string) => any, ctx?: any): EventRef; 182 | ``` 183 | 184 | ### on 185 | 186 | ```ts 187 | on(name: 'closed', callback: () => any, ctx?: any): EventRef; 188 | ``` 189 | -------------------------------------------------------------------------------- /docs/api/classes/View.md: -------------------------------------------------------------------------------- 1 | # View 2 | 3 | Extends `Component` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(leaf: WorkspaceLeaf); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### app 14 | 15 | ```ts 16 | app: App 17 | ``` 18 | 19 | ### icon 20 | 21 | ```ts 22 | icon: string 23 | ``` 24 | 25 | ### navigation 26 | 27 | ```ts 28 | navigation: boolean 29 | ``` 30 | 31 | ### leaf 32 | 33 | ```ts 34 | leaf: WorkspaceLeaf 35 | ``` 36 | 37 | ### containerEl 38 | 39 | ```ts 40 | containerEl: HTMLElement 41 | ``` 42 | 43 | ## Methods 44 | 45 | ### onOpen 46 | 47 | ```ts 48 | protected onOpen(): Promise; 49 | ``` 50 | 51 | ### onClose 52 | 53 | ```ts 54 | protected onClose(): Promise; 55 | ``` 56 | 57 | ### getViewType 58 | 59 | ```ts 60 | abstract getViewType(): string; 61 | ``` 62 | 63 | ### getState 64 | 65 | ```ts 66 | getState(): any; 67 | ``` 68 | 69 | ### setState 70 | 71 | ```ts 72 | setState(state: any, result: ViewStateResult): Promise; 73 | ``` 74 | 75 | ### getEphemeralState 76 | 77 | ```ts 78 | getEphemeralState(): any; 79 | ``` 80 | 81 | ### setEphemeralState 82 | 83 | ```ts 84 | setEphemeralState(state: any): void; 85 | ``` 86 | 87 | ### getIcon 88 | 89 | ```ts 90 | getIcon(): string; 91 | ``` 92 | 93 | ### onResize 94 | 95 | ```ts 96 | onResize(): void; 97 | ``` 98 | 99 | Called when the size of this view is changed. 100 | 101 | ### getDisplayText 102 | 103 | ```ts 104 | abstract getDisplayText(): string; 105 | ``` 106 | 107 | ### onHeaderMenu 108 | 109 | ```ts 110 | onHeaderMenu(menu: Menu): void; 111 | ``` 112 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceItem.md: -------------------------------------------------------------------------------- 1 | # WorkspaceItem 2 | 3 | Extends `Events` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### getRoot 14 | 15 | ```ts 16 | getRoot(): WorkspaceItem; 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceLeaf.md: -------------------------------------------------------------------------------- 1 | # WorkspaceLeaf 2 | 3 | Extends `WorkspaceItem` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### view 14 | 15 | ```ts 16 | view: View 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### openFile 22 | 23 | ```ts 24 | openFile(file: TFile, openState?: OpenViewState): Promise; 25 | ``` 26 | 27 | ### open 28 | 29 | ```ts 30 | open(view: View): Promise; 31 | ``` 32 | 33 | ### getViewState 34 | 35 | ```ts 36 | getViewState(): ViewState; 37 | ``` 38 | 39 | ### setViewState 40 | 41 | ```ts 42 | setViewState(viewState: ViewState, eState?: any): Promise; 43 | ``` 44 | 45 | ### getEphemeralState 46 | 47 | ```ts 48 | getEphemeralState(): any; 49 | ``` 50 | 51 | ### setEphemeralState 52 | 53 | ```ts 54 | setEphemeralState(state: any): void; 55 | ``` 56 | 57 | ### togglePinned 58 | 59 | ```ts 60 | togglePinned(): void; 61 | ``` 62 | 63 | ### setPinned 64 | 65 | ```ts 66 | setPinned(pinned: boolean): void; 67 | ``` 68 | 69 | ### setGroupMember 70 | 71 | ```ts 72 | setGroupMember(other: WorkspaceLeaf): void; 73 | ``` 74 | 75 | ### setGroup 76 | 77 | ```ts 78 | setGroup(group: string): void; 79 | ``` 80 | 81 | ### detach 82 | 83 | ```ts 84 | detach(): void; 85 | ``` 86 | 87 | ### getIcon 88 | 89 | ```ts 90 | getIcon(): string; 91 | ``` 92 | 93 | ### getDisplayText 94 | 95 | ```ts 96 | getDisplayText(): string; 97 | ``` 98 | 99 | ### onResize 100 | 101 | ```ts 102 | onResize(): void; 103 | ``` 104 | 105 | ### on 106 | 107 | ```ts 108 | on(name: 'pinned-change', callback: (pinned: boolean) => any, ctx?: any): EventRef; 109 | ``` 110 | 111 | ### on 112 | 113 | ```ts 114 | on(name: 'group-change', callback: (group: string) => any, ctx?: any): EventRef; 115 | ``` 116 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceMobileDrawer.md: -------------------------------------------------------------------------------- 1 | # WorkspaceMobileDrawer 2 | 3 | Extends `WorkspaceParent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### collapsed 14 | 15 | ```ts 16 | collapsed: boolean 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### expand 22 | 23 | ```ts 24 | expand(): void; 25 | ``` 26 | 27 | ### collapse 28 | 29 | ```ts 30 | collapse(): void; 31 | ``` 32 | 33 | ### toggle 34 | 35 | ```ts 36 | toggle(): void; 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceParent.md: -------------------------------------------------------------------------------- 1 | # WorkspaceParent 2 | 3 | Extends `WorkspaceItem` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceRibbon.md: -------------------------------------------------------------------------------- 1 | # WorkspaceRibbon 2 | 3 | ## Constructor 4 | 5 | ```ts 6 | constructor(); 7 | ``` 8 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceSidedock.md: -------------------------------------------------------------------------------- 1 | # WorkspaceSidedock 2 | 3 | Extends `WorkspaceSplit` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | 11 | ## Properties 12 | 13 | ### collapsed 14 | 15 | ```ts 16 | collapsed: boolean 17 | ``` 18 | 19 | ## Methods 20 | 21 | ### toggle 22 | 23 | ```ts 24 | toggle(): void; 25 | ``` 26 | 27 | ### collapse 28 | 29 | ```ts 30 | collapse(): void; 31 | ``` 32 | 33 | ### expand 34 | 35 | ```ts 36 | expand(): void; 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceSplit.md: -------------------------------------------------------------------------------- 1 | # WorkspaceSplit 2 | 3 | Extends `WorkspaceParent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/classes/WorkspaceTabs.md: -------------------------------------------------------------------------------- 1 | # WorkspaceTabs 2 | 3 | Extends `WorkspaceParent` 4 | 5 | ## Constructor 6 | 7 | ```ts 8 | constructor(); 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/classes/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Classes" 3 | } 4 | -------------------------------------------------------------------------------- /docs/api/enums/PopoverState.md: -------------------------------------------------------------------------------- 1 | # PopoverState 2 | 3 | ```ts 4 | export enum PopoverState { 5 | } 6 | ``` 7 | -------------------------------------------------------------------------------- /docs/api/enums/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Enums" 3 | } 4 | -------------------------------------------------------------------------------- /docs/api/functions/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Functions" 3 | } 4 | -------------------------------------------------------------------------------- /docs/api/functions/addIcon.md: -------------------------------------------------------------------------------- 1 | # addIcon 2 | 3 | ```ts 4 | export function addIcon(iconId: string, svgContent: string): void; 5 | ``` 6 | 7 | Adds an icon to the library 8 | 9 | ## Parameters 10 | 11 | | Parameter | Description | 12 | |-----------|-------------| 13 | | `iconId` | the icon ID | 14 | | `svgContent` | the content of the SVG, without the <svg>. Must fit viewBox="0 0 100 100". | 15 | -------------------------------------------------------------------------------- /docs/api/functions/debounce.md: -------------------------------------------------------------------------------- 1 | # debounce 2 | 3 | ```ts 4 | export function debounce(cb: (...args: [ 5 | ...T 6 | ]) => any, timeout?: number, resetTimer?: boolean): Debouncer; 7 | ``` 8 | 9 | A standard debounce function. 10 | 11 | ## Parameters 12 | 13 | | Parameter | Description | 14 | |-----------|-------------| 15 | | `cb` | The function to call. | 16 | | `timeout` | The timeout to wait. | 17 | | `resetTimer` | Whether to reset the timeout when the debouncer is called again. | 18 | -------------------------------------------------------------------------------- /docs/api/functions/finishRenderMath.md: -------------------------------------------------------------------------------- 1 | # finishRenderMath 2 | 3 | ```ts 4 | export function finishRenderMath(): Promise; 5 | ``` 6 | 7 | Flush the MathJax stylesheet. 8 | -------------------------------------------------------------------------------- /docs/api/functions/fuzzySearch.md: -------------------------------------------------------------------------------- 1 | # fuzzySearch 2 | 3 | ```ts 4 | export function fuzzySearch(q: PreparedQuery, text: string): SearchResult | null; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `q` | | 12 | | `text` | | 13 | -------------------------------------------------------------------------------- /docs/api/functions/getAllTags.md: -------------------------------------------------------------------------------- 1 | # getAllTags 2 | 3 | ```ts 4 | export function getAllTags(cache: CachedMetadata): string[] | null; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `cache` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/getLinkpath.md: -------------------------------------------------------------------------------- 1 | # getLinkpath 2 | 3 | ```ts 4 | export function getLinkpath(linktext: string): string; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `linktext` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/htmlToMarkdown.md: -------------------------------------------------------------------------------- 1 | # htmlToMarkdown 2 | 3 | ```ts 4 | export function htmlToMarkdown(html: string): string; 5 | ``` 6 | 7 | Converts HTML to Markdown using Turndown Service. 8 | 9 | ## Parameters 10 | 11 | | Parameter | Description | 12 | |-----------|-------------| 13 | | `html` | | 14 | -------------------------------------------------------------------------------- /docs/api/functions/iterateCacheRefs.md: -------------------------------------------------------------------------------- 1 | # iterateCacheRefs 2 | 3 | ```ts 4 | export function iterateCacheRefs(cache: CachedMetadata, cb: (ref: ReferenceCache) => boolean | void): boolean; 5 | ``` 6 | 7 | Iterate links and embeds. If callback returns true, the iteration process will be interrupted. 8 | 9 | ## Parameters 10 | 11 | | Parameter | Description | 12 | |-----------|-------------| 13 | | `cache` | | 14 | | `cb` | | 15 | -------------------------------------------------------------------------------- /docs/api/functions/iterateRefs.md: -------------------------------------------------------------------------------- 1 | # iterateRefs 2 | 3 | ```ts 4 | export function iterateRefs(refs: ReferenceCache[], cb: (ref: ReferenceCache) => boolean | void): boolean; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `refs` | | 12 | | `cb` | | 13 | -------------------------------------------------------------------------------- /docs/api/functions/loadMathJax.md: -------------------------------------------------------------------------------- 1 | # loadMathJax 2 | 3 | ```ts 4 | export function loadMathJax(): Promise; 5 | ``` 6 | 7 | Load MathJax. 8 | -------------------------------------------------------------------------------- /docs/api/functions/loadMermaid.md: -------------------------------------------------------------------------------- 1 | # loadMermaid 2 | 3 | ```ts 4 | export function loadMermaid(): Promise; 5 | ``` 6 | 7 | Load Mermaid and return a promise to the global mermaid object. 8 | Can also use `mermaid` after this promise resolves to get the same reference. 9 | -------------------------------------------------------------------------------- /docs/api/functions/loadPdfJs.md: -------------------------------------------------------------------------------- 1 | # loadPdfJs 2 | 3 | ```ts 4 | export function loadPdfJs(): Promise; 5 | ``` 6 | 7 | Load PDF.js and return a promise to the global pdfjsLib object. 8 | Can also use `window.pdfjsLib` after this promise resolves to get the same reference. 9 | -------------------------------------------------------------------------------- /docs/api/functions/loadPrism.md: -------------------------------------------------------------------------------- 1 | # loadPrism 2 | 3 | ```ts 4 | export function loadPrism(): Promise; 5 | ``` 6 | 7 | Load Prism.js and return a promise to the global Prism object. 8 | Can also use `Prism` after this promise resolves to get the same reference. 9 | -------------------------------------------------------------------------------- /docs/api/functions/normalizePath.md: -------------------------------------------------------------------------------- 1 | # normalizePath 2 | 3 | ```ts 4 | export function normalizePath(path: string): string; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `path` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/parseFrontMatterAliases.md: -------------------------------------------------------------------------------- 1 | # parseFrontMatterAliases 2 | 3 | ```ts 4 | export function parseFrontMatterAliases(frontmatter: any | null): string[] | null; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `frontmatter` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/parseFrontMatterEntry.md: -------------------------------------------------------------------------------- 1 | # parseFrontMatterEntry 2 | 3 | ```ts 4 | export function parseFrontMatterEntry(frontmatter: any | null, key: string | RegExp): any | null; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `frontmatter` | | 12 | | `key` | | 13 | -------------------------------------------------------------------------------- /docs/api/functions/parseFrontMatterStringArray.md: -------------------------------------------------------------------------------- 1 | # parseFrontMatterStringArray 2 | 3 | ```ts 4 | export function parseFrontMatterStringArray(frontmatter: any | null, key: string | RegExp, nospaces?: boolean): string[] | null; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `frontmatter` | | 12 | | `key` | | 13 | | `nospaces` | | 14 | -------------------------------------------------------------------------------- /docs/api/functions/parseFrontMatterTags.md: -------------------------------------------------------------------------------- 1 | # parseFrontMatterTags 2 | 3 | ```ts 4 | export function parseFrontMatterTags(frontmatter: any | null): string[] | null; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `frontmatter` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/parseLinktext.md: -------------------------------------------------------------------------------- 1 | # parseLinktext 2 | 3 | ```ts 4 | export function parseLinktext(linktext: string): { 5 | path: string; 6 | subpath: string; 7 | }; 8 | ``` 9 | 10 | ## Parameters 11 | 12 | | Parameter | Description | 13 | |-----------|-------------| 14 | | `linktext` | | 15 | -------------------------------------------------------------------------------- /docs/api/functions/parseYaml.md: -------------------------------------------------------------------------------- 1 | # parseYaml 2 | 3 | ```ts 4 | export function parseYaml(yaml: string): any; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `yaml` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/prepareFuzzySearch.md: -------------------------------------------------------------------------------- 1 | # prepareFuzzySearch 2 | 3 | ```ts 4 | export function prepareFuzzySearch(query: string): (text: string) => SearchResult | null; 5 | ``` 6 | 7 | Construct a fuzzy search callback that runs on a target string. 8 | Performance may be an issue if you are running the search for more than a few thousand times. 9 | If performance is a problem, consider using `prepareSimpleSearch` instead. 10 | 11 | ## Parameters 12 | 13 | | Parameter | Description | 14 | |-----------|-------------| 15 | | `query` | the fuzzy query. | 16 | -------------------------------------------------------------------------------- /docs/api/functions/prepareQuery.md: -------------------------------------------------------------------------------- 1 | # prepareQuery 2 | 3 | ```ts 4 | export function prepareQuery(query: string): PreparedQuery; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `query` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/prepareSimpleSearch.md: -------------------------------------------------------------------------------- 1 | # prepareSimpleSearch 2 | 3 | ```ts 4 | export function prepareSimpleSearch(query: string): (text: string) => SearchResult | null; 5 | ``` 6 | 7 | Construct a simple search callback that runs on a target string. 8 | 9 | ## Parameters 10 | 11 | | Parameter | Description | 12 | |-----------|-------------| 13 | | `query` | the space-separated words | 14 | -------------------------------------------------------------------------------- /docs/api/functions/renderMatches.md: -------------------------------------------------------------------------------- 1 | # renderMatches 2 | 3 | ```ts 4 | export function renderMatches(el: HTMLElement | DocumentFragment, text: string, matches: SearchMatches | null, offset?: number): void; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `el` | | 12 | | `text` | | 13 | | `matches` | | 14 | | `offset` | | 15 | -------------------------------------------------------------------------------- /docs/api/functions/renderMath.md: -------------------------------------------------------------------------------- 1 | # renderMath 2 | 3 | ```ts 4 | export function renderMath(source: string, display: boolean): HTMLElement; 5 | ``` 6 | 7 | Render some LaTeX math using the MathJax engine. Returns an HTMLElement. 8 | Requires calling `finishRenderMath` when rendering is all done to flush the MathJax stylesheet. 9 | 10 | ## Parameters 11 | 12 | | Parameter | Description | 13 | |-----------|-------------| 14 | | `source` | | 15 | | `display` | | 16 | -------------------------------------------------------------------------------- /docs/api/functions/renderResults.md: -------------------------------------------------------------------------------- 1 | # renderResults 2 | 3 | ```ts 4 | export function renderResults(el: HTMLElement, text: string, result: SearchResult, offset?: number): void; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `el` | | 12 | | `text` | | 13 | | `result` | | 14 | | `offset` | | 15 | -------------------------------------------------------------------------------- /docs/api/functions/request.md: -------------------------------------------------------------------------------- 1 | # request 2 | 3 | ```ts 4 | export function request(request: RequestUrlParam): Promise; 5 | ``` 6 | 7 | Similar to `fetch()`, request a URL using HTTP/HTTPS, without any CORS restrictions. 8 | Returns the text value of the response. 9 | 10 | ## Parameters 11 | 12 | | Parameter | Description | 13 | |-----------|-------------| 14 | | `request` | | 15 | -------------------------------------------------------------------------------- /docs/api/functions/requestUrl.md: -------------------------------------------------------------------------------- 1 | # requestUrl 2 | 3 | ```ts 4 | export function requestUrl(request: RequestUrlParam): Promise; 5 | ``` 6 | 7 | Similar to `fetch()`, request a URL using HTTP/HTTPS, without any CORS restrictions. 8 | 9 | ## Parameters 10 | 11 | | Parameter | Description | 12 | |-----------|-------------| 13 | | `request` | | 14 | -------------------------------------------------------------------------------- /docs/api/functions/requireApiVersion.md: -------------------------------------------------------------------------------- 1 | # requireApiVersion 2 | 3 | ```ts 4 | export function requireApiVersion(version: string): boolean; 5 | ``` 6 | 7 | Returns true if the API version is equal or higher than the requested version. 8 | Use this to limit functionality that require specific API versions to avoid 9 | crashing on older Obsidian builds. 10 | 11 | ## Parameters 12 | 13 | | Parameter | Description | 14 | |-----------|-------------| 15 | | `version` | | 16 | -------------------------------------------------------------------------------- /docs/api/functions/resolveSubpath.md: -------------------------------------------------------------------------------- 1 | # resolveSubpath 2 | 3 | ```ts 4 | export function resolveSubpath(cache: CachedMetadata, subpath: string): HeadingSubpathResult | BlockSubpathResult; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `cache` | | 12 | | `subpath` | | 13 | -------------------------------------------------------------------------------- /docs/api/functions/sanitizeHTMLToDom.md: -------------------------------------------------------------------------------- 1 | # sanitizeHTMLToDom 2 | 3 | ```ts 4 | export function sanitizeHTMLToDom(html: string): DocumentFragment; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `html` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/setIcon.md: -------------------------------------------------------------------------------- 1 | # setIcon 2 | 3 | ```ts 4 | export function setIcon(parent: HTMLElement, iconId: string, size?: number): void; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `parent` | the HTML element to insert the icon | 12 | | `iconId` | the icon ID | 13 | | `size` | the pixel size for width and height, defaults to 16 | 14 | -------------------------------------------------------------------------------- /docs/api/functions/sortSearchResults.md: -------------------------------------------------------------------------------- 1 | # sortSearchResults 2 | 3 | ```ts 4 | export function sortSearchResults(results: SearchResultContainer[]): void; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `results` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/stringifyYaml.md: -------------------------------------------------------------------------------- 1 | # stringifyYaml 2 | 3 | ```ts 4 | export function stringifyYaml(obj: any): string; 5 | ``` 6 | 7 | ## Parameters 8 | 9 | | Parameter | Description | 10 | |-----------|-------------| 11 | | `obj` | | 12 | -------------------------------------------------------------------------------- /docs/api/functions/stripHeading.md: -------------------------------------------------------------------------------- 1 | # stripHeading 2 | 3 | ```ts 4 | export function stripHeading(heading: string): string; 5 | ``` 6 | 7 | This function normalizes headings for link matching by stripping out special characters and shrinking consecutive spaces. 8 | 9 | ## Parameters 10 | 11 | | Parameter | Description | 12 | |-----------|-------------| 13 | | `heading` | | 14 | -------------------------------------------------------------------------------- /docs/api/interfaces/AjaxOptions.md: -------------------------------------------------------------------------------- 1 | # AjaxOptions 2 | 3 | ## Properties 4 | 5 | ### method 6 | 7 | ```ts 8 | method: "GET" | "POST" 9 | ``` 10 | 11 | ### url 12 | 13 | ```ts 14 | url: string 15 | ``` 16 | 17 | ### success 18 | 19 | ```ts 20 | success: (response: any, req: XMLHttpRequest) => any 21 | ``` 22 | 23 | ### error 24 | 25 | ```ts 26 | error: (error: any, req: XMLHttpRequest) => any 27 | ``` 28 | 29 | ### data 30 | 31 | ```ts 32 | data: string | object | ArrayBuffer 33 | ``` 34 | 35 | ### headers 36 | 37 | ```ts 38 | headers: Record 39 | ``` 40 | 41 | ### withCredentials 42 | 43 | ```ts 44 | withCredentials: boolean 45 | ``` 46 | 47 | ### req 48 | 49 | ```ts 50 | req: XMLHttpRequest 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/api/interfaces/BlockCache.md: -------------------------------------------------------------------------------- 1 | # BlockCache 2 | 3 | ## Properties 4 | 5 | ### id 6 | 7 | ```ts 8 | id: string 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/BlockSubpathResult.md: -------------------------------------------------------------------------------- 1 | # BlockSubpathResult 2 | 3 | ## Properties 4 | 5 | ### type 6 | 7 | ```ts 8 | type: "block" 9 | ``` 10 | 11 | ### block 12 | 13 | ```ts 14 | block: BlockCache 15 | ``` 16 | 17 | ### list 18 | 19 | ```ts 20 | list: ListItemCache 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/api/interfaces/CacheItem.md: -------------------------------------------------------------------------------- 1 | # CacheItem 2 | 3 | ## Properties 4 | 5 | ### position 6 | 7 | ```ts 8 | position: Pos 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/CachedMetadata.md: -------------------------------------------------------------------------------- 1 | # CachedMetadata 2 | 3 | ## Properties 4 | 5 | ### links 6 | 7 | ```ts 8 | links: LinkCache[] 9 | ``` 10 | 11 | ### embeds 12 | 13 | ```ts 14 | embeds: EmbedCache[] 15 | ``` 16 | 17 | ### tags 18 | 19 | ```ts 20 | tags: TagCache[] 21 | ``` 22 | 23 | ### headings 24 | 25 | ```ts 26 | headings: HeadingCache[] 27 | ``` 28 | 29 | ### sections 30 | 31 | ```ts 32 | sections: SectionCache[] 33 | ``` 34 | 35 | Sections are root level markdown blocks, which can be used to divide the document up. 36 | 37 | ### listItems 38 | 39 | ```ts 40 | listItems: ListItemCache[] 41 | ``` 42 | 43 | ### frontmatter 44 | 45 | ```ts 46 | frontmatter: FrontMatterCache 47 | ``` 48 | 49 | ### blocks 50 | 51 | ```ts 52 | blocks: Record 53 | ``` 54 | -------------------------------------------------------------------------------- /docs/api/interfaces/CloseableComponent.md: -------------------------------------------------------------------------------- 1 | # CloseableComponent 2 | 3 | ## Methods 4 | 5 | ### close 6 | 7 | ```ts 8 | close: () => any 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/Command.md: -------------------------------------------------------------------------------- 1 | # Command 2 | 3 | ## Properties 4 | 5 | ### id 6 | 7 | ```ts 8 | id: string 9 | ``` 10 | 11 | Globally unique ID to identify this command. 12 | 13 | ### name 14 | 15 | ```ts 16 | name: string 17 | ``` 18 | 19 | Human friendly name for searching. 20 | 21 | ### icon 22 | 23 | ```ts 24 | icon: string 25 | ``` 26 | 27 | Icon ID to be used in the toolbar. 28 | 29 | ### mobileOnly 30 | 31 | ```ts 32 | mobileOnly: boolean 33 | ``` 34 | 35 | ### callback 36 | 37 | ```ts 38 | callback: () => any 39 | ``` 40 | 41 | Simple callback, triggered globally. 42 | 43 | ### checkCallback 44 | 45 | ```ts 46 | checkCallback: (checking: boolean) => boolean | void 47 | ``` 48 | 49 | Complex callback, overrides the simple callback. 50 | Used to "check" whether your command can be performed in the current circumstances. 51 | For example, if your command requires the active focused pane to be a MarkdownSourceView, then 52 | you should only return true if the condition is satisfied. Returning false or undefined causes 53 | the command to be hidden from the command palette. 54 | 55 | ### editorCallback 56 | 57 | ```ts 58 | editorCallback: (editor: Editor, view: MarkdownView) => any 59 | ``` 60 | 61 | A command callback that is only triggered when the user is in an editor. 62 | Overrides `callback` and `checkCallback` 63 | 64 | ### editorCheckCallback 65 | 66 | ```ts 67 | editorCheckCallback: (checking: boolean, editor: Editor, view: MarkdownView) => boolean | void 68 | ``` 69 | 70 | A command callback that is only triggered when the user is in an editor. 71 | Overrides `editorCallback`, `callback` and `checkCallback` 72 | 73 | ### hotkeys 74 | 75 | ```ts 76 | hotkeys: Hotkey[] 77 | ``` 78 | 79 | Sets the default hotkey. It is recommended for plugins to avoid setting default hotkeys if possible, 80 | to avoid conflicting hotkeys with one that's set by the user, even though customized hotkeys have higher priority. 81 | -------------------------------------------------------------------------------- /docs/api/interfaces/Constructor.md: -------------------------------------------------------------------------------- 1 | # Constructor 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/DataAdapter.md: -------------------------------------------------------------------------------- 1 | # DataAdapter 2 | 3 | ## Methods 4 | 5 | ### getName 6 | 7 | ```ts 8 | getName: () => string 9 | ``` 10 | 11 | ### exists 12 | 13 | ```ts 14 | exists: (normalizedPath: string, sensitive?: boolean) => Promise 15 | ``` 16 | 17 | ### stat 18 | 19 | ```ts 20 | stat: (normalizedPath: string) => Promise 21 | ``` 22 | 23 | ### list 24 | 25 | ```ts 26 | list: (normalizedPath: string) => Promise 27 | ``` 28 | 29 | ### read 30 | 31 | ```ts 32 | read: (normalizedPath: string) => Promise 33 | ``` 34 | 35 | ### readBinary 36 | 37 | ```ts 38 | readBinary: (normalizedPath: string) => Promise 39 | ``` 40 | 41 | ### write 42 | 43 | ```ts 44 | write: (normalizedPath: string, data: string, options?: DataWriteOptions) => Promise 45 | ``` 46 | 47 | ### writeBinary 48 | 49 | ```ts 50 | writeBinary: (normalizedPath: string, data: ArrayBuffer, options?: DataWriteOptions) => Promise 51 | ``` 52 | 53 | ### append 54 | 55 | ```ts 56 | append: (normalizedPath: string, data: string, options?: DataWriteOptions) => Promise 57 | ``` 58 | 59 | ### getResourcePath 60 | 61 | ```ts 62 | getResourcePath: (normalizedPath: string) => string 63 | ``` 64 | 65 | ### mkdir 66 | 67 | ```ts 68 | mkdir: (normalizedPath: string) => Promise 69 | ``` 70 | 71 | ### trashSystem 72 | 73 | ```ts 74 | trashSystem: (normalizedPath: string) => Promise 75 | ``` 76 | 77 | ### trashLocal 78 | 79 | ```ts 80 | trashLocal: (normalizedPath: string) => Promise 81 | ``` 82 | 83 | ### rmdir 84 | 85 | ```ts 86 | rmdir: (normalizedPath: string, recursive: boolean) => Promise 87 | ``` 88 | 89 | ### remove 90 | 91 | ```ts 92 | remove: (normalizedPath: string) => Promise 93 | ``` 94 | 95 | ### rename 96 | 97 | ```ts 98 | rename: (normalizedPath: string, normalizedNewPath: string) => Promise 99 | ``` 100 | 101 | ### copy 102 | 103 | ```ts 104 | copy: (normalizedPath: string, normalizedNewPath: string) => Promise 105 | ``` 106 | -------------------------------------------------------------------------------- /docs/api/interfaces/DataWriteOptions.md: -------------------------------------------------------------------------------- 1 | # DataWriteOptions 2 | 3 | ## Properties 4 | 5 | ### ctime 6 | 7 | ```ts 8 | ctime: number 9 | ``` 10 | 11 | ### mtime 12 | 13 | ```ts 14 | mtime: number 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/Debouncer.md: -------------------------------------------------------------------------------- 1 | # Debouncer 2 | 3 | ## Methods 4 | 5 | ### cancel 6 | 7 | ```ts 8 | cancel: () => this 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorChange.md: -------------------------------------------------------------------------------- 1 | # EditorChange 2 | 3 | ## Properties 4 | 5 | ### text 6 | 7 | ```ts 8 | text: string 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorPosition.md: -------------------------------------------------------------------------------- 1 | # EditorPosition 2 | 3 | ## Properties 4 | 5 | ### line 6 | 7 | ```ts 8 | line: number 9 | ``` 10 | 11 | ### ch 12 | 13 | ```ts 14 | ch: number 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorRange.md: -------------------------------------------------------------------------------- 1 | # EditorRange 2 | 3 | ## Properties 4 | 5 | ### from 6 | 7 | ```ts 8 | from: EditorPosition 9 | ``` 10 | 11 | ### to 12 | 13 | ```ts 14 | to: EditorPosition 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorRangeOrCaret.md: -------------------------------------------------------------------------------- 1 | # EditorRangeOrCaret 2 | 3 | ## Properties 4 | 5 | ### from 6 | 7 | ```ts 8 | from: EditorPosition 9 | ``` 10 | 11 | ### to 12 | 13 | ```ts 14 | to: EditorPosition 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorSelection.md: -------------------------------------------------------------------------------- 1 | # EditorSelection 2 | 3 | ## Properties 4 | 5 | ### anchor 6 | 7 | ```ts 8 | anchor: EditorPosition 9 | ``` 10 | 11 | ### head 12 | 13 | ```ts 14 | head: EditorPosition 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorSelectionOrCaret.md: -------------------------------------------------------------------------------- 1 | # EditorSelectionOrCaret 2 | 3 | ## Properties 4 | 5 | ### anchor 6 | 7 | ```ts 8 | anchor: EditorPosition 9 | ``` 10 | 11 | ### head 12 | 13 | ```ts 14 | head: EditorPosition 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorSuggestContext.md: -------------------------------------------------------------------------------- 1 | # EditorSuggestContext 2 | 3 | ## Properties 4 | 5 | ### editor 6 | 7 | ```ts 8 | editor: Editor 9 | ``` 10 | 11 | ### file 12 | 13 | ```ts 14 | file: TFile 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorSuggestTriggerInfo.md: -------------------------------------------------------------------------------- 1 | # EditorSuggestTriggerInfo 2 | 3 | ## Properties 4 | 5 | ### start 6 | 7 | ```ts 8 | start: EditorPosition 9 | ``` 10 | 11 | The start position of the triggering text. This is used to position the popover. 12 | 13 | ### end 14 | 15 | ```ts 16 | end: EditorPosition 17 | ``` 18 | 19 | The end position of the triggering text. This is used to position the popover. 20 | 21 | ### query 22 | 23 | ```ts 24 | query: string 25 | ``` 26 | 27 | They query string (usually the text between start and end) that will be used to generate the suggestion content. 28 | -------------------------------------------------------------------------------- /docs/api/interfaces/EditorTransaction.md: -------------------------------------------------------------------------------- 1 | # EditorTransaction 2 | 3 | ## Properties 4 | 5 | ### replaceSelection 6 | 7 | ```ts 8 | replaceSelection: string 9 | ``` 10 | 11 | ### changes 12 | 13 | ```ts 14 | changes: EditorChange[] 15 | ``` 16 | 17 | ### selections 18 | 19 | ```ts 20 | selections: EditorRangeOrCaret[] 21 | ``` 22 | 23 | Multiple selections, overrides `selection`. 24 | 25 | ### selection 26 | 27 | ```ts 28 | selection: EditorRangeOrCaret 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/api/interfaces/EmbedCache.md: -------------------------------------------------------------------------------- 1 | # EmbedCache 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/EventListenerInfo.md: -------------------------------------------------------------------------------- 1 | # EventListenerInfo 2 | 3 | ## Properties 4 | 5 | ### selector 6 | 7 | ```ts 8 | selector: string 9 | ``` 10 | 11 | ### listener 12 | 13 | ```ts 14 | listener: Function 15 | ``` 16 | 17 | ### options 18 | 19 | ```ts 20 | options: boolean | AddEventListenerOptions 21 | ``` 22 | 23 | ### callback 24 | 25 | ```ts 26 | callback: Function 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/api/interfaces/EventRef.md: -------------------------------------------------------------------------------- 1 | # EventRef 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/FileStats.md: -------------------------------------------------------------------------------- 1 | # FileStats 2 | 3 | ## Properties 4 | 5 | ### ctime 6 | 7 | ```ts 8 | ctime: number 9 | ``` 10 | 11 | ### mtime 12 | 13 | ```ts 14 | mtime: number 15 | ``` 16 | 17 | ### size 18 | 19 | ```ts 20 | size: number 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/api/interfaces/FrontMatterCache.md: -------------------------------------------------------------------------------- 1 | # FrontMatterCache 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/FuzzyMatch.md: -------------------------------------------------------------------------------- 1 | # FuzzyMatch 2 | 3 | ## Properties 4 | 5 | ### item 6 | 7 | ```ts 8 | item: T 9 | ``` 10 | 11 | ### match 12 | 13 | ```ts 14 | match: SearchResult 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/HeadingCache.md: -------------------------------------------------------------------------------- 1 | # HeadingCache 2 | 3 | ## Properties 4 | 5 | ### heading 6 | 7 | ```ts 8 | heading: string 9 | ``` 10 | 11 | ### level 12 | 13 | ```ts 14 | level: number 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/HeadingSubpathResult.md: -------------------------------------------------------------------------------- 1 | # HeadingSubpathResult 2 | 3 | ## Properties 4 | 5 | ### type 6 | 7 | ```ts 8 | type: "heading" 9 | ``` 10 | 11 | ### current 12 | 13 | ```ts 14 | current: HeadingCache 15 | ``` 16 | 17 | ### next 18 | 19 | ```ts 20 | next: HeadingCache 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/api/interfaces/Hotkey.md: -------------------------------------------------------------------------------- 1 | # Hotkey 2 | 3 | ## Properties 4 | 5 | ### modifiers 6 | 7 | ```ts 8 | modifiers: Modifier[] 9 | ``` 10 | 11 | ### key 12 | 13 | ```ts 14 | key: string 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/HoverParent.md: -------------------------------------------------------------------------------- 1 | # HoverParent 2 | 3 | ## Properties 4 | 5 | ### hoverPopover 6 | 7 | ```ts 8 | hoverPopover: HoverPopover 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/ISuggestOwner.md: -------------------------------------------------------------------------------- 1 | # ISuggestOwner 2 | 3 | ## Methods 4 | 5 | ### renderSuggestion 6 | 7 | ```ts 8 | renderSuggestion: (value: T, el: HTMLElement) => void 9 | ``` 10 | 11 | Render the suggestion item into DOM. 12 | 13 | ### selectSuggestion 14 | 15 | ```ts 16 | selectSuggestion: (value: T, evt: MouseEvent | KeyboardEvent) => void 17 | ``` 18 | 19 | Called when the user makes a selection. 20 | -------------------------------------------------------------------------------- /docs/api/interfaces/Instruction.md: -------------------------------------------------------------------------------- 1 | # Instruction 2 | 3 | ## Properties 4 | 5 | ### command 6 | 7 | ```ts 8 | command: string 9 | ``` 10 | 11 | ### purpose 12 | 13 | ```ts 14 | purpose: string 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/KeymapContext.md: -------------------------------------------------------------------------------- 1 | # KeymapContext 2 | 3 | ## Properties 4 | 5 | ### vkey 6 | 7 | ```ts 8 | vkey: string 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/KeymapEventHandler.md: -------------------------------------------------------------------------------- 1 | # KeymapEventHandler 2 | 3 | ## Properties 4 | 5 | ### scope 6 | 7 | ```ts 8 | scope: Scope 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/KeymapInfo.md: -------------------------------------------------------------------------------- 1 | # KeymapInfo 2 | 3 | ## Properties 4 | 5 | ### modifiers 6 | 7 | ```ts 8 | modifiers: string 9 | ``` 10 | 11 | ### key 12 | 13 | ```ts 14 | key: string 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/LinkCache.md: -------------------------------------------------------------------------------- 1 | # LinkCache 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/ListItemCache.md: -------------------------------------------------------------------------------- 1 | # ListItemCache 2 | 3 | ## Properties 4 | 5 | ### id 6 | 7 | ```ts 8 | id: string 9 | ``` 10 | 11 | The block ID of this list item, if defined. 12 | 13 | ### task 14 | 15 | ```ts 16 | task: string 17 | ``` 18 | 19 | A single character indicating the checked status of a task. 20 | The space character `' '` is interpreted as an incomplete task. 21 | An other character is interpreted as completed task. 22 | `undefined` if this item isn't a task. 23 | 24 | ### parent 25 | 26 | ```ts 27 | parent: number 28 | ``` 29 | 30 | Line number of the parent list item (position.start.line). 31 | If this item has no parent (e.g. it's a root level list), 32 | then this value is the negative of the line number of the first list item (start of the list). 33 | 34 | Can be used to deduce which list items belongs to the same group (item1.parent === item2.parent). 35 | Can be used to reconstruct hierarchy information (parentItem.position.start.line === childItem.parent). 36 | -------------------------------------------------------------------------------- /docs/api/interfaces/ListedFiles.md: -------------------------------------------------------------------------------- 1 | # ListedFiles 2 | 3 | ## Properties 4 | 5 | ### files 6 | 7 | ```ts 8 | files: string[] 9 | ``` 10 | 11 | ### folders 12 | 13 | ```ts 14 | folders: string[] 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/Loc.md: -------------------------------------------------------------------------------- 1 | # Loc 2 | 3 | ## Properties 4 | 5 | ### line 6 | 7 | ```ts 8 | line: number 9 | ``` 10 | 11 | ### col 12 | 13 | ```ts 14 | col: number 15 | ``` 16 | 17 | ### offset 18 | 19 | ```ts 20 | offset: number 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/api/interfaces/MarkdownPostProcessor.md: -------------------------------------------------------------------------------- 1 | # MarkdownPostProcessor 2 | 3 | A post processor receives an element which is a section of the preview. 4 | 5 | Post processors can mutate the DOM to render various things, such as mermaid graphs, latex equations, or custom controls. 6 | 7 | If your post processor requires lifecycle management, for example, to clear an interval, kill a subprocess, etc when this element is 8 | removed from the app, look into {@link MarkdownPostProcessorContext#addChild} 9 | 10 | ## Properties 11 | 12 | ### sortOrder 13 | 14 | ```ts 15 | sortOrder: number 16 | ``` 17 | 18 | An optional integer sort order. Defaults to 0. Lower number runs before higher numbers. 19 | -------------------------------------------------------------------------------- /docs/api/interfaces/MarkdownPostProcessorContext.md: -------------------------------------------------------------------------------- 1 | # MarkdownPostProcessorContext 2 | 3 | ## Properties 4 | 5 | ### docId 6 | 7 | ```ts 8 | docId: string 9 | ``` 10 | 11 | ### sourcePath 12 | 13 | ```ts 14 | sourcePath: string 15 | ``` 16 | 17 | ### frontmatter 18 | 19 | ```ts 20 | frontmatter: any 21 | ``` 22 | 23 | ## Methods 24 | 25 | ### addChild 26 | 27 | ```ts 28 | addChild: (child: MarkdownRenderChild) => void 29 | ``` 30 | 31 | Adds a child component that will have its lifecycle managed by the renderer. 32 | 33 | Use this to add a dependent child to the renderer such that if the containerEl 34 | of the child is ever removed, the component's unload will be called. 35 | 36 | ### getSectionInfo 37 | 38 | ```ts 39 | getSectionInfo: (el: HTMLElement) => MarkdownSectionInformation 40 | ``` 41 | 42 | Gets the section information of this element at this point in time. 43 | Only call this function right before you need this information to get the most up-to-date version. 44 | This function may also return null in many circumstances; if you use it, you must be prepared to deal with nulls. 45 | -------------------------------------------------------------------------------- /docs/api/interfaces/MarkdownPreviewEvents.md: -------------------------------------------------------------------------------- 1 | # MarkdownPreviewEvents 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/MarkdownSectionInformation.md: -------------------------------------------------------------------------------- 1 | # MarkdownSectionInformation 2 | 3 | ## Properties 4 | 5 | ### text 6 | 7 | ```ts 8 | text: string 9 | ``` 10 | 11 | ### lineStart 12 | 13 | ```ts 14 | lineStart: number 15 | ``` 16 | 17 | ### lineEnd 18 | 19 | ```ts 20 | lineEnd: number 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/api/interfaces/MarkdownSubView.md: -------------------------------------------------------------------------------- 1 | # MarkdownSubView 2 | 3 | ## Methods 4 | 5 | ### getScroll 6 | 7 | ```ts 8 | getScroll: () => number 9 | ``` 10 | 11 | ### applyScroll 12 | 13 | ```ts 14 | applyScroll: (scroll: number) => void 15 | ``` 16 | 17 | ### get 18 | 19 | ```ts 20 | get: () => string 21 | ``` 22 | 23 | ### set 24 | 25 | ```ts 26 | set: (data: string, clear: boolean) => void 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/api/interfaces/ObsidianProtocolData.md: -------------------------------------------------------------------------------- 1 | # ObsidianProtocolData 2 | 3 | ## Properties 4 | 5 | ### action 6 | 7 | ```ts 8 | action: string 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/OpenViewState.md: -------------------------------------------------------------------------------- 1 | # OpenViewState 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/PluginManifest.md: -------------------------------------------------------------------------------- 1 | # PluginManifest 2 | 3 | ## Properties 4 | 5 | ### dir 6 | 7 | ```ts 8 | dir: string 9 | ``` 10 | 11 | ### id 12 | 13 | ```ts 14 | id: string 15 | ``` 16 | 17 | ### name 18 | 19 | ```ts 20 | name: string 21 | ``` 22 | 23 | ### author 24 | 25 | ```ts 26 | author: string 27 | ``` 28 | 29 | ### version 30 | 31 | ```ts 32 | version: string 33 | ``` 34 | 35 | ### minAppVersion 36 | 37 | ```ts 38 | minAppVersion: string 39 | ``` 40 | 41 | ### description 42 | 43 | ```ts 44 | description: string 45 | ``` 46 | 47 | ### authorUrl 48 | 49 | ```ts 50 | authorUrl: string 51 | ``` 52 | 53 | ### isDesktopOnly 54 | 55 | ```ts 56 | isDesktopOnly: boolean 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/api/interfaces/Point.md: -------------------------------------------------------------------------------- 1 | # Point 2 | 3 | ## Properties 4 | 5 | ### x 6 | 7 | ```ts 8 | x: number 9 | ``` 10 | 11 | ### y 12 | 13 | ```ts 14 | y: number 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/Pos.md: -------------------------------------------------------------------------------- 1 | # Pos 2 | 3 | ## Properties 4 | 5 | ### start 6 | 7 | ```ts 8 | start: Loc 9 | ``` 10 | 11 | ### end 12 | 13 | ```ts 14 | end: Loc 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/PreparedQuery.md: -------------------------------------------------------------------------------- 1 | # PreparedQuery 2 | 3 | ## Properties 4 | 5 | ### query 6 | 7 | ```ts 8 | query: string 9 | ``` 10 | 11 | ### tokens 12 | 13 | ```ts 14 | tokens: string[] 15 | ``` 16 | 17 | ### fuzzy 18 | 19 | ```ts 20 | fuzzy: string[] 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/api/interfaces/Rect_2.md: -------------------------------------------------------------------------------- 1 | # Rect_2 2 | 3 | ## Properties 4 | 5 | ### x 6 | 7 | ```ts 8 | x: number 9 | ``` 10 | 11 | ### y 12 | 13 | ```ts 14 | y: number 15 | ``` 16 | 17 | ### w 18 | 19 | ```ts 20 | w: number 21 | ``` 22 | 23 | ### h 24 | 25 | ```ts 26 | h: number 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/api/interfaces/ReferenceCache.md: -------------------------------------------------------------------------------- 1 | # ReferenceCache 2 | 3 | ## Properties 4 | 5 | ### link 6 | 7 | ```ts 8 | link: string 9 | ``` 10 | 11 | ### original 12 | 13 | ```ts 14 | original: string 15 | ``` 16 | 17 | ### displayText 18 | 19 | ```ts 20 | displayText: string 21 | ``` 22 | 23 | if title is different than link text, in the case of [[page name|display name]] 24 | -------------------------------------------------------------------------------- /docs/api/interfaces/RequestParam.md: -------------------------------------------------------------------------------- 1 | # RequestParam 2 | 3 | ## Properties 4 | 5 | ### url 6 | 7 | ```ts 8 | url: string 9 | ``` 10 | 11 | ### method 12 | 13 | ```ts 14 | method: string 15 | ``` 16 | 17 | ### contentType 18 | 19 | ```ts 20 | contentType: string 21 | ``` 22 | 23 | ### body 24 | 25 | ```ts 26 | body: string 27 | ``` 28 | 29 | ### headers 30 | 31 | ```ts 32 | headers: Record 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/api/interfaces/RequestUrlParam.md: -------------------------------------------------------------------------------- 1 | # RequestUrlParam 2 | 3 | ## Properties 4 | 5 | ### url 6 | 7 | ```ts 8 | url: string 9 | ``` 10 | 11 | ### method 12 | 13 | ```ts 14 | method: string 15 | ``` 16 | 17 | ### contentType 18 | 19 | ```ts 20 | contentType: string 21 | ``` 22 | 23 | ### body 24 | 25 | ```ts 26 | body: string | ArrayBuffer 27 | ``` 28 | 29 | ### headers 30 | 31 | ```ts 32 | headers: Record 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/api/interfaces/RequestUrlResponse.md: -------------------------------------------------------------------------------- 1 | # RequestUrlResponse 2 | 3 | ## Properties 4 | 5 | ### status 6 | 7 | ```ts 8 | status: number 9 | ``` 10 | 11 | ### headers 12 | 13 | ```ts 14 | headers: Record 15 | ``` 16 | 17 | ### arrayBuffer 18 | 19 | ```ts 20 | arrayBuffer: ArrayBuffer 21 | ``` 22 | 23 | ### json 24 | 25 | ```ts 26 | json: any 27 | ``` 28 | 29 | ### text 30 | 31 | ```ts 32 | text: string 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/api/interfaces/SearchResult.md: -------------------------------------------------------------------------------- 1 | # SearchResult 2 | 3 | ## Properties 4 | 5 | ### score 6 | 7 | ```ts 8 | score: number 9 | ``` 10 | 11 | ### matches 12 | 13 | ```ts 14 | matches: SearchMatches 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/SearchResultContainer.md: -------------------------------------------------------------------------------- 1 | # SearchResultContainer 2 | 3 | ## Properties 4 | 5 | ### match 6 | 7 | ```ts 8 | match: SearchResult 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/SectionCache.md: -------------------------------------------------------------------------------- 1 | # SectionCache 2 | 3 | ## Properties 4 | 5 | ### id 6 | 7 | ```ts 8 | id: string 9 | ``` 10 | 11 | The block ID of this section, if defined. 12 | 13 | ### type 14 | 15 | ```ts 16 | type: string 17 | ``` 18 | 19 | The type string generated by the parser. 20 | -------------------------------------------------------------------------------- /docs/api/interfaces/Stat.md: -------------------------------------------------------------------------------- 1 | # Stat 2 | 3 | ## Properties 4 | 5 | ### type 6 | 7 | ```ts 8 | type: "file" | "folder" 9 | ``` 10 | 11 | ### ctime 12 | 13 | ```ts 14 | ctime: number 15 | ``` 16 | 17 | ### mtime 18 | 19 | ```ts 20 | mtime: number 21 | ``` 22 | 23 | ### size 24 | 25 | ```ts 26 | size: number 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/api/interfaces/SubpathResult.md: -------------------------------------------------------------------------------- 1 | # SubpathResult 2 | 3 | ## Properties 4 | 5 | ### start 6 | 7 | ```ts 8 | start: Loc 9 | ``` 10 | 11 | ### end 12 | 13 | ```ts 14 | end: Loc 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/api/interfaces/TagCache.md: -------------------------------------------------------------------------------- 1 | # TagCache 2 | 3 | ## Properties 4 | 5 | ### tag 6 | 7 | ```ts 8 | tag: string 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/api/interfaces/ViewState.md: -------------------------------------------------------------------------------- 1 | # ViewState 2 | 3 | ## Properties 4 | 5 | ### type 6 | 7 | ```ts 8 | type: string 9 | ``` 10 | 11 | ### state 12 | 13 | ```ts 14 | state: any 15 | ``` 16 | 17 | ### active 18 | 19 | ```ts 20 | active: boolean 21 | ``` 22 | 23 | ### pinned 24 | 25 | ```ts 26 | pinned: boolean 27 | ``` 28 | 29 | ### group 30 | 31 | ```ts 32 | group: WorkspaceLeaf 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/api/interfaces/ViewStateResult.md: -------------------------------------------------------------------------------- 1 | # ViewStateResult 2 | -------------------------------------------------------------------------------- /docs/api/interfaces/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Interfaces" 3 | } 4 | -------------------------------------------------------------------------------- /docs/api/types/EditorCommandName.md: -------------------------------------------------------------------------------- 1 | # EditorCommandName 2 | 3 | ```ts 4 | export type EditorCommandName = 'goUp' | 'goDown' | 'goLeft' | 'goRight' | 'goStart' | 'goEnd' | 'indentMore' | 'indentLess' | 'newlineAndIndent' | 'swapLineUp' | 'swapLineDown' | 'deleteLine' | 'toggleFold' | 'foldAll' | 'unfoldAll'; 5 | ``` 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/api/types/KeymapEventListener.md: -------------------------------------------------------------------------------- 1 | # KeymapEventListener 2 | 3 | ```ts 4 | export type KeymapEventListener = (evt: KeyboardEvent, ctx: KeymapContext) => boolean | void; 5 | ``` 6 | 7 | Return `false` to automatically preventDefault 8 | -------------------------------------------------------------------------------- /docs/api/types/MarkdownViewModeType.md: -------------------------------------------------------------------------------- 1 | # MarkdownViewModeType 2 | 3 | ```ts 4 | export type MarkdownViewModeType = 'source' | 'preview'; 5 | ``` 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/api/types/Modifier.md: -------------------------------------------------------------------------------- 1 | # Modifier 2 | 3 | ```ts 4 | export type Modifier = 'Mod' | 'Ctrl' | 'Meta' | 'Shift' | 'Alt'; 5 | ``` 6 | 7 | Mod = Cmd on MacOS and Ctrl on other OS 8 | Ctrl = Ctrl key for every OS 9 | Meta = Cmd on MacOS and Win key on other OS 10 | -------------------------------------------------------------------------------- /docs/api/types/ObsidianProtocolHandler.md: -------------------------------------------------------------------------------- 1 | # ObsidianProtocolHandler 2 | 3 | ```ts 4 | export type ObsidianProtocolHandler = (params: ObsidianProtocolData) => any; 5 | ``` 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/api/types/SearchMatchPart.md: -------------------------------------------------------------------------------- 1 | # SearchMatchPart 2 | 3 | ```ts 4 | export type SearchMatchPart = [ 5 | number, 6 | number 7 | ]; 8 | ``` 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/api/types/SearchMatches.md: -------------------------------------------------------------------------------- 1 | # SearchMatches 2 | 3 | ```ts 4 | export type SearchMatches = SearchMatchPart[]; 5 | ``` 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/api/types/SplitDirection.md: -------------------------------------------------------------------------------- 1 | # SplitDirection 2 | 3 | ```ts 4 | export type SplitDirection = 'vertical' | 'horizontal'; 5 | ``` 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/api/types/UserEvent.md: -------------------------------------------------------------------------------- 1 | # UserEvent 2 | 3 | ```ts 4 | export type UserEvent = MouseEvent | KeyboardEvent | TouchEvent | PointerEvent; 5 | ``` 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/api/types/ViewCreator.md: -------------------------------------------------------------------------------- 1 | # ViewCreator 2 | 3 | ```ts 4 | export type ViewCreator = (leaf: WorkspaceLeaf) => View; 5 | ``` 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/api/types/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Types" 3 | } 4 | -------------------------------------------------------------------------------- /docs/concepts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Concepts", 3 | "position": 20 4 | } 5 | -------------------------------------------------------------------------------- /docs/concepts/codemirror.md: -------------------------------------------------------------------------------- 1 | # CodeMirror 2 | 3 | Obsidian uses [CodeMirror](https://codemirror.net/) as the underlying text editor. 4 | 5 | :::danger 6 | Only consider CodeMirror if what you want to do isn't already possible through the [Editor](../guides/editor.md). 7 | 8 | While Obsidian makes the underlying CodeMirror instance available to plugins through the Obsidian API, most plugins shouldn't use it. If possible, use [`Editor`](../api/classes/Editor.md), a high-level abstraction that bridges breaking changes between different versions of CodeMirror. 9 | ::: 10 | 11 | You can access the CodeMirror editor on an active Markdown view: 12 | 13 | ```ts 14 | const view = this.app.workspace.getActiveViewOfType(MarkdownView); 15 | 16 | if (view) { 17 | const editor = view.sourceMode.cmEditor; 18 | } 19 | ``` 20 | 21 | You can also use [`registerCodeMirror()`](../api/classes/Plugin_2.md#registercodemirror) to register a callback function whenever the user opens a new editor. 22 | 23 | -------------------------------------------------------------------------------- /docs/concepts/plugin-anatomy.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 20 3 | --- 4 | 5 | # Anatomy of a plugin 6 | 7 | The [`Plugin`](api/../../api/classes/Plugin_2.md) class defines the lifecycle of a plugin and exposes the operations available to all plugins: 8 | 9 | ```ts {1,3} title="main.ts" 10 | import { Plugin } from "obsidian"; 11 | 12 | export default class ExamplePlugin extends Plugin { 13 | async onload() { 14 | // Configure resources needed by the plugin. 15 | } 16 | async onunload() { 17 | // Release any resources configured by the plugin. 18 | } 19 | } 20 | ``` 21 | 22 | ## Plugin lifecycle 23 | 24 | [`onload()`](../api/classes/Component.md#onload) runs whenever Obsidian the user starts using the plugin. This is where you'll configure most of the plugin's capabilities. 25 | 26 | [`onunload()`](../api/classes/Component.md#onunload) runs when the plugin is disabled. Any resources that your plugin is using must be released here to avoid affecting the performance of Obsidian after your plugin has been disabled. 27 | 28 | To better understand when these methods are called, you can print a message to the console whenever the plugin loads and unloads. The console is a valuable tool that lets developers monitor the status of their code. 29 | 30 | To view the console: 31 | 32 | 1. Toggle the Developer Tools by pressing Ctrl+Shift+I in Windows and Linux, or Cmd-Option-I on macOS. 33 | 1. Click on the Console tab in the Developer Tools window. 34 | 35 | ```ts {5,8} title="main.ts" 36 | import { Plugin } from "obsidian"; 37 | 38 | export default class ExamplePlugin extends Plugin { 39 | async onload() { 40 | console.log('loading plugin') 41 | } 42 | async onunload() { 43 | console.log('unloading plugin') 44 | } 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /docs/concepts/vault.md: -------------------------------------------------------------------------------- 1 | # Vault 2 | 3 | From the official documentation on [Working with multiple Vaults](https://help.obsidian.md/How+to/Working+with+multiple+vaults): 4 | 5 | > Each collection of notes in Obsidian is known as a Vault. A Vault consists of a folder, and any sub-folders within it. 6 | 7 | While your plugin can access the file system like any other Node.js application, the [`Vault`](../api/classes/Vault.md) module aims to make it easier to work with files and folders within a Vault. 8 | 9 | The following example recursively prints the paths of all Markdown files in a Vault: 10 | 11 | ```ts 12 | const files = this.app.vault.getMarkdownFiles() 13 | 14 | for (let i = 0; i < files.length; i++) { 15 | console.log(files[i].path); 16 | } 17 | ``` 18 | 19 | :::tip 20 | If you want to list _all_ files, and not just Markdown documents, use [`getFiles()`](../api/classes/Vault.md#getfiles) instead. 21 | ::: 22 | 23 | ## Read files 24 | 25 | There are two methods for reading the content of a file: [`read()`](../api/classes/Vault.md#read) and [`cachedRead()`](../api/classes/Vault.md#cachedread). 26 | 27 | - If you only want to display the content to the user, then use `cachedRead()` to avoid reading the file from disk multiple times. 28 | - If you want to read the content, change it, and then write it back to disk, then use `read()` to avoid potentially overwriting the file with a stale copy. 29 | 30 | :::info 31 | The only difference between `cachedRead()` and `read()` is when the file was modified outside of Obsidian just before the plugin reads it. As soon as the file system notifies Obsidian that the file has changed from the outside, `cachedRead()` behaves _exactly_ like `read()`. Similarly, if you save the file within Obsidian, the read cache is flushed as well. 32 | ::: 33 | 34 | The following example reads the content of all Markdown files in the Vault and returns the average document size: 35 | 36 | ```ts title="main.ts" 37 | import { Notice, Plugin } from "obsidian"; 38 | 39 | export default class ExamplePlugin extends Plugin { 40 | async onload() { 41 | this.addRibbonIcon("info", "Calculate average file length", async () => { 42 | const fileLength = await this.averageFileLength(); 43 | new Notice(`The average file length is ${fileLength} characters.`); 44 | }); 45 | } 46 | 47 | async averageFileLength(): Promise { 48 | const { vault } = this.app; 49 | 50 | const fileContents: string[] = await Promise.all( 51 | vault.getMarkdownFiles().map((file) => vault.cachedRead(file)) 52 | ); 53 | 54 | let totalLength = 0; 55 | fileContents.forEach((content) => { 56 | totalLength += content.length; 57 | }); 58 | 59 | return totalLength / fileContents.length; 60 | } 61 | } 62 | ``` 63 | 64 | ## Delete files 65 | 66 | There are two methods to delete a file, [`delete()`](../api/classes/Vault.md#delete), and [`trash()`](../api/classes/Vault.md#trash). Which one you should use depends on if you want to allow the user to change their mind. 67 | 68 | - `delete()` removes the file without a trace. 69 | - `trash()` moves the file to the trash bin. 70 | 71 | When you use `trash()`, you have the option to move the file to the system's trash bin, or to a local `.trash` folder at the root of the user's Vault. 72 | 73 | ## Is it a file or folder? 74 | 75 | Some operations return or accept a [`TAbstractFile`](../api/classes/TAbstractFile.md) object, which can be either a file or a folder. Always check the concrete type of a `TAbstractFile` before you use it. 76 | 77 | ```ts 78 | const folderOrFile = this.app.vault.getAbstractFileByPath("folderOrFile"); 79 | 80 | if (folderOrFile instanceof TFile) { 81 | console.log("It's a file!"); 82 | } else if (folderOrFile instanceof TFolder) { 83 | console.log("It's a folder!"); 84 | } 85 | ``` 86 | -------------------------------------------------------------------------------- /docs/concepts/workspace.md: -------------------------------------------------------------------------------- 1 | # Workspace 2 | 3 | Obsidian lets you configure what content is visible to you at any given time. Hide the file explorer when you don't need it, display multiple documents side by side, or show an outline of your document while you're working on it. The configuration of visible content within your application window is known as the _workspace_. 4 | 5 | The workspace is implemented as a [tree data structure](https://en.wikipedia.org/wiki/Tree_(data_structure)), where each node in the tree is referred to as a [workspace item](../api/classes/WorkspaceItem.md). There are two types of workspace items: [_parents_](../api/classes/WorkspaceParent.md) and [_leaves_](../api/classes/WorkspaceLeaf.md). The main difference is that parent items can contain _child_ items, including other parent items, whereas leaf items can't contain any workspace items at all. 6 | 7 | There are two types of parent items, [_splits_](../api/classes/WorkspaceSplit.md) and [_tabs_](../api/classes/WorkspaceTabs.md), which determine how the children are presented to the user: 8 | 9 | ```mermaid 10 | flowchart TD 11 | split{Split} 12 | split --> A((Leaf)) 13 | split --> B((Leaf)) 14 | split --> C((Leaf)) 15 | 16 | tabs{Tabs} 17 | tabs --> X((Leaf)) 18 | tabs --> Y((Leaf)) 19 | tabs --> Z((Leaf)) 20 | ``` 21 | 22 | - A split item lays out its child items one after another along a vertical or horizontal direction. 23 | - A tabs item only displays one child item at a time and hides the others. 24 | 25 | The workspace has three special split items under it: _left_, _right_, and _root_. The following diagram shows a example of what a typical workspace could look like: 26 | 27 | ```mermaid 28 | flowchart TD 29 | Workspace --> Left{Left split} 30 | Workspace --> Root{Root split} 31 | Workspace --> Right{Right split} 32 | 33 | Left --> leftTabs{Tabs} 34 | leftTabs --> A((Leaf)) 35 | leftTabs --> B((Leaf)) 36 | 37 | Root --> C{Split} 38 | Root --> D((Leaf)) 39 | 40 | C --> E((Leaf)) 41 | C --> F((Leaf)) 42 | 43 | Right --> rightTabs{Tabs} 44 | 45 | rightTabs --> I((Leaf)) 46 | rightTabs --> J((Leaf)) 47 | rightTabs --> K((Leaf)) 48 | ``` 49 | 50 | A leaf is a window that can display content in different ways. The type of leaf determines how content is displayed, and correspond to a specific _view_. For example, a leaf of type `graph` displays the [graph view](https://help.obsidian.md/Plugins/Graph+view). 51 | 52 | ## Splits 53 | 54 | By default, the direction of the root split is set to vertical. When you create a new leaf to it, Obsidian creates a new column in the user interface. When you split a leaf, the resulting leaves are added to a new split item. While there's no defined limit to the number of levels you can create under the root split, in practice their usefulness diminish for each level. 55 | 56 | ```mermaid 57 | flowchart TD 58 | rootBefore{"Root split\n(before)"} 59 | 60 | rootBefore --> leaf1((Leaf)) 61 | rootBefore --> leaf2((Leaf)) 62 | 63 | rootAfter{"Root split\n(after)"} 64 | 65 | rootAfter --> split{Split} 66 | rootAfter --> leaf3((Leaf)) 67 | split --> leaf4((Leaf)) 68 | split --> leaf5((Leaf)) 69 | ``` 70 | 71 | The left and right splits work a little differently. When you split a leaf in the side docks, Obsidian generates a new tabs item and adds the new leaf under it. Effectively, this means they can only have three levels of workspace items at any time, and any direct children must be tabs items. 72 | 73 | ```mermaid 74 | flowchart TD 75 | split1{"Right split\n(before)"} 76 | tabs1{Tabs} 77 | leaf1((Leaf)) 78 | leaf2((Leaf)) 79 | 80 | split1 --> tabs1 81 | tabs1 --> leaf1 82 | tabs1 --> leaf2 83 | 84 | split2{"Right split\n(after)"} 85 | tabs2{Tabs} 86 | tabs3{Tabs} 87 | leaf3((Leaf)) 88 | leaf4((Leaf)) 89 | leaf5((Leaf)) 90 | 91 | split2 --> tabs2 92 | tabs2 --> leaf3 93 | tabs2 --> leaf4 94 | 95 | split2 --> tabs3 96 | tabs3 --> leaf5 97 | ``` 98 | 99 | ## Inspect the workspace 100 | 101 | You can access the workspace through the [App](../api/classes/App.md) object. The following example prints the type of every leaf in the workspace: 102 | 103 | ```ts title="main.ts" {6-8} 104 | import { Plugin } from "obsidian"; 105 | 106 | export default class ExamplePlugin extends Plugin { 107 | async onload() { 108 | this.addRibbonIcon("dice", "Print leaf types", () => { 109 | this.app.workspace.iterateAllLeaves((leaf) => { 110 | console.log(leaf.getViewState().type); 111 | }); 112 | }); 113 | } 114 | } 115 | ``` 116 | 117 | ## Leaf lifecycle 118 | 119 | Plugins can add leaves of any type to the workspace, as well as define new leaf types through [custom views](../guides/custom-views.md). Here are a few ways to add a leaf to the workspace. For more ways, refer to [`Workspace`](../api/classes/Workspace.md). 120 | 121 | - If you want to add a new leaf in the root split, use [`workspace.getLeaf(true)`](../api/classes/Workspace.md#getleaf). 122 | - If you want to add a new leaf in any of the side bars, use [`workspace.getLeftLeaf()`](../api/classes/Workspace.md#getleftleaf) and [`workspace.getRightLeaf()`](../api/classes/Workspace.md#getrightleaf). Both let you decide whether to add the leaf to a new split. 123 | 124 | You can also explicitly add the leaf in the split of your choice, using [`createLeafInParent()`](../api/classes/Workspace.md#createleafinparent). 125 | 126 | Unless explicitly removed, any leaves that a plugin add to the workspace remain even after the plugin is disabled. Plugins are responsible for removing any leaves they add to the workspace. 127 | 128 | To remove a leaf from the workspace, call [`detach()`](../api/classes/WorkspaceLeaf.md#detach) on the leaf you want to remove. You can also remove all leaves of a certain type, by using [`detachLeavesOfType()`](../api/classes/Workspace.md#detachleavesoftype). 129 | 130 | ## Leaf groups 131 | 132 | You can create [linked panes](https://help.obsidian.md/User+interface/Workspace/Panes/Linked+pane) by assigning multiple leaves to the same group, using [`setGroup()`](../api/classes/WorkspaceLeaf.md#setgroup). 133 | 134 | ```ts 135 | leaves.forEach((leaf) => leaf.setGroup("group1"); 136 | ``` 137 | -------------------------------------------------------------------------------- /docs/contribute.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 9999 3 | --- 4 | 5 | # Contribute to this site 6 | 7 | Thanks for considering contributing to the project! 8 | 9 | There's a link at the bottom of every page that says **Edit this page**. If you click it, you're taken to that docs page on GitHub where you can edit and submit a change right away. 10 | 11 | ## Style guide 12 | 13 | This site uses the [Google developer documentation style guide](https://developers.google.com/style) and the [Microsoft Style Guide](https://docs.microsoft.com/style-guide/welcome/). 14 | 15 | If you see anything that violates any of these style guides, please let me know by [creating an issue on GitHub](https://github.com/marcusolsson/obsidian-plugin-docs/issues/new). 16 | 17 | ## The four types of documentation 18 | 19 | This site hosts four types of documentation: 20 | 21 | - **Tutorials** are _learning-oriented_: they take the reader through a series of steps to complete a project. For example, [Create your first plugin](getting-started/create-your-first-plugin.md). 22 | - **Guides** are _goal-oriented_: they provide step-by-step instructions for how to solve a specific problem. For example, [Settings](guides/settings.md). 23 | - **Reference** is _information-oriented_: its only job is to describe. For example, [Plugin](api/classes/Plugin_2.md). 24 | - **Concepts** is _understanding-oriented_: they deepen the reader's understanding in a topic. For example, [Workspace](concepts/workspace.md). 25 | 26 | For more information, refer to [The documentation system](https://documentation.divio.com/) by [Divio](https://www.divio.com/). 27 | 28 | ### Tutorials 29 | 30 | Each tutorial should have the following structure: 31 | 32 | 1. Description of what the reader will have accomplished after the tutorial. 33 | 1. **Prerequisites** section that describes what the reader needs to complete the tutorial. 34 | 1. Headings for each step that start with "Step X — " (that's an [em-dash](https://en.wikipedia.org/wiki/Dash#Em_dash)), followed by a sentence in imperative form. For example, "Step 3 — Submit plugin for review". 35 | 1. Closing section that summarizes what the reader has accomplished, and where they can go next. 36 | 37 | ### Guides 38 | 39 | Each guide should have the following structure: 40 | 41 | 1. Description of the guide. 42 | 1. Summary of what the reader will build or learn in the guide. 43 | 1. Full code example 44 | 1. Detailed explanation of the code example 45 | 46 | The code block for the full code example must have a title with the filename, for example `title="main.ts"`. 47 | 48 | The example must be complete: the reader can copy-paste it into their own editor and run it without modifications. 49 | 50 | For simpler code examples, use [line highlighting](https://docusaurus.io/docs/markdown-features/code-blocks#line-highlighting) to draw the reader's attention to the important parts. 51 | 52 | For more complex code examples you may add one or more code blocks that duplicate sections of the full example, to allow for a more detailed explanation. 53 | -------------------------------------------------------------------------------- /docs/examples/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Examples", 3 | "position": 50 4 | } 5 | -------------------------------------------------------------------------------- /docs/examples/insert-link.md: -------------------------------------------------------------------------------- 1 | # Insert link 2 | 3 | This example adds a command that opens a modal to insert a Markdown link. It uses the editor to set the current selection as the default link text, and then replaces the selection when user inserts the link. 4 | 5 | This example assumes knowledge of [commands](../guides/commands.md), [modals](../guides/modals.md), and the [editor](../guides/editor.md). If you have difficulties to understand this example, refer to the corresponding guides before you continue reading. 6 | 7 | Here's what you'll create: 8 | 9 | ![Insert link modal](../../static/img/example-insert-link.gif) 10 | 11 | Here's the full source code: 12 | 13 | ```ts title="main.ts" 14 | import { Editor, Plugin } from "obsidian"; 15 | import { InsertLinkModal } from "./modal"; 16 | 17 | export default class InsertLinkPlugin extends Plugin { 18 | async onload() { 19 | this.addCommand({ 20 | id: "insert-link", 21 | name: "Insert link", 22 | editorCallback: (editor: Editor) => { 23 | const selectedText = editor.getSelection(); 24 | 25 | const onSubmit = (text: string, url: string) => { 26 | editor.replaceSelection(`[${text}](${url})`); 27 | }; 28 | 29 | new InsertLinkModal(this.app, selectedText, onSubmit).open(); 30 | }, 31 | }); 32 | } 33 | } 34 | ``` 35 | 36 | ```ts title="modal.ts" 37 | import { App, Modal, Setting } from "obsidian"; 38 | 39 | export class InsertLinkModal extends Modal { 40 | linkText: string; 41 | linkUrl: string; 42 | 43 | onSubmit: (linkText: string, linkUrl: string) => void; 44 | 45 | constructor( 46 | app: App, 47 | defaultLinkText: string, 48 | onSubmit: (linkText: string, linkUrl: string) => void 49 | ) { 50 | super(app); 51 | this.linkText = defaultLinkText; 52 | this.onSubmit = onSubmit; 53 | } 54 | 55 | onOpen() { 56 | const { contentEl } = this; 57 | 58 | contentEl.createEl("h1", { text: "Insert link" }); 59 | 60 | new Setting(contentEl).setName("Link text").addText((text) => 61 | text.setValue(this.linkText).onChange((value) => { 62 | this.linkText = value; 63 | }) 64 | ); 65 | 66 | new Setting(contentEl).setName("Link URL").addText((text) => 67 | text.setValue(this.linkUrl).onChange((value) => { 68 | this.linkUrl = value; 69 | }) 70 | ); 71 | 72 | new Setting(contentEl).addButton((btn) => 73 | btn 74 | .setButtonText("Insert") 75 | .setCta() 76 | .onClick(() => { 77 | this.close(); 78 | this.onSubmit(this.linkText, this.linkUrl); 79 | }) 80 | ); 81 | } 82 | 83 | onClose() { 84 | let { contentEl } = this; 85 | contentEl.empty(); 86 | } 87 | } 88 | ``` 89 | -------------------------------------------------------------------------------- /docs/getting-started/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Getting started", 3 | "position": 10 4 | } 5 | -------------------------------------------------------------------------------- /docs/getting-started/create-your-first-plugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 10 3 | --- 4 | 5 | # Create your first plugin 6 | 7 | In this guide, you'll build a plugin for Obsidian. If you prefer a video walk-through, check out [Create Your Own Obsidian Plugin](https://www.youtube.com/watch?v=9lA-jaMNS0k) by [Antone Heyward](https://www.youtube.com/channel/UC9w43btR2UUsfR6ZUf3AlqQ). 8 | 9 | :::warning Before you start 10 | **Don't develop plugins in your main vault.** When you develop a plugin, one mistake can lead to unintentional modifications to your vault. You also risk **permanently deleting your vault**. 11 | ::: 12 | 13 | ## Prerequisites 14 | 15 | To complete this guide, you will need: 16 | 17 | - [Git](https://git-scm.com/) installed on your local machine. 18 | - A [GitHub](https://github.com) account. 19 | - A local development environment for [Node.js](https://Node.js.org/en/about/). 20 | 21 | ## Step 1 — Download the sample plugin 22 | 23 | First, you'll download a working sample plugin that you'll build upon for the remaining steps. 24 | 25 | 1. Browse to the [Obsidian Sample Plugin](https://github.com/obsidianmd/obsidian-sample-plugin). 26 | 1. Click **Use this template**. 27 | 1. In **Repository name**, enter the name of your plugin. Obsidian plugins are typically prefixed by `obsidian-`. For example, `obsidian-instant-coffee`. 28 | 1. Click **Create repository from template**. 29 | 30 | You've now created your own repository based on the Obsidian sample plugin. Next, you'll download the source code on your local machine. 31 | 32 | 1. Browse to the repository you just created. 33 | 1. Click **Code**, and copy the path to your repository. 34 | 1. Open a terminal and navigate to the vault. 35 | 36 | ```bash 37 | cd path/to/vault/.obsidian/plugins 38 | ``` 39 | 40 | 1. Download the source code into the plugins folder. 41 | 42 | ```bash 43 | git clone https://github.com/your-username/obsidian-instant-coffee.git 44 | ``` 45 | 46 | ## Step 2 — Build the plugin 47 | 48 | In this section, you'll build the source code for the plugin. 49 | 50 | 1. Navigate into the plugin folder. 51 | 52 | ```bash 53 | cd path/to/vault/.obsidian/plugins/obsidian-instant-coffee 54 | ``` 55 | 56 | 1. Install dependencies. 57 | 58 | ```bash npm2yarn 59 | npm install 60 | ``` 61 | 62 | 1. Compile the source code. The following command generates a `main.js` that contains the compiled version of your plugin. 63 | 64 | ```bash npm2yarn 65 | npm run dev 66 | ``` 67 | 68 | ## Step 3 — Enable the plugin 69 | 70 | To load a plugin in Obsidian, you first need to enable it. 71 | 72 | 1. Open **Preferences** in Obsidian. 73 | 1. In the side menu, click **Community plugins**. 74 | 1. Under **Installed plugins**, enable the **Sample Plugin** by clicking the toggle button next to it. 75 | 76 | You're now running a custom plugin that you've built yourself. Nice! 💪 77 | 78 | Though, "Sample Plugin" is probably not the name you had in mind for your plugin. Let's change that. 79 | 80 | ## Step 4 — Update the plugin manifest 81 | 82 | In this step, you'll update the _manifest_ to rename the plugin., The plugin manifest, `manifest.json` is a file that contains information about your plugin, such as its name and version. 83 | 84 | 1. Open the `obsidian-instant-coffee` directory in a code editor, such as [Visual Studio Code](https://code.visualstudio.com/). 85 | 1. Open `manifest.json` in your editor. 86 | 1. Change `id` to your plugin ID, for example `obsidian-instant-coffee`. 87 | 1. Change `name` to the human-friendly name of the plugin, for example `Instant coffee`. 88 | 1. If you'd like, then update `description`, `author`, and `authorUrl` as well. 89 | 90 | A plugin is also a Node.js package, which you can configure in the `package.json`. You shouldn't need to worry much about it for now. For now, update it to match the properties in the plugin manifest. 91 | 92 | 1. Open `package.json` in your editor. 93 | 1. Change `name` to match the `id` in `manifest.json`. 94 | 1. Change `version` to match the `version` in `manifest.json`. 95 | 1. Change `description` to match the `description` in `manifest.json`. 96 | 1. Restart Obsidian to reload your plugin. 97 | 98 | ## Step 5 — Update the source code 99 | 100 | In this step, you'll make a change to the source code and reload the plugin to reflect your change. 101 | 102 | 1. Open `main.ts` in your editor. 103 | 1. Find the lines of code that adds a _ribbon icon_. 104 | 105 | ```ts 106 | this.addRibbonIcon('dice', 'Sample Plugin', () => { 107 | new Notice('This is a notice!'); 108 | }); 109 | 110 | 1. Change the text for the notice. Feel free to come up with a text of your own. 111 | 112 | ```ts 113 | new Notice('Hello, you!'); 114 | ``` 115 | 116 | 1. Restart Obsidian to reload your plugin. 117 | 1. Click the die icon in the sidebar. Make sure it says "Sample Plugin" when you hover it. 118 | 119 | ## Next steps 120 | 121 | You've built your own plugin for Obsidian! 🚀 You can experiment by making further changes to the code to see what it does. From here, you can explore some of the guides to see what your plugin can do. 122 | -------------------------------------------------------------------------------- /docs/getting-started/development-workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 15 3 | --- 4 | 5 | # Development workflow 6 | 7 | Whenever you make a change to the plugin source code, the plugin needs to be reloaded. You can reload the plugin by quitting Obsidian and starting it again, but that gets tiring quickly. 8 | 9 | ## Reload plugin inside Obsidian 10 | 11 | You can reload the plugin by re-enabling it in the list of installed plugins: 12 | 13 | 1. Open **Preferences**. 14 | 2. Click **Community plugins**. 15 | 3. Find your plugin under **Installed plugins**. 16 | 4. Toggle the switch off to disable the plugin. 17 | 5. Toggle the switch on to enable the plugin. 18 | 19 | You're now running the updated version of your plugin. 20 | 21 | ## Reload plugin on file changes 22 | 23 | The [Hot-Reload](https://github.com/pjeby/hot-reload) plugin reloads your plugin whenever the source code changes. 24 | 25 | For more information, check out the [forum announcement](https://forum.obsidian.md/t/plugin-release-for-developers-hot-reload-the-plugin-s-youre-developing/12185). 26 | -------------------------------------------------------------------------------- /docs/guides/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Guides", 3 | "position": 30 4 | } 5 | -------------------------------------------------------------------------------- /docs/guides/commands.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 40 3 | --- 4 | 5 | # Commands 6 | 7 | Commands are actions that the user can perform from the [Command Palette](https://help.obsidian.md/Plugins/Command+palette) or by using a hot key. 8 | 9 | ![Command](../../static/img/command.png) 10 | 11 | To register a new command for your plugin, call the [`addCommand()`](../api/classes/Plugin_2.md#addcommand) method inside the `onload()` method: 12 | 13 | ```ts title="main.ts" {5-11} 14 | import { Plugin } from "obsidian"; 15 | 16 | export default class ExamplePlugin extends Plugin { 17 | async onload() { 18 | this.addCommand({ 19 | id: "print-greeting-to-console", 20 | name: "Print greeting to console", 21 | callback: () => { 22 | console.log("Hey, you!"); 23 | }, 24 | }); 25 | } 26 | } 27 | ``` 28 | 29 | ## Conditional commands 30 | 31 | If your command is only able to run under certain conditions, then consider using [`checkCallback`](../api/interfaces/Command.md#checkcallback) instead. 32 | 33 | The `checkCallback` runs twice. First, to perform a preliminary check to determine whether the command can run. Second, to perform the action. 34 | 35 | Since time may pass between the two runs, you need to perform the check during both calls. 36 | 37 | To determine whether the callback should perform a preliminary check or an action, a `checking` argument is passed to the callback. 38 | 39 | - If `checking` is set to `true`, perform a preliminary check. 40 | - If `checking` is set to `false`, perform an action. 41 | 42 | The command in the following example depends on a required value. In both runs, the callback checks that the value is present but only performs the action if `checking` is `false`. 43 | 44 | ```ts {4} 45 | this.addCommand({ 46 | id: 'example-command', 47 | name: 'Example command', 48 | checkCallback: (checking: boolean) => { 49 | const value = getRequiredValue(); 50 | 51 | if (value) { 52 | if (!checking) { 53 | doCommand(value); 54 | } 55 | 56 | return true 57 | } 58 | 59 | return false; 60 | }, 61 | }); 62 | ``` 63 | 64 | ## Editor commands 65 | 66 | If your command needs access to the editor, you can also use the [`editorCallback`](../api/interfaces/Command.md#editorcallback), which provides the active editor and its view as arguments. 67 | 68 | ```ts {4} 69 | this.addCommand({ 70 | id: 'example-command', 71 | name: 'Example command', 72 | editorCallback: (editor: Editor, view: MarkdownView) => { 73 | const sel = editor.getSelection() 74 | 75 | console.log(`You have selected: ${sel}`); 76 | }, 77 | } 78 | ``` 79 | 80 | :::note 81 | Editor commands only appear in the Command Palette when there's an active editor available. 82 | ::: 83 | 84 | If the editor callback can only run given under certain conditions, consider using the [`editorCheckCallback`](../api/interfaces/Command.md#editorcheckcallback) instead. For more information, refer to [conditional commands](#conditional-commands). 85 | 86 | ```ts {4} 87 | this.addCommand({ 88 | id: 'example-command', 89 | name: 'Example command', 90 | editorCheckCallback: (checking: boolean, editor: Editor, view: MarkdownView) => { 91 | const value = getRequiredValue(); 92 | 93 | if (value) { 94 | if (!checking) { 95 | doCommand(value); 96 | } 97 | 98 | return true 99 | } 100 | 101 | return false; 102 | }, 103 | }); 104 | ``` 105 | 106 | ## Hot keys 107 | 108 | The user can run commands using a keyboard shortcut, or _hot key_. While they can configure this themselves, you can also provide a default hot key. 109 | 110 | :::warning 111 | Avoid setting default hot keys for plugins that you intend for others to use. Hot keys are highly likely to conflict with those defined by other plugins or by the user themselves. 112 | ::: 113 | 114 | In this example, the user can run the command by pressing and holding Ctrl (or Cmd on Mac) and Shift together, and then pressing the letter `a` on their keyboard. 115 | 116 | ```ts {4} 117 | this.addCommand({ 118 | id: 'example-command', 119 | name: 'Example command', 120 | hotkeys: [{ modifiers: ["Mod", "Shift"], key: "a" }], 121 | callback: () => { 122 | console.log('Hey, you!'); 123 | }, 124 | }); 125 | ``` 126 | 127 | :::note 128 | The Mod key is a special modifier key that becomes Ctrl on Windows and Linux, and Cmd on macOS. 129 | ::: 130 | -------------------------------------------------------------------------------- /docs/guides/context-menus.md: -------------------------------------------------------------------------------- 1 | # Context menus 2 | 3 | If you want to open up a context menu, use [`Menu`](../api/classes/Menu.md): 4 | 5 | ```ts {6,26} 6 | import { Menu, Notice, Plugin } from "obsidian"; 7 | 8 | export default class ExamplePlugin extends Plugin { 9 | async onload() { 10 | this.addRibbonIcon("dice", "Open menu", (event) => { 11 | const menu = new Menu(this.app); 12 | 13 | menu.addItem((item) => 14 | item 15 | .setTitle("Copy") 16 | .setIcon("documents") 17 | .onClick(() => { 18 | new Notice("Copied"); 19 | }) 20 | ); 21 | 22 | menu.addItem((item) => 23 | item 24 | .setTitle("Paste") 25 | .setIcon("paste") 26 | .onClick(() => { 27 | new Notice("Pasted"); 28 | }) 29 | ); 30 | 31 | menu.showAtMouseEvent(event); 32 | }); 33 | } 34 | } 35 | ``` 36 | 37 | [`showAtMouseEvent()`](../api/classes/Menu.md#showatmouseevent) opens the menu where you clicked with the mouse. 38 | 39 | :::tip 40 | If you need more control of where the menu appears, you can use `menu.showAtPosition({ x: 20, y: 20 })` to open the menu at a position relative to the top-left corner of the Obsidian window. 41 | ::: 42 | 43 | For more information on what icons you can use, refer to [Icons](icons.md). 44 | 45 | You can also add an item to the file menu, or the editor menu, by subscribing to the `file-menu` and `editor-menu` workspace events: 46 | 47 | ![Context menu positions](../../static/img/context-menu-positions.png) 48 | 49 | ```ts 50 | import { Notice, Plugin } from "obsidian"; 51 | 52 | export default class ExamplePlugin extends Plugin { 53 | async onload() { 54 | this.registerEvent( 55 | this.app.workspace.on("file-menu", (menu, file) => { 56 | menu.addItem((item) => { 57 | item 58 | .setTitle("Print file path 👈") 59 | .setIcon("document") 60 | .onClick(async () => { 61 | new Notice(file.path); 62 | }); 63 | }); 64 | }) 65 | ); 66 | 67 | this.registerEvent( 68 | this.app.workspace.on("editor-menu", (menu, editor, view) => { 69 | menu.addItem((item) => { 70 | item 71 | .setTitle("Print file path 👈") 72 | .setIcon("document") 73 | .onClick(async () => { 74 | new Notice(view.file.path); 75 | }); 76 | }); 77 | }) 78 | ); 79 | } 80 | } 81 | ``` 82 | 83 | For more information on handling events, refer to [Events](events.md). 84 | -------------------------------------------------------------------------------- /docs/guides/custom-views.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 70 3 | --- 4 | 5 | # Custom views 6 | 7 | Views determine how Obsidian displays content. The file explorer, graph view, and the Markdown view are all examples of views, but you can also create your own custom views that display content in a way that makes sense for your plugin. 8 | 9 | To create a custom view, create a class that extends the [`ItemView`](../api/classes/ItemView.md) interface: 10 | 11 | ```ts title="view.ts" 12 | import { ItemView, WorkspaceLeaf } from "obsidian"; 13 | 14 | export const VIEW_TYPE_EXAMPLE = "example-view"; 15 | 16 | export class ExampleView extends ItemView { 17 | constructor(leaf: WorkspaceLeaf) { 18 | super(leaf); 19 | } 20 | 21 | getViewType() { 22 | return VIEW_TYPE_EXAMPLE; 23 | } 24 | 25 | getDisplayText() { 26 | return "Example view"; 27 | } 28 | 29 | async onOpen() { 30 | const container = this.containerEl.children[1]; 31 | container.empty(); 32 | container.createEl("h4", { text: "Example view" }); 33 | } 34 | 35 | async onClose() { 36 | // Nothing to clean up. 37 | } 38 | } 39 | ``` 40 | 41 | :::note 42 | For more information on how to use the `createEl()` method, refer to [HTML elements](html-elements.md). 43 | ::: 44 | 45 | Each view is uniquely identified by a text string and several operations require that you specify the view you'd like to use. Extracting it to a constant, `VIEW_TYPE_EXAMPLE`, is a good idea—as you will see later in this guide. 46 | 47 | - `getViewType()` returns a unique identifier for the view. 48 | - `getDisplayText()` returns a human-friendly name for the view. 49 | - `onOpen()` is called when the view is opened within a new leaf and is responsible for building the content of your view. 50 | - `onClose()` is called when the view should close and is responsible for cleaning up any resources used by the view. 51 | 52 | Custom views need to be registered when the plugin is enabled, and cleaned up when the plugin is disabled: 53 | 54 | ```ts title="main.ts" {6-9,17} 55 | import { Plugin } from "obsidian"; 56 | import { ExampleView, VIEW_TYPE_EXAMPLE } from "./view"; 57 | 58 | export default class ExamplePlugin extends Plugin { 59 | async onload() { 60 | this.registerView( 61 | VIEW_TYPE_EXAMPLE, 62 | (leaf) => new ExampleView(leaf) 63 | ); 64 | 65 | this.addRibbonIcon("dice", "Activate view", () => { 66 | this.activateView(); 67 | }); 68 | } 69 | 70 | async onunload() { 71 | this.app.workspace.detachLeavesOfType(VIEW_TYPE_EXAMPLE); 72 | } 73 | 74 | async activateView() { 75 | this.app.workspace.detachLeavesOfType(VIEW_TYPE_EXAMPLE); 76 | 77 | await this.app.workspace.getRightLeaf(false).setViewState({ 78 | type: VIEW_TYPE_EXAMPLE, 79 | active: true, 80 | }); 81 | 82 | this.app.workspace.revealLeaf( 83 | this.app.workspace.getLeavesOfType(VIEW_TYPE_EXAMPLE)[0] 84 | ); 85 | } 86 | } 87 | ``` 88 | 89 | The second argument to [`registerView()`](../api/classes/Plugin_2.md#registerview) is a factory function that returns an instance of the view you want to register. 90 | 91 | :::warning 92 | Never manage references to views in your plugin. Obsidian may call the view factory function multiple times. Avoid side effects in your view, and use `getLeavesOfType()` whenever you need to access your view instances. 93 | 94 | ```ts 95 | this.app.workspace.getLeavesOfType(VIEW_TYPE_EXAMPLE).forEach((leaf) => { 96 | if (leaf.view instanceof ExampleView) { 97 | // Access your view instance. 98 | } 99 | }); 100 | ``` 101 | 102 | ::: 103 | 104 | In the `onunload()` method, to make sure that you clean up the view whenever the plugin is disabled: 105 | 106 | - Allow the view clean up after itself by calling `close()`. 107 | - Detach all leaves that are using the view. 108 | 109 | After you've registered a custom view for the plugin, you should to give the user a way to activate it. The `activateView()` is a convenient method that does three things: 110 | 111 | - Detaches all leaves with the custom view. 112 | - Adds the custom view on the right leaf. 113 | - Reveals the leaf that contains the custom view. 114 | 115 | :::tip 116 | The `activateView()` restricts your plugin to at most one leaf at a time. Try commenting out the call to `detachLeavesOfType()` to allow the user to create more than one leaf. One for every call to `activateView()`. 117 | ::: 118 | 119 | How you want the user to activate the custom view is up to you. The example uses a [ribbon action](./ribbon-actions.md), but you can also use a [command](./commands.md). 120 | -------------------------------------------------------------------------------- /docs/guides/editor.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 80 3 | --- 4 | 5 | # Editor 6 | 7 | The [`Editor`](../api/classes/Editor.md) class exposes operations for reading and manipulating an active Markdown document in edit mode. 8 | 9 | If you want to access the editor in a command, use the [editorCallback](./commands.md#editor-commands). 10 | 11 | If you want to use the editor elsewhere, you can access it from the active view: 12 | 13 | ```ts {5} 14 | const view = this.app.workspace.getActiveViewOfType(MarkdownView); 15 | 16 | // Make sure the user is editing a Markdown file. 17 | if (view) { 18 | const cursor = view.editor.getCursor(); 19 | 20 | // ... 21 | } 22 | ``` 23 | 24 | :::note 25 | Obsidian uses [CodeMirror](https://codemirror.net/) (CM) as the underlying text editor, and exposes the CodeMirror editor as part of the API. `Editor` serves as an abstraction to bridge features in CM5 (desktop) and CM6 (mobile). By using `Editor` instead of directly accessing the CodeMirror instance, you ensure that your plugin works on both platforms. 26 | ::: 27 | 28 | ## Insert text at cursor position 29 | 30 | The [`replaceRange()`](../api/classes/Editor.md#replacerange) method replaces the text between two cursor positions. If you only give it one position, it inserts the new text between that position and the next. 31 | 32 | The following command inserts today's date at the cursor position: 33 | 34 | ```ts title="main.ts" {9} 35 | import { Editor, moment, Plugin } from "obsidian"; 36 | 37 | export default class ExamplePlugin extends Plugin { 38 | async onload() { 39 | this.addCommand({ 40 | id: "insert-todays-date", 41 | name: "Insert today's date", 42 | editorCallback: (editor: Editor) => { 43 | editor.replaceRange(moment().format("YYYY-MM-DD"), editor.getCursor()); 44 | }, 45 | }); 46 | } 47 | } 48 | ``` 49 | 50 | ![Insert today's date](../../static/img/editor-todays-date.gif) 51 | 52 | ## Replace current selection 53 | 54 | If you want to modify the selected text, use [`replaceSelection()`](../api/classes/Editor.md#replaceselection) to replace the current selection with a new text. 55 | 56 | The following command reads the current selection and converts it to uppercase: 57 | 58 | ```ts title="main.ts" {9-10} 59 | import { Editor, Plugin } from "obsidian"; 60 | 61 | export default class ExamplePlugin extends Plugin { 62 | async onload() { 63 | this.addCommand({ 64 | id: "convert-to-uppercase", 65 | name: "Convert to uppercase", 66 | editorCallback: (editor: Editor) => { 67 | const selection = editor.getSelection(); 68 | editor.replaceSelection(selection.toUpperCase()); 69 | }, 70 | }); 71 | } 72 | } 73 | ``` 74 | 75 | ![Convert to uppercase](../../static/img/editor-uppercase.gif) 76 | -------------------------------------------------------------------------------- /docs/guides/events.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 58 3 | --- 4 | 5 | # Events 6 | 7 | Many of the interfaces in the Obsidian lets you subscribe to events throughout the application, for example when the user makes changes to a file. 8 | 9 | Any registered event handlers need to be detached whenever the plugin unloads. The safest way to make sure this happens is to use the [`registerEvent()`](../api/classes/Component.md#registerevent) method. 10 | 11 | ```ts title="main.ts" {5-7} 12 | import { Plugin } from "obsidian"; 13 | 14 | export default class ExamplePlugin extends Plugin { 15 | async onload() { 16 | this.registerEvent(this.app.vault.on('create', () => { 17 | console.log('a new file has entered the arena') 18 | })); 19 | } 20 | } 21 | ``` 22 | 23 | ## Timing events 24 | 25 | If you want to repeatedly call a function with a fixed delay, use the [`window.setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) function with the [`registerInterval()`](../api/classes/Component.md#registerinterval) method. 26 | 27 | The following example displays the current time in the status bar, updated every second: 28 | 29 | ```ts {11-13} 30 | import { moment, Plugin } from "obsidian"; 31 | 32 | export default class ExamplePlugin extends Plugin { 33 | statusBar: HTMLElement; 34 | 35 | async onload() { 36 | this.statusBar = this.addStatusBarItem(); 37 | 38 | this.updateStatusBar(); 39 | 40 | this.registerInterval( 41 | window.setInterval(() => this.updateStatusBar(), 1000) 42 | ); 43 | } 44 | 45 | updateStatusBar() { 46 | this.statusBar.setText(moment().format("H:mm:ss")); 47 | } 48 | } 49 | ``` 50 | 51 | :::tip 52 | [Moment](https://momentjs.com/) is a popular JavaScript library for working with dates and time. Obsidian uses Moment internally, so you don't need to install it yourself. You can import it from the Obsidian API instead: 53 | 54 | ```ts 55 | import { moment } from "obsidian"; 56 | ``` 57 | 58 | ::: 59 | -------------------------------------------------------------------------------- /docs/guides/html-elements.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 75 3 | --- 4 | 5 | # HTML elements 6 | 7 | Several components in the Obsidian API, such as the [settings tab](settings.md), expose _container elements_: 8 | 9 | ```ts {12} 10 | import { App, PluginSettingTab } from "obsidian"; 11 | 12 | class ExampleSettingTab extends PluginSettingTab { 13 | plugin: ExamplePlugin; 14 | 15 | constructor(app: App, plugin: ExamplePlugin) { 16 | super(app, plugin); 17 | this.plugin = plugin; 18 | } 19 | 20 | display(): void { 21 | let { containerEl } = this; 22 | 23 | // ... 24 | } 25 | } 26 | ``` 27 | 28 | Container elements are `HTMLElement` objects that make it possible to create custom interfaces within Obsidian. 29 | 30 | ## Create HTML elements using `createEl()` 31 | 32 | Every `HTMLElement`, including the container element, exposes a `createEl()` method that creates an `HTMLElement` under the original element. 33 | 34 | For example, here's how you can add an `

` heading element inside the container element: 35 | 36 | ```ts 37 | containerEl.createEl("h1", { text: "Heading 1" }); 38 | ``` 39 | 40 | `createEl()` returns a reference to the new element: 41 | 42 | ```ts 43 | const book = containerEl.createEl("div"); 44 | book.createEl("div", { text: "How to Take Smart Notes" }); 45 | book.createEl("small", { text: "Sönke Ahrens" }); 46 | ``` 47 | 48 | ## Style your elements 49 | 50 | You can add custom CSS styles to your plugin by adding a `styles.css` file in the plugin root directory. To add some styles for the previous book example: 51 | 52 | ```css title="styles.css" 53 | .book { 54 | border: 1px solid var(--background-modifier-border); 55 | padding: 10px; 56 | } 57 | 58 | .book__title { 59 | font-weight: 600; 60 | } 61 | 62 | .book__author { 63 | color: var(--text-muted); 64 | } 65 | ``` 66 | 67 | :::tip 68 | `--background-modifier-border` and `--text-muted` are [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) that are defined and used by Obsidian itself. If you use these variables for your styles, your plugin will look great even if the user has a different theme! 🌈 69 | ::: 70 | 71 | To make the HTML elements use the styles, set the `cls` property for the HTML element: 72 | 73 | ```ts 74 | const book = containerEl.createEl("div", { cls: "book" }); 75 | book.createEl("div", { text: "How to Take Smart Notes", cls: "book__title" }); 76 | book.createEl("small", { text: "Sönke Ahrens", cls: "book__author" }); 77 | ``` 78 | 79 | Now it looks much better! 🎉 80 | 81 | ![Styled book item](../../static/img/styles.png) 82 | 83 | ### Conditional styles 84 | 85 | Use the `toggleClass` method if you want to change the style of an element based on the user's settings or other values: 86 | 87 | ```ts 88 | element.toggleClass("danger", status === "error"); 89 | ``` 90 | -------------------------------------------------------------------------------- /docs/guides/icons.md: -------------------------------------------------------------------------------- 1 | # Icons 2 | 3 | Several of the UI components in the Obsidian API lets you configure an accompanying icon. You can choose from one of the built-in icons, or you can add your own. 4 | 5 | ## Browse available icons 6 | 7 | If you'd like to see all available icons and their corresponding names, you can install the 8 | [Icon Swapper](https://github.com/mgmeyers/obsidian-icon-swapper) plugin by mgmeyers. While its main purpose is to replace the built-in icons with custom ones, it also serves as a list of what icons are available in Obsidian. 9 | 10 | ## Draw icons 11 | 12 | If you'd like to use icons in your custom interfaces, use the [`setIcon`](../api/functions/setIcon.md) utility function to add an icon to an [HTML element](html-elements.md). The following example adds icon to the status bar: 13 | 14 | ```ts title="main.ts" 15 | import { Plugin, setIcon } from "obsidian"; 16 | 17 | export default class ExamplePlugin extends Plugin { 18 | async onload() { 19 | const item = this.addStatusBarItem(); 20 | setIcon(item, "info", 14); 21 | } 22 | } 23 | ``` 24 | 25 | ## Add your own icon 26 | 27 | To add a custom icon for your plugin, use the [`addIcon`](../api/functions/addIcon.md) utility: 28 | 29 | ```ts title="main.ts" 30 | import { addIcon, Plugin } from "obsidian"; 31 | 32 | export default class ExamplePlugin extends Plugin { 33 | async onload() { 34 | addIcon("circle", ``); 35 | 36 | this.addRibbonIcon("circle", "Click me", () => { 37 | console.log("Hello, you!"); 38 | }); 39 | } 40 | } 41 | ``` 42 | 43 | `addIcon` takes two arguments: 44 | 45 | 1. A name to uniquely identify your icon. 46 | 1. The SVG content for the icon, without the surrounding `` tag. 47 | 48 | Note that your icon needs to fit within a `0 0 100 100` view box to be drawn properly. 49 | 50 | After the call to `addIcon`, you can use the icon just like any of the built-in icons. 51 | -------------------------------------------------------------------------------- /docs/guides/markdown-post-processing.md: -------------------------------------------------------------------------------- 1 | # Markdown post processing 2 | 3 | If you want to change how a Markdown document is rendered in Preview mode, you can add your own _Markdown post processor_. As indicated by the name, the post processor runs _after_ the Markdown has been processed into HTML. It lets you add, remove, or replace [HTML elements](html-elements.md) to the rendered document. 4 | 5 | The following example looks for any code block that contains a text between two colons, `:`, and replaces it with an appropriate emoji: 6 | 7 | ```ts title="main.ts" {6,15} 8 | import { Plugin } from "obsidian"; 9 | import { Emoji } from "./emoji"; 10 | 11 | export default class ExamplePlugin extends Plugin { 12 | async onload() { 13 | this.registerMarkdownPostProcessor((element, context) => { 14 | const codeblocks = element.querySelectorAll("code"); 15 | 16 | for (let index = 0; index < codeblocks.length; index++) { 17 | const codeblock = codeblocks.item(index); 18 | const text = codeblock.innerText.trim(); 19 | const isEmoji = text[0] === ":" && text[text.length - 1] === ":"; 20 | 21 | if (isEmoji) { 22 | context.addChild(new Emoji(codeblock, text)); 23 | } 24 | } 25 | }); 26 | } 27 | } 28 | ``` 29 | 30 | The `Emoji` class extends [`MarkdownRenderChild`](../api/classes/MarkdownRenderChild.md), and replaces the code block with a `span` element with the emoji: 31 | 32 | ```ts title="emoji.ts" {3,19-22} 33 | import { MarkdownRenderChild } from "obsidian"; 34 | 35 | export class Emoji extends MarkdownRenderChild { 36 | static ALL_EMOJIS: Record = { 37 | ":+1:": "👍", 38 | ":sunglasses:": "😎", 39 | ":smile:": "😄", 40 | }; 41 | 42 | text: string; 43 | 44 | constructor(containerEl: HTMLElement, text: string) { 45 | super(containerEl); 46 | 47 | this.text = text; 48 | } 49 | 50 | onload() { 51 | const emojiEl = this.containerEl.createSpan({ 52 | text: Emoji.ALL_EMOJIS[this.text] ?? this.text, 53 | }); 54 | this.containerEl.replaceWith(emojiEl); 55 | } 56 | } 57 | ``` 58 | 59 | ## Post-process Markdown code blocks 60 | 61 | Did you know that you can create [Mermaid](https://mermaid-js.github.io/) diagrams in Obsidian by creating a `mermaid` code block with a text definition like this one?: 62 | 63 | ````md 64 | ```mermaid 65 | flowchart LR 66 | Start --> Stop 67 | ``` 68 | ```` 69 | 70 | If you change to Preview mode, the text in the code block becomes the following diagram: 71 | 72 | ```mermaid 73 | flowchart LR 74 | Start --> Stop 75 | ``` 76 | 77 | If you want to add your own custom code blocks like the Mermaid one, you can use [`registerMarkdownCodeBlockProcessor`](../api/classes/Plugin_2.md#registermarkdowncodeblockprocessor). The following example renders a code block with CSV data, as a table: 78 | 79 | ```ts title="main.ts" 80 | import { Plugin } from "obsidian"; 81 | 82 | export default class ExamplePlugin extends Plugin { 83 | async onload() { 84 | this.registerMarkdownCodeBlockProcessor("csv", (source, el, ctx) => { 85 | const rows = source.split("\n").filter((row) => row.length > 0); 86 | 87 | const table = el.createEl("table"); 88 | const body = table.createEl("tbody"); 89 | 90 | for (let i = 0; i < rows.length; i++) { 91 | const cols = rows[i].split(","); 92 | 93 | const row = body.createEl("tr"); 94 | 95 | for (let j = 0; j < cols.length; j++) { 96 | row.createEl("td", { text: cols[j] }); 97 | } 98 | } 99 | }); 100 | } 101 | } 102 | ``` 103 | -------------------------------------------------------------------------------- /docs/guides/modals.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 56 3 | --- 4 | 5 | # Modals 6 | 7 | Modals display information and accept input from the user. To create a modal, create a class that extends [`Modal`](../api/classes/Modal.md): 8 | 9 | ```ts title="modal.ts" 10 | import { App, Modal } from "obsidian"; 11 | 12 | export class ExampleModal extends Modal { 13 | constructor(app: App) { 14 | super(app); 15 | } 16 | 17 | onOpen() { 18 | let { contentEl } = this; 19 | contentEl.setText("Look at me, I'm a modal! 👀"); 20 | } 21 | 22 | onClose() { 23 | let { contentEl } = this; 24 | contentEl.empty(); 25 | } 26 | } 27 | ``` 28 | 29 | - [`onOpen()`](../api/classes/Modal.md#onopen) is called when the modal is opened and is responsible for building the content of your modal. For more information, refer to [HTML elements](html-elements.md). 30 | - [`onClose()`](../api/classes/Modal.md#onclose) is called when the modal is closed and is responsible for cleaning up any resources used by the modal. 31 | 32 | To open a modal, create a new instance of `ExampleModal` and call [`open()`](../api/classes/Modal.md#open) on it: 33 | 34 | ```ts title="main.ts" 35 | import { Plugin } from "obsidian"; 36 | import { ExampleModal } from "./modal"; 37 | 38 | export default class ExamplePlugin extends Plugin { 39 | async onload() { 40 | this.addCommand({ 41 | id: "display-modal", 42 | name: "Display modal", 43 | callback: () => { 44 | new ExampleModal(this.app).open(); 45 | }, 46 | }); 47 | } 48 | } 49 | ``` 50 | 51 | ## Accept user input 52 | 53 | The modal in the previous example only displayed some text. Let's look at a little more complex example that handles input from the user. 54 | 55 | ![Modal with user input](../../static/img/modal-input.png) 56 | 57 | ```ts title="modal.ts" {21,30-31} 58 | import { App, Modal, Setting } from "obsidian"; 59 | 60 | export class ExampleModal extends Modal { 61 | result: string; 62 | onSubmit: (result: string) => void; 63 | 64 | constructor(app: App, onSubmit: (result: string) => void) { 65 | super(app); 66 | this.onSubmit = onSubmit; 67 | } 68 | 69 | onOpen() { 70 | const { contentEl } = this; 71 | 72 | contentEl.createEl("h1", { text: "What's your name?" }); 73 | 74 | new Setting(contentEl) 75 | .setName("Name") 76 | .addText((text) => 77 | text.onChange((value) => { 78 | this.result = value 79 | })); 80 | 81 | new Setting(contentEl) 82 | .addButton((btn) => 83 | btn 84 | .setButtonText("Submit") 85 | .setCta() 86 | .onClick(() => { 87 | this.close(); 88 | this.onSubmit(this.result); 89 | })); 90 | } 91 | 92 | onClose() { 93 | let { contentEl } = this; 94 | contentEl.empty(); 95 | } 96 | } 97 | ``` 98 | 99 | The result is stored in `this.result` and returned in the `onSubmit` callback when the user clicks **Submit**: 100 | 101 | ```ts 102 | new ExampleModal(this.app, (result) => { 103 | new Notice(`Hello, ${result}!`); 104 | }).open(); 105 | ``` 106 | 107 | ## Select from list of suggestions 108 | 109 | [`SuggestModal`](../api/classes/SuggestModal.md) is a special modal that lets you display a list of suggestions to the user. 110 | 111 | ![Modal with suggestions](../../static/img/suggest-modal.gif) 112 | 113 | ```ts title="modal.ts" 114 | import { App, Notice, SuggestModal } from "obsidian"; 115 | 116 | interface Book { 117 | title: string; 118 | author: string; 119 | } 120 | 121 | const ALL_BOOKS = [ 122 | { 123 | title: "How to Take Smart Notes", 124 | author: "Sönke Ahrens", 125 | }, 126 | { 127 | title: "Thinking, Fast and Slow", 128 | author: "Daniel Kahneman", 129 | }, 130 | { 131 | title: "Deep Work", 132 | author: "Cal Newport", 133 | }, 134 | ]; 135 | 136 | export class ExampleModal extends SuggestModal { 137 | // Returns all available suggestions. 138 | getSuggestions(query: string): Book[] { 139 | return ALL_BOOKS.filter((book) => 140 | book.title.toLowerCase().includes(query.toLowerCase()) 141 | ); 142 | } 143 | 144 | // Renders each suggestion item. 145 | renderSuggestion(book: Book, el: HTMLElement) { 146 | el.createEl("div", { text: book.title }); 147 | el.createEl("small", { text: book.author }); 148 | } 149 | 150 | // Perform action on the selected suggestion. 151 | onChooseSuggestion(book: Book, evt: MouseEvent | KeyboardEvent) { 152 | new Notice(`Selected ${book.title}`); 153 | } 154 | } 155 | ``` 156 | 157 | In addition to `SuggestModal`, the Obsidian API provides an even more specialized type of modal for suggestions: the [`FuzzySuggestModal`](../api/classes/FuzzySuggestModal.md). While it doesn't give you the same control of how each item is rendered, you get [fuzzy string search](https://en.wikipedia.org/wiki/Approximate_string_matching) out-of-the-box. 158 | 159 | ![Fuzzy string search](../../static/img/fuzzy-suggestion-modal.png) 160 | 161 | ```ts 162 | export class ExampleModal extends FuzzySuggestModal { 163 | getItems(): Book[] { 164 | return ALL_BOOKS; 165 | } 166 | 167 | getItemText(book: Book): string { 168 | return book.title; 169 | } 170 | 171 | onChooseItem(book: Book, evt: MouseEvent | KeyboardEvent) { 172 | new Notice(`Selected ${book.title}`); 173 | } 174 | } 175 | ``` 176 | -------------------------------------------------------------------------------- /docs/guides/ribbon-actions.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 30 3 | --- 4 | 5 | # Ribbon actions 6 | 7 | The sidebar on the left side of the Obsidian interface is mainly known as the _ribbon_. In addition to system operations, such as opening the preferences or another vault, the ribbon can also host actions defined by plugins. 8 | 9 | To add a action to the ribbon, use the [`addRibbonIcon()`](../api/classes/Plugin_2.md#addribbonicon) method: 10 | 11 | ```ts title="main.ts" {5-7} 12 | import { Plugin } from "obsidian"; 13 | 14 | export default class ExamplePlugin extends Plugin { 15 | async onload() { 16 | this.addRibbonIcon("dice", "Print to console", () => { 17 | console.log("Hello, you!"); 18 | }); 19 | } 20 | } 21 | ``` 22 | 23 | The first argument specifies which icon to use. For more information on the available icons, and how to add your own, refer to [Icons](icons.md). 24 | -------------------------------------------------------------------------------- /docs/guides/settings.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 55 3 | --- 4 | 5 | # Settings 6 | 7 | If you want users to be able to configure parts of your plugin themselves, you can expose them as _settings_. 8 | 9 | In this guide, you'll learn how to create a settings page like this 👇 10 | 11 | ![Settings](../../static/img/settings.png) 12 | 13 | The main reason to add settings to a plugin is to store configuration that persists even after the user quits Obsidian. The following example demonstrates how to save and load settings from disk: 14 | 15 | ```ts title="main.ts" 16 | import { Plugin } from "obsidian"; 17 | import { ExampleSettingTab } from "./settings"; 18 | 19 | interface ExamplePluginSettings { 20 | dateFormat: string; 21 | } 22 | 23 | const DEFAULT_SETTINGS: Partial = { 24 | dateFormat: "YYYY-MM-DD", 25 | }; 26 | 27 | export default class ExamplePlugin extends Plugin { 28 | settings: ExamplePluginSettings; 29 | 30 | async onload() { 31 | await this.loadSettings(); 32 | 33 | this.addSettingTab(new ExampleSettingTab(this.app, this)); 34 | } 35 | 36 | async loadSettings() { 37 | this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); 38 | } 39 | 40 | async saveSettings() { 41 | await this.saveData(this.settings); 42 | } 43 | } 44 | ``` 45 | 46 | There's a lot going on here 🤯, so let's look closer at each part. 47 | 48 | ## Create a settings definition 49 | 50 | First, you need to create a definition, `ExamplePluginSettings`, for what settings you want the user to be able to configure. While the plugin is enabled, you can access the settings from the `settings` member variable. 51 | 52 | ```ts 53 | interface ExamplePluginSettings { 54 | dateFormat: string; 55 | } 56 | 57 | export default class ExamplePlugin extends Plugin { 58 | settings: ExamplePluginSettings; 59 | 60 | // ... 61 | } 62 | ``` 63 | 64 | ## Save and load the settings object 65 | 66 | [`loadData()`](../api/classes/Plugin_2.md#loaddata) and [`saveData()`](../api/classes/Plugin_2.md#savedata) provide an easy way to store and retrieve data from disk. The example also introduces two helper methods that makes it easier to use `loadData()` and `saveData()` from other parts of the plugin. 67 | 68 | ```ts 69 | export default class ExamplePlugin extends Plugin { 70 | 71 | // ... 72 | 73 | async loadSettings() { 74 | this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); 75 | } 76 | 77 | async saveSettings() { 78 | await this.saveData(this.settings); 79 | } 80 | } 81 | ``` 82 | 83 | Finally, make sure to load the settings when the plugin loads: 84 | 85 | ```ts 86 | async onload() { 87 | await this.loadSettings(); 88 | 89 | // ... 90 | } 91 | ``` 92 | 93 | ## Provide default values 94 | 95 | When the user enables the plugin for the first time, none of the settings have been configured yet. The preceding example provides default values for any missing settings. 96 | 97 | To understand how this work, let's look at the following code: 98 | 99 | ```ts 100 | Object.assign(DEFAULT_SETTINGS, await this.loadData()) 101 | ``` 102 | 103 | `Object.assign()` is a JavaScript function that copies all properties from one object to another. Any properties that are returned by `loadData()` override the properties in `DEFAULT_SETTINGS`. 104 | 105 | ```ts 106 | const DEFAULT_SETTINGS: Partial = { 107 | dateFormat: "YYYY-MM-DD", 108 | }; 109 | ``` 110 | 111 | :::tip 112 | `Partial` is a TypeScript utility that returns a type with all properties of `Type` set to optional. It enables type checking while letting you only define the properties you want to provide defaults for. 113 | ::: 114 | 115 | ## Register a settings tab 116 | 117 | The plugin can now save and load plugin configuration, but the user doesn't yet have any way of changing any of the settings. By adding a settings tab you can provide an easy-to-use interface for the user to update their plugin settings: 118 | 119 | ```ts 120 | this.addSettingTab(new ExampleSettingTab(this.app, this)); 121 | ``` 122 | 123 | Here, the `ExampleSettingTab` is a class that extends [`PluginSettingTab`](../api/classes/PluginSettingTab.md): 124 | 125 | ```ts title="settings.ts" 126 | import ExamplePlugin from "main"; 127 | import { App, PluginSettingTab, Setting } from "obsidian"; 128 | 129 | export class ExampleSettingTab extends PluginSettingTab { 130 | plugin: ExamplePlugin; 131 | 132 | constructor(app: App, plugin: ExamplePlugin) { 133 | super(app, plugin); 134 | this.plugin = plugin; 135 | } 136 | 137 | display(): void { 138 | let { containerEl } = this; 139 | 140 | containerEl.empty(); 141 | 142 | new Setting(containerEl) 143 | .setName("Date format") 144 | .setDesc("Default date format") 145 | .addText((text) => 146 | text 147 | .setPlaceholder("MMMM dd, yyyy") 148 | .setValue(this.plugin.settings.dateFormat) 149 | .onChange(async (value) => { 150 | this.plugin.settings.dateFormat = value; 151 | await this.plugin.saveSettings(); 152 | }) 153 | ); 154 | } 155 | } 156 | ``` 157 | 158 | `display()` is where you build the content for the settings tab. For more information, refer to [HTML elements](html-elements.md). 159 | 160 | `new Setting(containerEl)` appends a setting to the container element. This example uses a text field using `addText()`, but there are several other setting types available. 161 | 162 | Update the settings object whenever the value of the text field changes, and then save it to disk: 163 | 164 | ```ts {2,3} 165 | .onChange(async (value) => { 166 | this.plugin.settings.dateFormat = value; 167 | await this.plugin.saveSettings(); 168 | }) 169 | ``` 170 | 171 | Nice work! 💪 Your users will thank you for giving them a way to customize how they interact with your plugin. Before heading to the next guide, experiment with what you've learned by adding another setting. 172 | -------------------------------------------------------------------------------- /docs/guides/status-bar.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 45 3 | --- 4 | 5 | # Status bar 6 | 7 | To create a new block in the status bar, call the [`addStatusBarItem()`](../api/classes/Plugin_2.md#addstatusbaritem) in the `onload()` method. The `addStatusBarItem()` method returns an [HTML element](html-elements.md) that you can add your own elements to. 8 | 9 | :::caution Obsidian mobile 10 | Custom status bar items [is **not** supported](https://discord.com/channels/686053708261228577/707816848615407697/832321402106544179) on Obsidian mobile apps. 11 | ::: 12 | 13 | ```ts title="main.ts" 14 | import { Plugin } from "obsidian"; 15 | 16 | export default class ExamplePlugin extends Plugin { 17 | async onload() { 18 | const item = this.addStatusBarItem(); 19 | item.createEl("span", { text: "Hello from the status bar 👋" }); 20 | } 21 | } 22 | ``` 23 | 24 | :::note 25 | For more information on how to use the `createEl()` method, refer to [HTML elements](html-elements.md). 26 | ::: 27 | 28 | You can add multiple status bar items by calling `addStatusBarItem()` multiple times. Since Obsidian adds a gap between them, you need to create multiple HTML element on the same status bar item if you need more control of spacing. 29 | 30 | ```ts title="main.ts" 31 | import { Plugin } from "obsidian"; 32 | 33 | export default class ExamplePlugin extends Plugin { 34 | async onload() { 35 | const fruits = this.addStatusBarItem(); 36 | fruits.createEl("span", { text: "🍎" }); 37 | fruits.createEl("span", { text: "🍌" }); 38 | 39 | const veggies = this.addStatusBarItem(); 40 | veggies.createEl("span", { text: "🥦" }); 41 | veggies.createEl("span", { text: "🥬" }); 42 | } 43 | } 44 | ``` 45 | 46 | The example above results in the following status bar: 47 | 48 | ![Status bar](../../static/img/status-bar.png) 49 | -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_label: Introduction 4 | sidebar_position: 1 5 | --- 6 | 7 | # Obsidian Plugin Developer Docs 8 | 9 | This is the **unofficial** documentation for Obsidian plugin development. 10 | 11 | It's being maintained by [@marcusolsson](https://github.com/marcusolsson), with the help of the Obsidian community. If this site has been useful to you, you can buy the maintainer a coffee to support its continued development: 12 | 13 | 14 | 15 | 16 | 17 | If this site doesn't help you, maybe one of these resources might: 18 | 19 | **Official resources by the Obsidian team:** 20 | 21 | - [Obsidian Sample Plugin](https://github.com/obsidianmd/obsidian-sample-plugin) 22 | - [Obsidian API](https://github.com/obsidianmd/obsidian-api) 23 | 24 | **Unofficial resources by community members:** 25 | 26 | - [for Plugin Developers](https://publish.obsidian.md/hub/04+-+Guides%2C+Workflows%2C+%26+Courses/for+Plugin+Developers "for Plugin Developers - Obsidian Hub - Obsidian Publish") in Obsidian Hub 27 | - [Plugins mini FAQ](https://forum.obsidian.md/t/plugins-mini-faq/7737) 28 | - [How to create a plugin for Obsidian](https://www.youtube.com/watch?v=XaES2G3PVpg) by [@phibr0](https://github.com/phibr0) 29 | - [Create Your Own Obsidian Plugin](https://www.youtube.com/watch?v=9lA-jaMNS0k) by [Antone Heyward](https://www.youtube.com/channel/UC9w43btR2UUsfR6ZUf3AlqQ) 30 | - [Unofficial API FAQ](https://liamca.in/Obsidian/API+FAQ/index) by [Liam Cain](https://liamca.in) 31 | - [Obsidian Tools](https://github.com/obsidian-tools/obsidian-tools) 32 | - [Getting Started with CodeMirror 6](https://github.com/nothingislost/obsidian-cm6-attributes#getting-started-with-codemirror-6) by [NothingIsLost](https://github.com/nothingislost) 33 | -------------------------------------------------------------------------------- /docs/manifest-reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /manifest 3 | sidebar_label: Manifest reference 4 | sidebar_position: 75 5 | --- 6 | 7 | # Manifest 8 | 9 | This page describe the schema for the plugin manifest, `manifest.json`. 10 | 11 | ## Properties 12 | 13 | | Property | Type | Required | Description | 14 | |-----------------|---------|----------|--------------------------------------------------------| 15 | | `author` | string | **Yes** | The plugin author's name. | 16 | | `description` | string | **Yes** | The long description of your plugin. | 17 | | `id` | string | **Yes** | The ID of your plugin. | 18 | | `isDesktopOnly` | boolean | **Yes** | Whether your plugin uses NodeJS or Electron APIs. | 19 | | `minAppVersion` | string | **Yes** | The minimum required Obsidian version for your plugin. | 20 | | `name` | string | **Yes** | The display name of your plugin. | 21 | | `version` | string | **Yes** | The version of your plugin. | 22 | | `authorUrl` | string | No | A URL to your own website. | 23 | 24 | -------------------------------------------------------------------------------- /docs/publishing/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Publishing", 3 | "position": 60 4 | } 5 | -------------------------------------------------------------------------------- /docs/publishing/submission-guidelines.md: -------------------------------------------------------------------------------- 1 | # Submission guidelines 2 | 3 | This page lists common review comments plugin authors get when submitting their plugin. 4 | 5 | ## Use `normalizePath()` to clean up user-defined paths 6 | 7 | Use [`normalizePath()`](../api/functions/normalizePath) whenever you accept user-defined paths to files or folders in the vault, or when you construct your own paths in the plugin code. 8 | 9 | `normalizePath()` takes a path and scrubs it to be safe for the file system and for cross-platform use. This function: 10 | 11 | - Cleans up the use of forward and backward slashes, such as replacing 1 or more of `\` or `/` with a single `/`. 12 | - Removes leading and trailing forward and backward slashes. 13 | - Replaces any non-breaking spaces, `\u00A0`, with a regular space. 14 | - Runs the path through [String.prototype.normalize](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). 15 | 16 | ```ts 17 | import { normalizePath } from "obsidian"; 18 | const pathToPlugin = normalizePath(app.vault.configDir + "//plugins/my-plugin"); 19 | // pathToPlugin contains ".obsidian/plugins/my-plugin" not .obsidian//plugins/my-plugin 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/publishing/submit-your-plugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Submit your plugin 6 | 7 | If you want to share your plugin with the Obsidian community, the best way is to submit it to the [official list of plugins](https://github.com/obsidianmd/obsidian-releases/blob/master/community-plugins.json). Once your plugin has been reviewed, users can install your plugin directly from within Obsidian. It'll also be featured in the [plugin directory](https://obsidian.md/plugins) on the Obsidian website. In this guide, you'll submit your own plugin. 8 | 9 | :::caution 10 | The purpose of this guide is to provide richer instructions for how to submit a plugin. Before you submit your plugin however, make sure that you have reviewed the [official instructions](https://github.com/obsidianmd/obsidian-sample-plugin#adding-your-plugin-to-the-community-plugin-list). 11 | ::: 12 | 13 | ## Prerequisites 14 | 15 | To follow this guide, make sure you have the following files at the root of your repository: 16 | 17 | - A `README.md` that describes the purpose of the plugin, and how to use it. 18 | - A `LICENSE` that determines how others are allowed to use the plugin and its source code. If you need help to pick a license for your plugin, refer to [Choose a License](https://choosealicense.com/). 19 | - A `manifest.json` that describes your plugin. For more information, refer to [Manifest](manifest-reference.md). 20 | 21 | ## Step 1 — Create a release 22 | 23 | In this step, you'll prepare a release for your plugin that's ready to be submitted. 24 | 25 | 1. In `manifest.json`, update `version` to a new version that follows the [Semantic Versioning](https://semver.org/) specification. 26 | 27 | 1. [Create a GitHub release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release). 28 | - The "Tag version" of the release must match the version in your `manifest.json`. 29 | - Don't include a `v` in the tag version. 30 | 1. Enter a name for the release, and describe it in the description field. 31 | 32 | 1. Upload the following plugin assets to the release, as binary attachments: 33 | 34 | - `main.js` 35 | - `manifest.json` 36 | - `styles.css` (optional) 37 | 38 | :::tip 39 | To automate the process of creating a release, refer to [Release your plugin with GitHub Actions](release-your-plugin-with-github-actions.md). 40 | ::: 41 | ## Step 2 — Submit your plugin for review 42 | 43 | In this step, you'll submit your plugin to the Obsidian team for review. 44 | 45 | 1. Fork the [obsidian-releases](https://github.com/obsidianmd/obsidian-releases) repository on GitHub. For more information on how to fork a repository, refer to [Fork a repo](https://docs.github.com/en/get-started/quickstart/fork-a-repo). 46 | 47 | 1. In `community-plugins.json`, create a new entry in the JSON array. The following example shows the entry for the [Recent Files](https://github.com/tgrosinger/recent-files-obsidian) plugin. 48 | 49 | ```json 50 | { 51 | "id": "recent-files-obsidian", 52 | "name": "Recent Files", 53 | "author": "Tony Grosinger", 54 | "description": "Display a list of recently opened files", 55 | "repo": "tgrosinger/recent-files-obsidian", 56 | "branch": "main" 57 | } 58 | ``` 59 | 60 | - `id`, `name`, `author`, and `description` determines how your plugin appears to the user, and should match the corresponding properties in your [plugin manifest](manifest-reference.md). 61 | - `id` is unique to your plugin. Search `community-plugins.json` to confirm that there's no existing plugin with the same id. 62 | - `repo` is the path to your GitHub repository. For example, if your GitHub repo is located at https://github.com/your-username/your-repo-name, the path is `your-username/your-repo-name`. 63 | - (Optional) `branch` lets you specify the Git branch you want to use. It defaults to `master`, if omitted. 64 | 65 | Remember to add a comma after the closing brace, `}`, of the previous entry. 66 | 67 | 1. [Create a pull request](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). 68 | 1. Follow the instructions in the description field for the pull request to create a pull request from the required template. 69 | 1. Click **Create pull request**. 70 | 1. Fill in the details in the description for the pull request. For the checkboxes, insert an `x` between the brackets, `[x]`, to mark them as done. 71 | 1. Click **Create pull request** (for the last time 🤞). 72 | 73 | You've now submitted your plugin to the Obsidian plugin directory. Sit back and wait for the team to review your plugin. The time it takes to review your plugin depends on the current workload of the Obsidian team. The team is still small, so please be patient while you wait for your plugin to be reviewed. 74 | 75 | ## Step 3 — Address review comments 76 | 77 | Once a reviewer has reviewed your plugin, they'll add a comment to your pull request with the result of the review. The reviewer may require that you update your plugin, or they can offer suggestions on how you can improve it. 78 | 79 | While only Obsidian team members can publish your plugin, other community members may also offer to review your submission in the meantime. 80 | 81 | Users can install your plugin as soon as your pull request has been merged. 82 | 83 | :::tip Want to help? 84 | If you'd like to help review community plugins, refer to the [Plugin Review Guidelines](https://liamca.in/Obsidian/Plugin+Review+Guide/index) by Liam Cain. 85 | ::: 86 | 87 | ## Update an already published plugin 88 | 89 | You only need to submit the initial version of your plugin. After that, users can automatically download any new updates to your plugin directly from within Obsidian. 90 | 91 | To release a new update of your plugin, follow the instructions in [Create a release](#step-1--create-a-release). 92 | 93 | For more information about how Obsidian pulls new versions of community plugins, refer to [How community plugins are pulled](https://github.com/obsidianmd/obsidian-releases#how-community-plugins-are-pulled). 94 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | const lightCodeTheme = require("prism-react-renderer/themes/github"); 2 | const darkCodeTheme = require("prism-react-renderer/themes/dracula"); 3 | 4 | // With JSDoc @type annotations, IDEs can provide config autocompletion 5 | /** @type {import('@docusaurus/types').DocusaurusConfig} */ 6 | ( 7 | module.exports = { 8 | title: "Obsidian Plugin Developer Docs", 9 | tagline: "Obsidian Plugin Developer Docs", 10 | url: "https://marcusolsson.github.io", 11 | baseUrl: "/obsidian-plugin-docs/", 12 | onBrokenLinks: "throw", 13 | onBrokenMarkdownLinks: "warn", 14 | organizationName: "marcusolsson", // Usually your GitHub org/user name. 15 | projectName: "obsidian-plugin-docs", // Usually your repo name. 16 | trailingSlash: false, 17 | scripts: [ 18 | { 19 | src: "https://plausible.io/js/plausible.js", 20 | defer: true, 21 | "data-domain": "marcus.se.net", 22 | }, 23 | ], 24 | plugins: [ 25 | [ 26 | "@docusaurus/plugin-client-redirects", 27 | { 28 | redirects: [ 29 | { 30 | to: "/api/classes/Plugin_2", 31 | from: ["/api/classes/Plugin"], 32 | }, 33 | { 34 | to: "/concepts/plugin-anatomy", 35 | from: ["/getting-started/plugin-anatomy"], 36 | }, 37 | { 38 | to: "/advanced-guides/react", 39 | from: ["/guides/react"], 40 | }, 41 | { 42 | to: "/advanced-guides/svelte", 43 | from: ["/guides/svelte"], 44 | }, 45 | ], 46 | }, 47 | ], 48 | ], 49 | presets: [ 50 | [ 51 | "@docusaurus/preset-classic", 52 | { 53 | docs: { 54 | sidebarPath: require.resolve("./sidebars.js"), 55 | editUrl: 56 | "https://github.com/marcusolsson/obsidian-plugin-docs/edit/main/", 57 | routeBasePath: "/", 58 | remarkPlugins: [ 59 | require("mdx-mermaid"), 60 | [require("@docusaurus/remark-plugin-npm2yarn"), { sync: true }], 61 | ], 62 | }, 63 | theme: { 64 | customCss: require.resolve("./src/css/custom.css"), 65 | }, 66 | }, 67 | ], 68 | ], 69 | 70 | themeConfig: { 71 | defaultMode: "dark", 72 | navbar: { 73 | logo: { 74 | alt: "Logo", 75 | src: "img/logo.svg", 76 | }, 77 | title: "Obsidian Plugin Developer Docs", 78 | items: [ 79 | { 80 | href: "https://buymeacoffee.com/marcusolsson", 81 | label: "Buy me a coffee", 82 | position: "right", 83 | }, 84 | { 85 | href: "https://obsidian.md/community", 86 | label: "Community", 87 | position: "right", 88 | }, 89 | { 90 | href: "https://github.com/marcusolsson/obsidian-plugin-docs", 91 | label: "GitHub", 92 | position: "right", 93 | }, 94 | { 95 | href: "https://marcus.se.net", 96 | label: "Who am I?", 97 | position: "right", 98 | }, 99 | ], 100 | }, 101 | footer: { 102 | links: [ 103 | { 104 | title: "Docs", 105 | items: [ 106 | { 107 | label: "Create your first plugin", 108 | to: "/getting-started/create-your-first-plugin", 109 | }, 110 | ], 111 | }, 112 | { 113 | title: "Resources", 114 | items: [ 115 | { 116 | label: "Community", 117 | href: "https://obsidian.md/community", 118 | }, 119 | { 120 | label: "Create Your Own Obsidian Plugin", 121 | href: "https://www.youtube.com/watch?v=9lA-jaMNS0k", 122 | }, 123 | { 124 | label: "Obsidian API", 125 | href: "https://github.com/obsidianmd/obsidian-api", 126 | }, 127 | ], 128 | }, 129 | { 130 | title: "More", 131 | items: [ 132 | { 133 | label: "GitHub", 134 | href: "https://github.com/marcusolsson/obsidian-plugin-docs", 135 | }, 136 | ], 137 | }, 138 | ], 139 | }, 140 | prism: { 141 | theme: lightCodeTheme, 142 | darkTheme: darkCodeTheme, 143 | }, 144 | }, 145 | } 146 | ); 147 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-plugin-docs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "2.0.0-beta.6", 18 | "@docusaurus/plugin-client-redirects": "^2.0.0-beta.6", 19 | "@docusaurus/preset-classic": "2.0.0-beta.6", 20 | "@docusaurus/remark-plugin-npm2yarn": "^2.0.0-beta.8", 21 | "@mdx-js/react": "^1.6.21", 22 | "@svgr/webpack": "^5.5.0", 23 | "clsx": "^1.1.1", 24 | "file-loader": "^6.2.0", 25 | "mdx-mermaid": "^1.1.0", 26 | "mermaid": "^8.13.2", 27 | "prism-react-renderer": "^1.2.1", 28 | "react": "^17.0.1", 29 | "react-dom": "^17.0.1", 30 | "sass": "^1.39.2", 31 | "url-loader": "^4.1.1" 32 | }, 33 | "browserslist": { 34 | "production": [ 35 | ">0.5%", 36 | "not dead", 37 | "not op_mini all" 38 | ], 39 | "development": [ 40 | "last 1 chrome version", 41 | "last 1 firefox version", 42 | "last 1 safari version" 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | docs: [ 3 | { 4 | type: "autogenerated", 5 | dirName: ".", 6 | }, 7 | ], 8 | }; 9 | -------------------------------------------------------------------------------- /src/css/custom.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"); 2 | 3 | :root { 4 | --ifm-color-primary: #7f6df2; 5 | --ifm-font-family-base: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", 6 | Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", 7 | "Segoe UI Symbol", "Microsoft YaHei Light", sans-serif; 8 | --ifm-link-hover-color: #8875ff; 9 | --ifm-link-hover-decoration: none; 10 | --ifm-navbar-height: 66px; 11 | } 12 | 13 | html body { 14 | text-rendering: optimizeLegibility; 15 | } 16 | 17 | .docusaurus-highlight-code-line { 18 | background-color: rgba(0, 0, 0, 0.1); 19 | display: block; 20 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 21 | padding: 0 var(--ifm-pre-padding); 22 | } 23 | 24 | html[data-theme="dark"] { 25 | --ifm-background-color: #161616; 26 | --ifm-navbar-background-color: #202020; 27 | --ifm-footer-background-color: #202020; 28 | } 29 | 30 | html[data-theme="dark"] .docusaurus-highlight-code-line { 31 | background-color: rgba(0, 0, 0, 0.3); 32 | } 33 | -------------------------------------------------------------------------------- /src/manifest.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$id": "https://marcus.se.net/obsidian-plugin-docs/manifest", 3 | "$schema": "http://json-schema.org/draft-07/schema", 4 | "type": "object", 5 | "title": "Manifest", 6 | "description": "This page describe the schema for the plugin manifest, `manifest.json`.", 7 | "required": [ 8 | "id", 9 | "name", 10 | "author", 11 | "version", 12 | "minAppVersion", 13 | "description", 14 | "isDesktopOnly" 15 | ], 16 | "additionalProperties": false, 17 | "properties": { 18 | "id": { 19 | "type": "string", 20 | "description": "The ID of your plugin.", 21 | "pattern": "^[-0-9a-z]+$" 22 | }, 23 | "name": { 24 | "type": "string", 25 | "description": "The display name of your plugin." 26 | }, 27 | "author": { 28 | "type": "string", 29 | "description": "The plugin author's name." 30 | }, 31 | "version": { 32 | "type": "string", 33 | "description": "The version of your plugin." 34 | }, 35 | "minAppVersion": { 36 | "type": "string", 37 | "description": "The minimum required Obsidian version for your plugin." 38 | }, 39 | "description": { 40 | "type": "string", 41 | "description": "The long description of your plugin." 42 | }, 43 | "authorUrl": { 44 | "type": "string", 45 | "description": "A URL to your own website." 46 | }, 47 | "isDesktopOnly": { 48 | "type": "boolean", 49 | "description": "Whether your plugin uses NodeJS or Electron APIs." 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /static/img/command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/command.png -------------------------------------------------------------------------------- /static/img/context-menu-positions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/context-menu-positions.png -------------------------------------------------------------------------------- /static/img/default-violet.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/default-violet.webp -------------------------------------------------------------------------------- /static/img/editor-todays-date.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/editor-todays-date.gif -------------------------------------------------------------------------------- /static/img/editor-uppercase.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/editor-uppercase.gif -------------------------------------------------------------------------------- /static/img/example-insert-link.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/example-insert-link.gif -------------------------------------------------------------------------------- /static/img/fuzzy-suggestion-modal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/fuzzy-suggestion-modal.png -------------------------------------------------------------------------------- /static/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /static/img/modal-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/modal-input.png -------------------------------------------------------------------------------- /static/img/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/settings.png -------------------------------------------------------------------------------- /static/img/status-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/status-bar.png -------------------------------------------------------------------------------- /static/img/styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/styles.png -------------------------------------------------------------------------------- /static/img/suggest-modal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obsidianmd/obsidian-plugin-docs/dc59a2594b0f99d6c129e03fe2f87f5694899cf8/static/img/suggest-modal.gif --------------------------------------------------------------------------------