Initial commit
This commit is contained in:
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 4
|
||||||
46
.eslintrc.js
Normal file
46
.eslintrc.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2021: true,
|
||||||
|
},
|
||||||
|
extends: ['standard'],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 13,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint'],
|
||||||
|
rules: {
|
||||||
|
'comma-dangle': ['error', 'always-multiline'],
|
||||||
|
'arrow-parens': ['error', 'as-needed'],
|
||||||
|
'brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
|
||||||
|
'func-call-spacing': 'off',
|
||||||
|
// unused vars - fix for enums
|
||||||
|
'no-unused-vars': ['off'],
|
||||||
|
'@typescript-eslint/no-unused-vars': ['warn'],
|
||||||
|
// no redeclare - fix for overloading
|
||||||
|
'no-redeclare': 'off',
|
||||||
|
'@typescript-eslint/no-redeclare': ['error'],
|
||||||
|
// 'simple-import-sort/imports': 'warn',
|
||||||
|
// 'simple-import-sort/exports': 'warn',
|
||||||
|
'@typescript-eslint/func-call-spacing': ['error'],
|
||||||
|
'@typescript-eslint/explicit-function-return-type': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
allowExpressions: true,
|
||||||
|
allowTypedFunctionExpressions: true,
|
||||||
|
allowHigherOrderFunctions: true,
|
||||||
|
allowDirectConstAssertionInArrowFunctions: true,
|
||||||
|
allowConciseArrowFunctionExpressionsStartingWithVoid: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'space-before-function-paren': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
anonymous: 'always',
|
||||||
|
named: 'never',
|
||||||
|
asyncArrow: 'always',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# vscode
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Intellij
|
||||||
|
*.iml
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# npm
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Exclude sourcemaps
|
||||||
|
*.map
|
||||||
|
|
||||||
|
# obsidian
|
||||||
|
data.json
|
||||||
|
|
||||||
|
# Exclude macOS Finder (System Explorer) View States
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
dist
|
||||||
|
.pnpm-debug.log
|
||||||
72
README.md
Normal file
72
README.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
## Obsidian Sample Plugin
|
||||||
|
|
||||||
|
This is a sample plugin for Obsidian (https://obsidian.md).
|
||||||
|
|
||||||
|
This project uses Typescript to provide type checking and documentation.
|
||||||
|
The repo depends on the latest plugin API (obsidian.d.ts) in Typescript Definition format, which contains TSDoc comments describing what it does.
|
||||||
|
|
||||||
|
**Note:** The Obsidian API is still in early alpha and is subject to change at any time!
|
||||||
|
|
||||||
|
This sample plugin demonstrates some of the basic functionality the plugin API can do.
|
||||||
|
- Changes the default font color to red using `styles.css`.
|
||||||
|
- Adds a ribbon icon, which shows a Notice when clicked.
|
||||||
|
- Adds a command "Open Sample Modal" which opens a Modal.
|
||||||
|
- Adds a plugin setting tab to the settings page.
|
||||||
|
- Registers a global click event and output 'click' to the console.
|
||||||
|
- Registers a global interval which logs 'setInterval' to the console.
|
||||||
|
|
||||||
|
### First time developing plugins?
|
||||||
|
|
||||||
|
Quick starting guide for new plugin devs:
|
||||||
|
|
||||||
|
- Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it).
|
||||||
|
- Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder.
|
||||||
|
- Install NodeJS, then run `npm i` in the command line under your repo folder.
|
||||||
|
- Run `npm run dev` to compile your plugin from `main.ts` to `main.js`.
|
||||||
|
- Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`.
|
||||||
|
- Reload Obsidian to load the new version of your plugin.
|
||||||
|
- Enable plugin in settings window.
|
||||||
|
- For updates to the Obsidian API run `npm update` in the command line under your repo folder.
|
||||||
|
|
||||||
|
### Releasing new releases
|
||||||
|
|
||||||
|
- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release.
|
||||||
|
- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible.
|
||||||
|
- Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases
|
||||||
|
- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments. Note: The manifest.json file must be in two places, first the root path of your repository and also in the release.
|
||||||
|
- Publish the release.
|
||||||
|
|
||||||
|
> You can simplify the version bump process by running `npm version patch`, `npm version minor` or `npm version major` after updating `minAppVersion` manually in `manifest.json`.
|
||||||
|
> The command will bump version in `manifest.json` and `package.json`, and add the entry for the new version to `versions.json`
|
||||||
|
|
||||||
|
### Adding your plugin to the community plugin list
|
||||||
|
|
||||||
|
- Check https://github.com/obsidianmd/obsidian-releases/blob/master/plugin-review.md
|
||||||
|
- Publish an initial version.
|
||||||
|
- Make sure you have a `README.md` file in the root of your repo.
|
||||||
|
- Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin.
|
||||||
|
|
||||||
|
### How to use
|
||||||
|
|
||||||
|
- Clone this repo.
|
||||||
|
- `npm i` or `yarn` to install dependencies
|
||||||
|
- `npm run dev` to start compilation in watch mode.
|
||||||
|
|
||||||
|
### Manually installing the plugin
|
||||||
|
|
||||||
|
- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`.
|
||||||
|
|
||||||
|
### Improve code quality with eslint (optional)
|
||||||
|
- [ESLint](https://eslint.org/) is a tool that analyzes your code to quickly find problems. You can run ESLint against your plugin to find common bugs and ways to improve your code.
|
||||||
|
- To use eslint with this project, make sure to install eslint from terminal:
|
||||||
|
- `npm install -g eslint`
|
||||||
|
- To use eslint to analyze this project use this command:
|
||||||
|
- `eslint main.ts`
|
||||||
|
- eslint will then create a report with suggestions for code improvement by file and line number.
|
||||||
|
- If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder:
|
||||||
|
- `eslint .\src\`
|
||||||
|
|
||||||
|
|
||||||
|
### API Documentation
|
||||||
|
|
||||||
|
See https://github.com/obsidianmd/obsidian-api
|
||||||
10
assets/manifest.json
Normal file
10
assets/manifest.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"id": "scambier.obsidian-omnisearch",
|
||||||
|
"name": "Omnisearch",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"minAppVersion": "0.14.2",
|
||||||
|
"description": "Search over organization",
|
||||||
|
"author": "Simon Cambier",
|
||||||
|
"authorUrl": "",
|
||||||
|
"isDesktopOnly": false
|
||||||
|
}
|
||||||
4
assets/styles.css
Normal file
4
assets/styles.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/* Sets all the text color to red! */
|
||||||
|
body {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
66
esbuild.config.mjs
Normal file
66
esbuild.config.mjs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import esbuild from 'esbuild'
|
||||||
|
import process from 'process'
|
||||||
|
import builtins from 'builtin-modules'
|
||||||
|
import { copy } from 'esbuild-plugin-copy'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
const banner = `/*
|
||||||
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||||||
|
if you want to view the source, please visit the github repository of this plugin
|
||||||
|
*/
|
||||||
|
`
|
||||||
|
|
||||||
|
const prod = process.argv[2] === 'production'
|
||||||
|
|
||||||
|
esbuild
|
||||||
|
.build({
|
||||||
|
banner: {
|
||||||
|
js: banner,
|
||||||
|
},
|
||||||
|
entryPoints: ['./src/main.ts'],
|
||||||
|
bundle: true,
|
||||||
|
external: [
|
||||||
|
'obsidian',
|
||||||
|
'electron',
|
||||||
|
'@codemirror/autocomplete',
|
||||||
|
'@codemirror/closebrackets',
|
||||||
|
'@codemirror/collab',
|
||||||
|
'@codemirror/commands',
|
||||||
|
'@codemirror/comment',
|
||||||
|
'@codemirror/fold',
|
||||||
|
'@codemirror/gutter',
|
||||||
|
'@codemirror/highlight',
|
||||||
|
'@codemirror/history',
|
||||||
|
'@codemirror/language',
|
||||||
|
'@codemirror/lint',
|
||||||
|
'@codemirror/matchbrackets',
|
||||||
|
'@codemirror/panel',
|
||||||
|
'@codemirror/rangeset',
|
||||||
|
'@codemirror/rectangular-selection',
|
||||||
|
'@codemirror/search',
|
||||||
|
'@codemirror/state',
|
||||||
|
'@codemirror/stream-parser',
|
||||||
|
'@codemirror/text',
|
||||||
|
'@codemirror/tooltip',
|
||||||
|
'@codemirror/view',
|
||||||
|
...builtins,
|
||||||
|
],
|
||||||
|
outfile: path.join('./dist', 'main.js'),
|
||||||
|
plugins: [
|
||||||
|
copy({
|
||||||
|
// this is equal to process.cwd(), which means we use cwd path as base path to resolve `to` path
|
||||||
|
// if not specified, this plugin uses ESBuild.build outdir/outfile options as base path.
|
||||||
|
assets: {
|
||||||
|
from: ['./assets/*'],
|
||||||
|
to: ['./'],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
format: 'cjs',
|
||||||
|
watch: !prod,
|
||||||
|
target: 'chrome98',
|
||||||
|
logLevel: 'info',
|
||||||
|
sourcemap: prod ? false : 'inline',
|
||||||
|
treeShaking: true,
|
||||||
|
})
|
||||||
|
.catch(() => process.exit(1))
|
||||||
36
package.json
Normal file
36
package.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "scambier.obsidian-search",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "Search over organization",
|
||||||
|
"main": "dist/main.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "node esbuild.config.mjs",
|
||||||
|
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||||
|
"version": "node version-bump.mjs && git add manifest.json versions.json"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^16.11.6",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||||
|
"@typescript-eslint/parser": "^5.18.0",
|
||||||
|
"builtin-modules": "^3.2.0",
|
||||||
|
"esbuild": "0.13.12",
|
||||||
|
"esbuild-plugin-copy": "^1.2.1",
|
||||||
|
"eslint": "7.12.1",
|
||||||
|
"eslint-config-standard": "^16.0.3",
|
||||||
|
"eslint-plugin-import": "2.22.1",
|
||||||
|
"eslint-plugin-node": "11.1.0",
|
||||||
|
"eslint-plugin-promise": "5.0.0",
|
||||||
|
"obsidian": "latest",
|
||||||
|
"prettier": "^2.6.2",
|
||||||
|
"prettier-eslint": "^13.0.0",
|
||||||
|
"tslib": "2.3.1",
|
||||||
|
"typescript": "4.4.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minisearch": "^4.0.3",
|
||||||
|
"remove-markdown": "^0.3.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
2152
pnpm-lock.yaml
generated
Normal file
2152
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
115
src/main.ts
Normal file
115
src/main.ts
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import { App, Plugin, SuggestModal, TFile } from 'obsidian'
|
||||||
|
import MiniSearch from 'minisearch'
|
||||||
|
import removeMarkdown from 'remove-markdown'
|
||||||
|
|
||||||
|
type OmnisearchMatch = {
|
||||||
|
path: string
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class OmnisearchPlugin extends Plugin {
|
||||||
|
minisearch: MiniSearch<OmnisearchMatch>
|
||||||
|
files: TFile[]
|
||||||
|
contents: Record<string, string>
|
||||||
|
|
||||||
|
async onload(): Promise<void> {
|
||||||
|
this.contents = {}
|
||||||
|
this.minisearch = new MiniSearch<OmnisearchMatch>({
|
||||||
|
idField: 'path',
|
||||||
|
fields: ['content', 'title'],
|
||||||
|
storeFields: ['path'],
|
||||||
|
extractField: (document, fieldName) => {
|
||||||
|
if (fieldName === 'title') return getNoteTitle(document.content)
|
||||||
|
return (document as any)[fieldName] as string
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
this.app.workspace.onLayoutReady(async () => {
|
||||||
|
this.files = this.app.vault.getMarkdownFiles()
|
||||||
|
for (const file of this.files) {
|
||||||
|
const content = await this.app.vault.cachedRead(file)
|
||||||
|
this.contents[file.path] = truncateBody(getNoteBody(content))
|
||||||
|
this.minisearch.add({ content, path: file.path })
|
||||||
|
}
|
||||||
|
console.log('minisearch loaded')
|
||||||
|
console.log(this.files.length + ' notes')
|
||||||
|
})
|
||||||
|
|
||||||
|
this.addCommand({
|
||||||
|
id: 'show-modal',
|
||||||
|
name: 'Open Omnisearch',
|
||||||
|
hotkeys: [{ modifiers: ['Mod'], key: 'o' }],
|
||||||
|
callback: () => {
|
||||||
|
new OmnisearchModal(this).open()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OmnisearchModal extends SuggestModal<OmnisearchMatch> {
|
||||||
|
plugin: OmnisearchPlugin
|
||||||
|
|
||||||
|
constructor(plugin: OmnisearchPlugin) {
|
||||||
|
super(plugin.app)
|
||||||
|
this.plugin = plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
getSuggestions(query: string): OmnisearchMatch[] {
|
||||||
|
const results = this.plugin.minisearch.search(query, {
|
||||||
|
prefix: true,
|
||||||
|
fuzzy: term => (term.length > 4 ? 0.2 : false),
|
||||||
|
combineWith: 'AND',
|
||||||
|
// processTerm: term => term.length <= minLength ? false : term,
|
||||||
|
boost: { title: 2 },
|
||||||
|
})
|
||||||
|
return results.map(result => {
|
||||||
|
const file = this.plugin.files.find(f => f.path === result.id)
|
||||||
|
return {
|
||||||
|
path: file.path,
|
||||||
|
content: this.plugin.contents[file.path],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSuggestion(value: OmnisearchMatch, el: HTMLElement) {
|
||||||
|
el.createEl('div', { text: value.path })
|
||||||
|
el.createEl('small', { text: value.content })
|
||||||
|
}
|
||||||
|
|
||||||
|
onChooseSuggestion(item: OmnisearchMatch, evt: MouseEvent | KeyboardEvent) {
|
||||||
|
throw new Error('Method not implemented.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function truncateBody(body: string): string {
|
||||||
|
return body.substring(0, 200) + (body.length > 0 ? '...' : '')
|
||||||
|
}
|
||||||
|
function getNoteTitle(note: string): string {
|
||||||
|
return getFirstLine(removeMd(note))
|
||||||
|
}
|
||||||
|
function getNoteBody(contents: string): string {
|
||||||
|
return truncateFirstLine(removeMd(contents))
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFirstLine(text: string): string {
|
||||||
|
return splitLines(text.trim())[0]
|
||||||
|
}
|
||||||
|
function splitLines(text: string): string[] {
|
||||||
|
return text.split(/\r?\n|\r/)
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeMd(text: string): string {
|
||||||
|
return removeMarkdown(removeFrontMatter(text))
|
||||||
|
}
|
||||||
|
function removeFrontMatter(text: string): string {
|
||||||
|
// Regex to recognize YAML Front Matter (at beginning of file, 3 hyphens, than any charecter, including newlines, then 3 hyphens).
|
||||||
|
const YAMLFrontMatter = /^---\s*\n(.*?)\n?^---\s?/ms
|
||||||
|
return text.replace(YAMLFrontMatter, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function truncateFirstLine(text: string): string {
|
||||||
|
// https://stackoverflow.com/questions/2528076/delete-a-line-of-text-in-javascript
|
||||||
|
const lines = splitLines(text.trim())
|
||||||
|
lines.splice(0, 1)
|
||||||
|
return lines.join('\n')
|
||||||
|
}
|
||||||
1
src/modules.d.ts
vendored
Normal file
1
src/modules.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
declare module 'remove-markdown'
|
||||||
4
src/styles.css
Normal file
4
src/styles.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/* Sets all the text color to red! */
|
||||||
|
body {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
23
tsconfig.json
Normal file
23
tsconfig.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"inlineSourceMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"target": "ES6",
|
||||||
|
"allowJs": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"importHelpers": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"lib": [
|
||||||
|
"DOM",
|
||||||
|
"ES5",
|
||||||
|
"ES6",
|
||||||
|
"ES7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
14
version-bump.mjs
Normal file
14
version-bump.mjs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { readFileSync, writeFileSync } from "fs";
|
||||||
|
|
||||||
|
const targetVersion = process.env.npm_package_version;
|
||||||
|
|
||||||
|
// read minAppVersion from manifest.json and bump version to target version
|
||||||
|
let manifest = JSON.parse(readFileSync("manifest.json", "utf8"));
|
||||||
|
const { minAppVersion } = manifest;
|
||||||
|
manifest.version = targetVersion;
|
||||||
|
writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t"));
|
||||||
|
|
||||||
|
// update versions.json with target version and minAppVersion from manifest.json
|
||||||
|
let versions = JSON.parse(readFileSync("versions.json", "utf8"));
|
||||||
|
versions[targetVersion] = minAppVersion;
|
||||||
|
writeFileSync("versions.json", JSON.stringify(versions, null, "\t"));
|
||||||
4
versions.json
Normal file
4
versions.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"1.0.0": "0.9.7",
|
||||||
|
"1.0.1": "0.12.0"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user