### Install ESLint Source: https://github.com/obsidianmd/eslint-plugin/blob/master/README.md Install ESLint as a development dependency. ```sh npm i eslint --save-dev ``` -------------------------------- ### Example PluginManifest Object Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/types.md Illustrates how to construct a PluginManifest object with all required and optional fields. ```typescript const manifest: PluginManifest = { id: 'my-plugin', name: 'My Plugin', version: '1.0.0', minAppVersion: '1.0.0', author: 'Your Name', description: 'A helpful plugin for Obsidian', isDesktopOnly: false, authorUrl: 'https://yoursite.com', fundingUrl: { buy: 'https://buymeacoffee.com/yourname', github: 'https://github.com/sponsors/yourname' } }; ``` -------------------------------- ### Install ESLint and Plugin Dependencies Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Install the necessary ESLint, TypeScript ESLint, and obsidianmd plugin packages as development dependencies. ```bash npm install --save-dev eslint-plugin-obsidianmd npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin npm install --save-dev typescript typescript-eslint ``` -------------------------------- ### Configurations Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Provides predefined ESLint configurations for recommended and locale-specific setups. ```APIDOC ## plugin.configs.recommended **Type:** `Config[]` ### Description An array of ESLint configuration objects providing the recommended baseline for Obsidian plugin development. Enables core ESLint rules, TypeScript-ESLint recommended rules, `obsidianmd` plugin rules, security rules, and import validation. ### Usage ```typescript import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], languageOptions: { parser: '@typescript-eslint/parser', }, }, ]); ``` ``` ```APIDOC ## plugin.configs.recommendedWithLocalesEn **Type:** `Config[]` ### Description Extends the recommended configuration with additional rules for English locale files. Applies sentence case validation to JSON and TypeScript/JavaScript modules matching `en*.json`, `en*.ts`, or `en*.js` patterns. ### Usage ```typescript import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommendedWithLocalesEn, ]); ``` ``` -------------------------------- ### Install Obsidian Module Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Ensure the 'obsidian' package is installed and available in your project's node_modules. This is a prerequisite for using Obsidian-specific functionalities. ```bash npm install --save obsidian ``` -------------------------------- ### Basic ESLint Setup for Obsidian Plugins Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Recommended ESLint configuration for most Obsidian plugins, using TypeScript and the recommended plugin settings. ```javascript // eslint.config.js import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json' }, }, }, ]); ``` -------------------------------- ### Example Usage of getManifest Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Demonstrates how to import and use the getManifest function to retrieve and log plugin metadata. Includes a check to ensure the manifest was successfully parsed. ```typescript import { getManifest } from 'eslint-plugin-obsidianmd/lib/manifest'; const manifest = getManifest(); if (manifest) { console.log(manifest.minAppVersion); // e.g., '1.0.0' console.log(manifest.isDesktopOnly); // e.g., false } ``` -------------------------------- ### Configure ESLint Rule Options Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/INDEX.md Set specific options for ESLint rules. This example configures 'obsidianmd/no-unsupported-api' with a minimum app version and 'obsidianmd/ui/sentence-case' with brand exceptions. ```javascript rules: { 'obsidianmd/no-unsupported-api': ['error', { minAppVersion: '1.5.0' }], 'obsidianmd/ui/sentence-case': ['error', { brands: ['GitHub'] }], } ``` -------------------------------- ### Install eslint-plugin-obsidianmd Source: https://github.com/obsidianmd/eslint-plugin/blob/master/README.md Install the obsidianmd ESLint plugin as a development dependency. ```sh npm install eslint-plugin-obsidianmd --save-dev ``` -------------------------------- ### Example of Rendered Message Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/errors-and-messages.md Illustrates how the template variables are filled to produce the final error message. ```text 'App.workspace.getActiveFile' requires Obsidian v1.5.0, but minAppVersion is 1.0.0. ``` -------------------------------- ### ESLint Configuration with Recommended Rules Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/INDEX.md Configure ESLint to use the recommended rules from the obsidianmd plugin. This setup includes type-checking for TypeScript files. ```javascript import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json' }, }, }, ]); ``` -------------------------------- ### Example manifest.json Configuration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md This JSON file configures plugin metadata and is used by the `obsidianmd/no-unsupported-api` and `obsidianmd/no-nodejs-modules` rules. Ensure `minAppVersion` is set to the minimum Obsidian version your plugin supports. ```json { "id": "my-plugin", "name": "My Plugin", "version": "1.0.0", "minAppVersion": "1.0.0", "description": "A plugin for Obsidian", "author": "Your Name", "isDesktopOnly": false } ``` -------------------------------- ### Install TypeScript Types Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Install necessary TypeScript type definitions for Node.js and ESLint to resolve module declaration errors. This is crucial for projects using TypeScript. ```bash npm install --save-dev @types/node @types/eslint ``` -------------------------------- ### Common ESLint Language Options Configuration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/types.md An example of how to configure language options for ESLint, including specifying a TypeScript parser, project settings, and global variables. ```typescript languageOptions: { parser: tsParser, parserOptions: { project: './tsconfig.json', ecmaVersion: 2020, }, globals: { console: 'readonly', fetch: 'readonly', } } ``` -------------------------------- ### Use Recommended ESLint Configuration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Integrate the recommended ESLint configuration for Obsidian plugin development into your flat config. This setup includes core ESLint, TypeScript-ESLint, obsidianmd rules, and security/import validation. ```typescript import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; // Use in ESLint flat config export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], rules: { 'obsidianmd/sample-names': 'off', }, }, ]); ``` -------------------------------- ### Configure ESLint for UI Sentence Case (Flat Config) Source: https://github.com/obsidianmd/eslint-plugin/blob/master/README.md Configure ESLint using flat config to enforce UI sentence case rules. This example shows how to import the plugin and apply its recommended configurations, with specific overrides for the sentence case rule including custom brands, acronyms, and camel case enforcement. ```javascript // eslint.config.mjs import tsparser from "@typescript-eslint/parser"; import { defineConfig } from "eslint/config"; import obsidianmd from "eslint-plugin-obsidianmd"; export default defineConfig([ ...obsidianmd.configs.recommended, // Or include English locale files (JSON and TS/JS modules) // ...obsidianmd.configs.recommendedWithLocalesEn, { files: ["**/*.ts"], languageOptions: { parser: tsparser, parserOptions: { project: "./tsconfig.json" }, }, // Optional project overrides rules: { "obsidianmd/ui/sentence-case": [ "warn", { brands: ["YourBrand"], acronyms: ["OK"], enforceCamelCaseLower: true, }, ], }, }, ]); ``` -------------------------------- ### ESLint Setup with English Locale Validation Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Configure ESLint to include validation for English locale files, suitable for plugins with internationalization support. ```javascript // eslint.config.js import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommendedWithLocalesEn, { files: ['**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json' }, }, }, ]); ``` -------------------------------- ### Fix: Use Vault#configDir for paths Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Do not hardcode paths like '.obsidian/plugins'. Use the `this.app.vault.configDir` property to dynamically get the correct configuration directory path. ```typescript // Error: Use Vault#configDir instead const configPath = '.obsidian/plugins'; ``` ```typescript const configPath = this.app.vault.configDir + '/plugins'; ``` -------------------------------- ### Message ID with Data Template Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/errors-and-messages.md Example of a message ID with data that can be used to fill template variables in the message string. ```javascript messageId: 'apiNotAvailable', data: { qualifiedName: 'App.workspace.getActiveFile', sinceVersion: '1.5.0', minAppVersion: '1.0.0' } ``` -------------------------------- ### Get Plugin Manifest Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Reads and caches the manifest.json file. Use this to determine plugin metadata like minimum app version. Returns the parsed manifest object or null if the file is not found or parsing fails. ```typescript function getManifest(): PluginManifest | null ``` -------------------------------- ### Add ESLint Check to GitHub Actions CI Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Integrate ESLint into your GitHub Actions workflow to automatically lint code on push and pull requests. Ensure Node.js is set up and dependencies are installed before running lint scripts. ```yaml # .github/workflows/lint.yml name: Lint on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm ci - run: npm run lint # Optional: type check as well - run: npm run type-check ``` -------------------------------- ### fundingUrl Type Definition and Variants Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/types.md Defines the structure for funding URLs, which can be either a single string URL or a record of named funding sources. Examples show how to represent both single and multiple funding options. ```typescript type fundingUrl = string | Record ``` ```typescript // Single funding source const fundingUrl1: fundingUrl = 'https://buymeacoffee.com/myname'; ``` ```typescript // Multiple funding sources const fundingUrl2: fundingUrl = { 'buy': 'https://buymeacoffee.com/myname', 'github': 'https://github.com/sponsors/myname', 'patreon': 'https://patreon.com/myname' }; ``` -------------------------------- ### Basic ESLint Configuration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Set up the basic ESLint configuration file using recommended settings and TypeScript parser. ```javascript // eslint.config.js import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts', '**/*.tsx'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json', }, }, }, ]); ``` -------------------------------- ### Recommended ESLint Configuration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md Use the `recommended` preset for standard Obsidian plugin development. It includes core ESLint, TypeScript, security, import, and depository rules, with type-checked rules applied only to TypeScript files. ```javascript { "plugins": { "obsidianmd": require("eslint-plugin-obsidianmd") }, "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:@microsoft/eslint-plugin-sdl/recommended", "plugin:import/recommended", "plugin:import/typescript", "plugin:obsidianmd/recommended" ] } ``` -------------------------------- ### Customize Rule Message Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/errors-and-messages.md Use the `obsidianmd/rule-custom-message` rule to redefine specific error messages for ESLint rules. This example customizes the message for the `no-console` rule. ```javascript 'obsidianmd/rule-custom-message': [ 'error', { 'no-console': { messages: { 'Unexpected console statement. Only these console methods are allowed: warn, error, debug.': 'Only use console.warn, console.error, or console.debug.' }, options: [{ allow: ['warn', 'error', 'debug'] }] } } ] ``` -------------------------------- ### Set Up Pre-commit Hook with Husky and Lint-staged Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Configure Husky and lint-staged to automatically lint staged TypeScript, TSX, and manifest.json files before each commit. This ensures code quality is maintained at the commit level. ```bash npm install --save-dev husky lint-staged npx husky install npx husky add .husky/pre-commit "npx lint-staged" ``` ```json { "lint-staged": { "*.ts": ["eslint --fix"], "*.tsx": ["eslint --fix"], "manifest.json": ["eslint --fix"] } } ``` -------------------------------- ### Configure Legacy ESLint Config Source: https://github.com/obsidianmd/eslint-plugin/blob/master/README.md Extend the recommended configuration in your `.eslintrc` file for ESLint v8 and older. This allows for easy integration of the plugin's rules. ```json { "extends": ["plugin:obsidianmd/recommended"] } ``` -------------------------------- ### docsUrl() Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Generates the documentation URL for a rule, pointing to its location on GitHub. ```APIDOC ## docsUrl() ### Description Generates the documentation URL for a rule. ### Parameters #### Path Parameters - **name** (string) - Required - Rule name (e.g., `'detach-leaves'`) - **subdir** (string) - Optional - Optional subdirectory (e.g., `'commands'`, `'ui'`) ### Returns `string` - Full documentation URL pointing to GitHub ### Example ```typescript const url = docsUrl('sample-names'); // Returns: 'https://github.com/obsidianmd/eslint-plugin/blob/master/docs/rules/sample-names.md' const nestedUrl = docsUrl('no-command-in-command-id', 'commands'); // Returns: 'https://github.com/obsidianmd/eslint-plugin/blob/master/docs/rules/commands/no-command-in-command-id.md' ``` ``` -------------------------------- ### Wrap Plugin ESLint Rule with Custom Message Source: https://github.com/obsidianmd/eslint-plugin/blob/master/docs/rules/rule-custom-message.md Integrate custom messages for rules from external ESLint plugins, such as '@typescript-eslint/eslint-plugin'. This example demonstrates overriding the 'no-explicit-any' rule with a more descriptive message. ```javascript import typescriptPlugin from "@typescript-eslint/eslint-plugin"; export default [ { rules: { "@typescript-eslint/no-explicit-any": "off", "obsidianmd/rule-custom-message": [ "error", { "@typescript-eslint/no-explicit-any": { messages: { "Unexpected any. Specify a different type.": "Avoid using 'any'. Use 'unknown' or define a proper type." }, options: [], rule: typescriptPlugin.rules["no-explicit-any"] } } ] } } ]; ``` -------------------------------- ### Generate Rule Documentation URL Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Use `docsUrl` to create the correct URL for a rule's documentation on GitHub. It accepts the rule name and an optional subdirectory. ```typescript function docsUrl(name: string, subdir?: string): string ``` ```typescript const url = docsUrl('sample-names'); // Returns: 'https://github.com/obsidianmd/eslint-plugin/blob/master/docs/rules/sample-names.md' const nestedUrl = docsUrl('no-command-in-command-id', 'commands'); // Returns: 'https://github.com/obsidianmd/eslint-plugin/blob/master/docs/rules/commands/no-command-in-command-id.md' ``` -------------------------------- ### Apply Recommended ESLint Configuration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Apply the recommended ESLint configuration for Obsidian plugin development using the flat config system. Ensure TypeScript parsing is enabled for TypeScript files. ```typescript import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], languageOptions: { parser: '@typescript-eslint/parser', }, }, ]); ``` -------------------------------- ### Prefer window timers for popout compatibility Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/rules-reference.md Use `window.setTimeout()` and similar functions instead of bare global calls to ensure compatibility with popout windows. ```typescript // ⚠️ NOT POPOUT-COMPATIBLE setTimeout(() => { }, 100); // ✅ POPOUT-COMPATIBLE window.setTimeout(() => { }, 100); ``` -------------------------------- ### Wrap Built-in ESLint Rule with Custom Message Source: https://github.com/obsidianmd/eslint-plugin/blob/master/docs/rules/rule-custom-message.md Configure the 'obsidianmd/rule-custom-message' to override the default message for the 'no-console' rule. This example shows how to disable the original rule and provide a custom message with specific allowed console methods. ```javascript export default [ { files: ["**/*.js"], plugins: { obsidianmd: obsidianmd, }, rules: { "no-console": "off", // Disable the original rule "obsidianmd/rule-custom-message": [ "error", { "no-console": { messages: { "Unexpected console statement. Only these console methods are allowed: warn, error, debug.": "Avoid unnecessary logging to console. See https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines#Avoid+unnecessary+logging+to+console" }, options: [{ allow: ["warn", "error", "debug"] }] } } ] } } ]; ``` -------------------------------- ### Partial Message Matching for Custom ESLint Messages Source: https://github.com/obsidianmd/eslint-plugin/blob/master/docs/rules/rule-custom-message.md Utilize partial message matching to apply a custom message to any ESLint rule violation where the original message contains specific text. This example shows a generic custom message for 'no-console' violations containing 'Unexpected console statement'. ```json { "obsidianmd/rule-custom-message": [ "error", { "no-console": { messages: { "Unexpected console statement": "Custom message for all console violations" }, options: [{ allow: ["warn", "error"] }] } } ] } ``` -------------------------------- ### Configure ESLint v9+ with Flat Config Source: https://github.com/obsidianmd/eslint-plugin/blob/master/README.md Use the recommended configuration for ESLint v9 and above in your `eslint.config.js` (or `.mjs`). This enables all recommended rules and allows for custom rule overrides. ```javascript // eslint.config.mjs import tsparser from "@typescript-eslint/parser"; import { defineConfig } from "eslint/config"; import obsidianmd from "eslint-plugin-obsidianmd"; export default defineConfig([ ...obsidianmd.configs.recommended, { files: ["**/*.ts"], languageOptions: { parser: tsparser, parserOptions: { project: "./tsconfig.json" }, }, // You can add your own configuration to override or add rules rules: { // example: turn off a rule from the recommended set "obsidianmd/sample-names": "off", // example: add a rule not in the recommended set and set its severity "obsidianmd/prefer-file-manager-trash": "error", }, }, ]); ``` -------------------------------- ### Node.js Globals for Desktop-Only Plugins Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md Lists Node.js globals available for desktop-only Obsidian plugins. These are enabled when the manifest.json includes `"isDesktopOnly": true`. ```plaintext fs, path, process, Buffer, require, __dirname, __filename, etc. ``` -------------------------------- ### Node.js Module Usage Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/errors-and-messages.md Rule to flag the use of Node.js built-in modules. These should only be used on desktop via Platform.isDesktop. ```javascript messageId: 'noNodejs', message: "'{{module}}' is a Node.js module. Use it only on desktop via Platform.isDesktop." ``` -------------------------------- ### Iterating Vault Files Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/rules-reference.md Demonstrates the incorrect method of iterating all vault files to find a specific file by path and the recommended, more efficient approach using getAbstractFileByPath(). ```typescript // ❌ INCORRECT const file = this.app.vault.getFiles().find(f => f.path === 'notes/my-note.md'); // ✅ CORRECT const file = this.app.vault.getAbstractFileByPath('notes/my-note.md'); ``` -------------------------------- ### ESLint Configuration with Locale Files Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md An ESLint configuration that includes locale validation rules and customizes their behavior for specific brands. ```javascript // eslint.config.js import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ // Include locale validation ...plugin.configs.recommendedWithLocalesEn, { files: ['**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json' }, }, rules: { // Customize locale rule behavior 'obsidianmd/ui/sentence-case-json': [ 'warn', { brands: ['Obsidian'] }, ], 'obsidianmd/ui/sentence-case-locale-module': [ 'warn', { brands: ['Obsidian'] }, ], }, }, ]); ``` -------------------------------- ### Import ESLint Plugin Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Import the main plugin object for use in ESLint configurations. This is the primary integration point. ```typescript import plugin from 'eslint-plugin-obsidianmd'; ``` -------------------------------- ### Configure `no-unsupported-api` Rule Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md Use this snippet to override the minimum app version check for unsupported APIs. Specify a `minAppVersion` to enforce a newer minimum version than what's defined in `manifest.json`. ```javascript // eslint.config.js export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], rules: { 'obsidianmd/no-unsupported-api': [ 'error', { minAppVersion: '1.5.0' } // Check against 1.5.0 instead of manifest ] } } ]); ``` -------------------------------- ### Recommended ESLint Configuration with English Locale Validation Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md Extend the `recommended` configuration with `recommendedWithLocalesEn` to enable validation for English locale files (`.json` and `.ts`/`.js`). This preset applies specific rules with a `warn` severity for sentence case consistency. ```javascript { "plugins": { "obsidianmd": require("eslint-plugin-obsidianmd") }, "extends": [ "plugin:obsidianmd/recommendedWithLocalesEn" ] } ``` -------------------------------- ### Run ESLint Commands Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Execute ESLint commands to check for violations, automatically fix them, or check a specific file. ```bash # Check for violations npm run lint # Auto-fix violations npm run lint:fix # Check specific file npx eslint src/main.ts ``` -------------------------------- ### Prefer Obsidian DOM helpers Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/rules-reference.md Use Obsidian's DOM helper functions like `createDiv()` over native `document.createElement()` for preferred syntax. ```typescript // ❌ NOT PREFERRED const div = document.createElement('div'); // ✅ PREFERRED const div = createDiv(); ``` -------------------------------- ### Prefer activeDocument over document Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/rules-reference.md Use `activeDocument` instead of `document` for better compatibility with popout windows. ```typescript // ⚠️ SUBOPTIMAL const el = document.querySelector('div'); // ✅ BETTER const el = activeDocument.querySelector('div'); ``` -------------------------------- ### Avoid Hardcoding '.obsidian' Paths Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/errors-and-messages.md Rule to prevent hardcoding '.obsidian' paths. Use 'Vault#configDir' instead for better compatibility. ```javascript messageId: 'hardcodedPath', message: "Avoid hardcoding '.obsidian' paths. Use 'Vault#configDir' instead." ``` -------------------------------- ### Type Definitions Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/COMPLETION-REPORT.txt Key type definitions available in the plugin. ```APIDOC ## Type Definitions - **PluginManifest**: Represents the plugin's manifest. - **ThemeManifest**: Represents a theme's manifest. - **Manifest**: A general manifest type. - **fundingUrl**: Type for funding URLs. - **ESLint.Plugin**: The interface for the ESLint plugin. - **Config**: Represents the plugin's configuration. - **RuleDefinition**: Defines an ESLint rule. - **RuleContext**: Provides context for rule execution. - **TSESTree**: Types related to the ESTree AST. - **SentenceCaseRuleOptions**: Options for sentence case rules. - **RulesConfig**: Configuration for multiple rules. - **LanguageOptions**: Options related to language settings. - **PackageJson**: Represents the package.json structure. ``` -------------------------------- ### ESLint Configuration with Custom Rule Options Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Customize ESLint rules, including sentence casing for brands, disabling irrelevant rules, and rewriting custom messages. ```javascript // eslint.config.js import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json' }, }, rules: { // Customize sentence case for your brands 'obsidianmd/ui/sentence-case': [ 'error', { brands: ['GitHub', 'Obsidian', 'YourBrandName'], acronyms: ['API', 'HTTP', 'OK'], }, ], // Disable rules not relevant to your project 'obsidianmd/sample-names': 'off', // Customize custom message rewrites 'obsidianmd/rule-custom-message': [ 'error', { 'no-console': { messages: { 'Unexpected console statement. Only these console methods are allowed: warn, error, debug.': 'Only use console.warn, console.error, or console.debug for debugging.', }, options: [{ allow: ['warn', 'error', 'debug'] }], }, }, ], }, }, ]); ``` -------------------------------- ### Browser Globals for ESLint Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md Lists common browser globals available when using the ESLint plugin in a browser environment. These are typically provided by the browser's runtime. ```plaintext window, document, globalThis, location, history, navigator, console, HTMLElement, HTMLDivElement, HTMLDocument, etc. ``` -------------------------------- ### Use 'window' instead of 'global'/'globalThis' Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/rules-reference.md This rule disallows `global` and `globalThis` references in favor of `window` for cross-window compatibility in Obsidian's popout windows. It is a suggestion type rule and is fixable by replacing with `window`. It does not require type information. ```typescript // ❌ INCORRECT const isDarkMode = (globalThis as any).isDarkMode; const x = global.someProperty; // ✅ CORRECT const isDarkMode = (window as any).isDarkMode; const x = window.someProperty; ``` -------------------------------- ### Apply Recommended ESLint Configuration with English Locales Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Extend the recommended ESLint configuration with additional rules specifically for English locale files. This configuration validates JSON and TypeScript/JavaScript files matching 'en*.json', 'en*.ts', or 'en*.js' patterns. ```typescript import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommendedWithLocalesEn, ]); ``` -------------------------------- ### Fix: Use Obsidian's requestUrl Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Replace external libraries like 'axios' with Obsidian's built-in `requestUrl` function for making HTTP requests. This ensures better integration and avoids unnecessary dependencies. ```typescript // Error: Use the built-in `requestUrl` function instead import axios from 'axios'; axios.get('https://api.example.com'); ``` ```typescript import { requestUrl } from 'obsidian'; requestUrl({ url: 'https://api.example.com' }); ``` -------------------------------- ### getManifest() Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/api-reference.md Reads and caches the `manifest.json` file from the current working directory. This function is used by rules to determine plugin metadata such as the minimum app version. ```APIDOC ## getManifest() ### Description Reads and caches the `manifest.json` file from the current working directory. Used by rules to determine plugin metadata like minimum app version. ### Returns - `PluginManifest | null` — Parsed manifest object or null if file not found or parsing fails ### Type: PluginManifest ```typescript type PluginManifest = { id: string; name: string; version: string; description: string; author: string; minAppVersion: string; isDesktopOnly: boolean; authorUrl?: string; fundingUrl?: string | Record; } ``` ### Example ```typescript import { getManifest } from 'eslint-plugin-obsidianmd/lib/manifest'; const manifest = getManifest(); if (manifest) { console.log(manifest.minAppVersion); // e.g., '1.0.0' console.log(manifest.isDesktopOnly); // e.g., false } ``` ``` -------------------------------- ### Configure VS Code for ESLint Integration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Set up VS Code to use the ESLint extension for validation, formatting, and on-save checks. This ensures consistent code style and quality directly within the editor. ```json { "eslint.validate": [ "javascript", "javascriptreact", "typescript", "typescriptreact", "json" ], "editor.defaultFormatter": "dbaeumer.vscode-eslint", "editor.formatOnSave": true } ``` ```json { "recommendations": ["dbaeumer.vscode-eslint"] } ``` -------------------------------- ### ESLint Configuration Excluding Files and Rules Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Configure ESLint to exclude specific files (like test files) from certain rules and ignore entire directories. ```javascript // eslint.config.js import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json' }, }, }, // Test files: disable some rules { files: ['**/*.test.ts', '**/*.spec.ts'], rules: { 'obsidianmd/no-console': 'off', 'obsidianmd/no-sample-code': 'off', }, }, // Ignore certain directories entirely { ignores: ['node_modules/**', 'dist/**', '.obsidian/**'], }, ]); ``` -------------------------------- ### ESLint ObsidianMD Plugin Main Export Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/INDEX.md Imports the main plugin object and shows its structure, including meta information, rules, and configurations. This is the entry point for integrating the plugin with ESLint. ```typescript import plugin from 'eslint-plugin-obsidianmd'; // Type: ESLint.Plugin plugin.meta // { name, version } plugin.rules // { [ruleId]: RuleDefinition } plugin.configs.recommended // Config[] plugin.configs.recommendedWithLocalesEn // Config[] ``` -------------------------------- ### Extended ESLint Configuration with Custom Rules Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md An extended ESLint configuration that includes the recommended settings, custom TypeScript parsing, and overrides for specific rules like sentence casing and API version checking. ```javascript // eslint.config.js import tsparser from '@typescript-eslint/parser'; import { defineConfig } from 'eslint/config'; import plugin from 'eslint-plugin-obsidianmd'; export default defineConfig([ // Use the recommended config as base ...plugin.configs.recommended, // Configure TypeScript files { files: ['**/*.ts', '**/*.tsx'], languageOptions: { parser: tsparser, parserOptions: { project: './tsconfig.json', ecmaVersion: 2020, }, }, rules: { // Override rules 'obsidianmd/sample-names': 'off', 'obsidianmd/prefer-file-manager-trash-file': 'error', // Customize sentence case behavior 'obsidianmd/ui/sentence-case': [ 'error', { brands: ['GitHub', 'Obsidian', 'OpenAI'], acronyms: ['API', 'HTTP', 'OK', 'FAQ'], enforceCamelCaseLower: false, }, ], // Customize API version checking 'obsidianmd/no-unsupported-api': [ 'error', { minAppVersion: '1.0.0' }, ], // Customize console messages 'obsidianmd/rule-custom-message': [ 'error', { 'no-console': { messages: { 'Unexpected console statement. Only these console methods are allowed: warn, error, debug.': 'Use console.warn, console.error, or console.debug for debugging.', }, options: [{ allow: ['warn', 'error', 'debug'] }], }, }, ], }, }, // Ignore test files for some rules { files: ['**/*.test.ts', '**/*.spec.ts'], rules: { 'obsidianmd/no-sample-code': 'off', }, }, ]); ``` -------------------------------- ### Fix: Use getAbstractFileByPath for file lookup Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Avoid iterating through all vault files to find a file by its path. Use the more efficient `this.app.vault.getAbstractFileByPath` method instead. ```typescript // Error: Use getAbstractFileByPath instead const file = this.app.vault.getFiles().find(f => f.path === 'notes/file.md'); ``` ```typescript const file = this.app.vault.getAbstractFileByPath('notes/file.md'); ``` -------------------------------- ### Required Fields in manifest.json Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/INDEX.md This JSON structure outlines the essential fields required for a plugin's manifest file. Ensure all listed fields are present for proper plugin integration. ```json { "id": "unique-plugin-id", "name": "Plugin Name", "version": "1.0.0", "minAppVersion": "1.0.0", "author": "Author Name", "description": "Plugin description", "isDesktopOnly": false } ``` -------------------------------- ### Schema for ui/sentence-case rule Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/rules-reference.md Defines the configuration options for the ui/sentence-case rule, including arrays for brands and acronyms to exclude, and a boolean to enforce camel case. ```json { type: 'object', properties: { brands: { type: 'array', items: { type: 'string' } }, acronyms: { type: 'array', items: { type: 'string' } }, enforceCamelCaseLower: { type: 'boolean' } } } ``` -------------------------------- ### Fix: Use sentence case for UI strings Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Ensure that UI strings, such as command names, follow sentence case conventions. This improves the consistency and readability of the user interface. ```typescript // Error: Use sentence case this.addCommand({ id: 'execute', name: 'EXECUTE COMMAND', }); ``` ```typescript this.addCommand({ id: 'execute', name: 'Execute command', }); ``` -------------------------------- ### Configure `ui/sentence-case` Rule Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/configuration.md Configure the `ui/sentence-case` rule to validate sentence casing in UI strings. Exempt specific brand names, acronyms, or enforce stricter camelCase rules. This rule applies to method arguments, `createEl()` options, and string return values. ```javascript // eslint.config.js export default defineConfig([ ...plugin.configs.recommended, { files: ['**/*.ts'], rules: { 'obsidianmd/ui/sentence-case': [ 'error', { brands: ['GitHub', 'Obsidian'], acronyms: ['API', 'HTTP', 'OK'], enforceCamelCaseLower: true // Reject CamelCase } ] } } ]); ``` -------------------------------- ### TypeScript Type for Rule Configuration Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/types.md Defines the structure for configuring ESLint rules, supporting simple on/off states, warnings with options, or full configuration objects. ```typescript type RulesConfig = Record ``` ```typescript 'rule-id': 'off' | 'warn' | 'error' ``` ```typescript 'rule-id': ['warn', { option: value }] ``` ```typescript 'rule-id': { level: 'off' | 'warn' | 'error', options: [{ option: value }] } ``` -------------------------------- ### Update and Lint Plugin Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/integration-guide.md Update the eslint-plugin-obsidianmd and run lint to check for new rule violations. New rules in the recommended config will become active. ```bash npm update eslint-plugin-obsidianmd npm run lint ``` -------------------------------- ### Global This Reference Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/errors-and-messages.md Rule to disallow references to 'global' or 'globalThis'. Use 'window' or 'activeWindow' for popout window compatibility. ```javascript messageId: 'noGlobalThis', message: "Use 'window' or 'activeWindow' instead of '{{name}}' for popout window compatibility." ``` -------------------------------- ### Sample Code Removal Source: https://github.com/obsidianmd/eslint-plugin/blob/master/_autodocs/errors-and-messages.md Rule to ensure sample code is removed from the plugin template. This includes comments and sample command/event handler patterns. ```javascript messageId: 'removeSampleCode', message: "Remove sample code from the plugin template." ```