linthis 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {linthis-0.2.0 → linthis-0.2.1}/Cargo.lock +1 -1
- {linthis-0.2.0 → linthis-0.2.1}/Cargo.toml +1 -1
- {linthis-0.2.0 → linthis-0.2.1}/PKG-INFO +1 -1
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisStreamConnectionProvider.kt +17 -2
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/actions/LinthisFormatAction.kt +1 -1
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/listeners/LinthisDocumentListener.kt +1 -1
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/settings/LinthisSettings.kt +5 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/settings/LinthisSettingsConfigurable.kt +14 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/util/LinthisExecutor.kt +19 -6
- {linthis-0.2.0 → linthis-0.2.1}/pyproject.toml +1 -1
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/python.rs +5 -1
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/commands.rs +18 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/main.rs +109 -18
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/fetcher.rs +60 -4
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/mod.rs +54 -1
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/.vscodeignore +2 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/package.json +6 -17
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/extension.ts +113 -60
- {linthis-0.2.0 → linthis-0.2.1}/.github/workflows/release.yml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/.gitignore +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/.readthedocs.yaml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/CHANGELOG.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/README.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/defaults/.clang-tidy +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/defaults/config.toml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/dev.sh +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/assets/README.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/assets/favicon.svg +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/assets/logo.svg +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/assets/preview.html +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/config-cli-design.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/development/changelog.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/development/changelog.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/development/contributing.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/development/contributing.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/development/roadmap.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/development/roadmap.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/editors/vscode.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/editors/vscode.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/auto-sync.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/auto-sync.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/git-hooks.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/git-hooks.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/plugins.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/plugins.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/self-update.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/self-update.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/watch-mode.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/features/watch-mode.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/configuration.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/configuration.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/installation.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/installation.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/quickstart.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/quickstart.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/index.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/index.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/init-hooks-design.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/cpp.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/cpp.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/csharp.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/csharp.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/dart.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/dart.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/go.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/go.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/index.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/index.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/java.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/java.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/javascript.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/javascript.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/kotlin.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/kotlin.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/lua.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/lua.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/objc.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/objc.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/php.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/php.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/python.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/python.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/ruby.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/ruby.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/rust.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/rust.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/scala.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/scala.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/shell.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/shell.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/swift.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/swift.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/typescript.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/languages/typescript.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/plan-ruff-integration.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/reference/cli.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/reference/cli.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/reference/configuration.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/reference/configuration.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/requirements.txt +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/docs/tasks.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/.gitignore +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/PUBLISHING.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/PUBLISHING.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/README.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/build.gradle.kts +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/docs/images/settings.png +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/docs/images/tools-menu.png +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradle/wrapper/gradle-wrapper.jar +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradle/wrapper/gradle-wrapper.properties +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradle.properties +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradlew +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradlew.bat +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/settings.gradle.kts +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisLanguageClient.kt +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisLanguageServerFactory.kt +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisStartupListener.kt +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/actions/LinthisLintAction.kt +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/listeners/LinthisFileOpenListener.kt +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/META-INF/plugin.xml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/META-INF/pluginIcon.svg +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/META-INF/pluginIcon_dark.svg +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/images/settings.png +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/messages/LinthisBundle.properties +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/mkdocs.yml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/LICENSE +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/PUBLISHING.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/PUBLISHING.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/README.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/doc/linthis.txt +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/lua/linthis/config.lua +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/lua/linthis/init.lua +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/plugin/linthis.vim +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/test.sh +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/scripts/release.sh +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/ai/context.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/ai/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/ai/prompts.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/ai/provider.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/ai/suggestions.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/benchmark.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cache/hash.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cache/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cache/storage.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cache/types.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/cpp.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/csharp.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/dart.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/go.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/java.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/kotlin.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/lua.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/php.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/ruby.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/rust.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/scala.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/shell.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/swift.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/traits.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/checkers/typescript.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/cache.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/complexity.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/doctor.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/fix.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/helpers.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/hook.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/init.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/license.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/paths.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/plugin.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/recheck.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/report.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/runner.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/security.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/cli/watch.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/analyzer.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/go.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/java.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/python.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/rust.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/typescript.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/metrics.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/report.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/complexity/thresholds.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/cli.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/eslint.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/prettier.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/python.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/detect.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/eslint.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/prettier.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/python.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/validate.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/config/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/fixers/cpplint.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/fixers/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/fixers/source.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/cpp.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/csharp.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/dart.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/go.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/java.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/kotlin.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/lua.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/php.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/python.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/ruby.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/rust.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/scala.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/shell.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/swift.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/traits.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/formatters/typescript.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/interactive/ai_fix.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/interactive/editor.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/interactive/menu.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/interactive/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/interactive/nolint.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/interactive/quickfix.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/lib.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/go.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/java.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/node.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/python.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/rust.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/policy.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/report.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/scanner.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/license/spdx.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/lsp/diagnostics.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/lsp/document.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/lsp/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/lsp/server.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/auto_sync.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/cache.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/config_manager.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/loader.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/manifest.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/plugin/registry.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/presets/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/reports/consistency.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/reports/html.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/reports/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/reports/statistics.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/reports/templates.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/reports/trends.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/rules/config.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/rules/custom_checker.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/rules/filter.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/rules/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/advisories.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/go.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/java.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/node.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/python.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/rust.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/report.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/scanner.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/security/vulnerability.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/self_update.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/templates/linter_configs.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/templates/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/templates/plugin_templates.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/templates/readme.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/app.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/event.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/ui.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/file_tree.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/help.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/issue_list.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/status_bar.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/utils/language.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/utils/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/utils/output.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/utils/types.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/utils/unicode.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/utils/walker.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/watch/debounce.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/watch/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/watch/notifications.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/watch/state.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/src/watch/watcher.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/test-plugin-check/README.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/test-plugin-check/linthis-plugin.toml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/cli_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/python/bad.py +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/python/good.py +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/python/unformatted.py +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/rust/bad.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/linthis-plugin.toml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/python/ruff.toml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/rust/clippy.toml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/rust/rustfmt.toml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/us1/good.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/us1/unformatted.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/cache_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/check_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/common.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/config_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/error_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/format_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/language_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/mod.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/tests/integration/plugin_tests.rs +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/.gitignore +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/.linthis.toml +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/CHANGELOG.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/LICENSE +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/PUBLISHING.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/PUBLISHING.zh.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/README.md +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/icon.png +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/icon.svg +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/package-lock.json +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/test/runTest.ts +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/test/suite/extension.test.ts +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/test/suite/index.ts +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/tsconfig.json +0 -0
- {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/webpack.config.js +0 -0
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
package com.mojeter.linthis.plugin
|
|
8
8
|
|
|
9
9
|
import com.intellij.openapi.project.Project
|
|
10
|
+
import com.mojeter.linthis.plugin.settings.LinthisSettings
|
|
10
11
|
import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider
|
|
11
12
|
import java.io.File
|
|
12
13
|
|
|
@@ -31,8 +32,22 @@ class LinthisStreamConnectionProvider(private val project: Project) : ProcessStr
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
private fun buildCommand(): List<String> {
|
|
34
|
-
val
|
|
35
|
-
|
|
35
|
+
val settings = LinthisSettings.getInstance(project)
|
|
36
|
+
val linthisPath = if (settings.linthisPath.isNotBlank()) {
|
|
37
|
+
settings.linthisPath
|
|
38
|
+
} else {
|
|
39
|
+
findLinthisExecutable()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
val commands = mutableListOf(linthisPath, "lsp")
|
|
43
|
+
|
|
44
|
+
// Add --use-plugin if configured
|
|
45
|
+
if (settings.usePlugin.isNotBlank()) {
|
|
46
|
+
commands.add("--use-plugin")
|
|
47
|
+
commands.add(settings.usePlugin)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return commands
|
|
36
51
|
}
|
|
37
52
|
|
|
38
53
|
/**
|
|
@@ -49,7 +49,7 @@ class LinthisFormatAction : AnAction(), DumbAware {
|
|
|
49
49
|
// Run linthis format
|
|
50
50
|
ApplicationManager.getApplication().executeOnPooledThread {
|
|
51
51
|
LOG.warn("Running format on file: ${file.path}")
|
|
52
|
-
val result = LinthisExecutor.format(file.path, project.basePath, settings.linthisPath)
|
|
52
|
+
val result = LinthisExecutor.format(file.path, project.basePath, settings.linthisPath, settings.usePlugin)
|
|
53
53
|
|
|
54
54
|
ApplicationManager.getApplication().invokeLater {
|
|
55
55
|
if (result.success) {
|
|
@@ -81,7 +81,7 @@ class LinthisDocumentListener : FileDocumentManagerListener {
|
|
|
81
81
|
LOG.warn("Running format on save for: ${file.path}")
|
|
82
82
|
|
|
83
83
|
// Format the file in-place (file is already saved to disk)
|
|
84
|
-
val result = LinthisExecutor.format(file.path, project.basePath, settings.linthisPath)
|
|
84
|
+
val result = LinthisExecutor.format(file.path, project.basePath, settings.linthisPath, settings.usePlugin)
|
|
85
85
|
|
|
86
86
|
if (result.success) {
|
|
87
87
|
LOG.warn("Format on save successful, reloading document")
|
|
@@ -28,6 +28,7 @@ class LinthisSettings : PersistentStateComponent<LinthisSettings.State> {
|
|
|
28
28
|
var lintOnSave: Boolean = true
|
|
29
29
|
var formatOnSave: Boolean = false
|
|
30
30
|
var linthisPath: String = ""
|
|
31
|
+
var usePlugin: String = ""
|
|
31
32
|
var additionalArgs: String = ""
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -53,6 +54,10 @@ class LinthisSettings : PersistentStateComponent<LinthisSettings.State> {
|
|
|
53
54
|
get() = myState.linthisPath
|
|
54
55
|
set(value) { myState.linthisPath = value }
|
|
55
56
|
|
|
57
|
+
var usePlugin: String
|
|
58
|
+
get() = myState.usePlugin
|
|
59
|
+
set(value) { myState.usePlugin = value }
|
|
60
|
+
|
|
56
61
|
var additionalArgs: String
|
|
57
62
|
get() = myState.additionalArgs
|
|
58
63
|
set(value) { myState.additionalArgs = value }
|
|
@@ -28,6 +28,7 @@ class LinthisSettingsConfigurable(private val project: Project) : Configurable {
|
|
|
28
28
|
private var lintOnSaveCheckbox: JBCheckBox? = null
|
|
29
29
|
private var formatOnSaveCheckbox: JBCheckBox? = null
|
|
30
30
|
private var linthisPathField: TextFieldWithBrowseButton? = null
|
|
31
|
+
private var usePluginField: JBTextField? = null
|
|
31
32
|
private var additionalArgsField: JBTextField? = null
|
|
32
33
|
|
|
33
34
|
override fun getDisplayName(): String = "Linthis"
|
|
@@ -47,6 +48,7 @@ class LinthisSettingsConfigurable(private val project: Project) : Configurable {
|
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
additionalArgsField = JBTextField()
|
|
51
|
+
usePluginField = JBTextField()
|
|
50
52
|
|
|
51
53
|
settingsPanel = FormBuilder.createFormBuilder()
|
|
52
54
|
.addComponent(JBLabel("<html><b>Behavior</b></html>"))
|
|
@@ -59,6 +61,14 @@ class LinthisSettingsConfigurable(private val project: Project) : Configurable {
|
|
|
59
61
|
JBLabel("Linthis path (leave empty for auto-detect):"),
|
|
60
62
|
linthisPathField!!
|
|
61
63
|
)
|
|
64
|
+
.addSeparator()
|
|
65
|
+
.addComponent(JBLabel("<html><b>Plugin</b></html>"))
|
|
66
|
+
.addLabeledComponent(
|
|
67
|
+
JBLabel("<html>Use plugin (e.g., https://github.com/zhlinh/linthis-plugin-template):</html>"),
|
|
68
|
+
usePluginField!!
|
|
69
|
+
)
|
|
70
|
+
.addSeparator()
|
|
71
|
+
.addComponent(JBLabel("<html><b>Advanced</b></html>"))
|
|
62
72
|
.addLabeledComponent(
|
|
63
73
|
JBLabel("Additional arguments:"),
|
|
64
74
|
additionalArgsField!!
|
|
@@ -75,6 +85,7 @@ class LinthisSettingsConfigurable(private val project: Project) : Configurable {
|
|
|
75
85
|
lintOnSaveCheckbox?.isSelected != settings.lintOnSave ||
|
|
76
86
|
formatOnSaveCheckbox?.isSelected != settings.formatOnSave ||
|
|
77
87
|
linthisPathField?.text != settings.linthisPath ||
|
|
88
|
+
usePluginField?.text != settings.usePlugin ||
|
|
78
89
|
additionalArgsField?.text != settings.additionalArgs
|
|
79
90
|
}
|
|
80
91
|
|
|
@@ -84,6 +95,7 @@ class LinthisSettingsConfigurable(private val project: Project) : Configurable {
|
|
|
84
95
|
settings.lintOnSave = lintOnSaveCheckbox?.isSelected ?: true
|
|
85
96
|
settings.formatOnSave = formatOnSaveCheckbox?.isSelected ?: false
|
|
86
97
|
settings.linthisPath = linthisPathField?.text ?: ""
|
|
98
|
+
settings.usePlugin = usePluginField?.text ?: ""
|
|
87
99
|
settings.additionalArgs = additionalArgsField?.text ?: ""
|
|
88
100
|
}
|
|
89
101
|
|
|
@@ -93,6 +105,7 @@ class LinthisSettingsConfigurable(private val project: Project) : Configurable {
|
|
|
93
105
|
lintOnSaveCheckbox?.isSelected = settings.lintOnSave
|
|
94
106
|
formatOnSaveCheckbox?.isSelected = settings.formatOnSave
|
|
95
107
|
linthisPathField?.text = settings.linthisPath
|
|
108
|
+
usePluginField?.text = settings.usePlugin
|
|
96
109
|
additionalArgsField?.text = settings.additionalArgs
|
|
97
110
|
}
|
|
98
111
|
|
|
@@ -102,6 +115,7 @@ class LinthisSettingsConfigurable(private val project: Project) : Configurable {
|
|
|
102
115
|
lintOnSaveCheckbox = null
|
|
103
116
|
formatOnSaveCheckbox = null
|
|
104
117
|
linthisPathField = null
|
|
118
|
+
usePluginField = null
|
|
105
119
|
additionalArgsField = null
|
|
106
120
|
}
|
|
107
121
|
}
|
|
@@ -36,19 +36,25 @@ object LinthisExecutor {
|
|
|
36
36
|
* @param filePath Path to the file to format
|
|
37
37
|
* @param workingDir Working directory for the command
|
|
38
38
|
* @param customLinthisPath Custom path to linthis executable (empty for auto-detect)
|
|
39
|
+
* @param usePlugin Plugin URL to use (empty for none)
|
|
39
40
|
* @return ExecutionResult with success status and any error messages
|
|
40
41
|
*/
|
|
41
|
-
fun format(filePath: String, workingDir: String?, customLinthisPath: String?): ExecutionResult {
|
|
42
|
+
fun format(filePath: String, workingDir: String?, customLinthisPath: String?, usePlugin: String? = null): ExecutionResult {
|
|
42
43
|
val linthisPath = if (customLinthisPath.isNullOrBlank()) {
|
|
43
44
|
findLinthisExecutable()
|
|
44
45
|
} else {
|
|
45
46
|
customLinthisPath
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
LOG.warn("Format file: $filePath, linthisPath: $linthisPath, workingDir: $workingDir")
|
|
49
|
+
LOG.warn("Format file: $filePath, linthisPath: $linthisPath, workingDir: $workingDir, usePlugin: $usePlugin")
|
|
49
50
|
|
|
50
51
|
return try {
|
|
51
|
-
val
|
|
52
|
+
val commands = mutableListOf(linthisPath, "-f", "-i", filePath)
|
|
53
|
+
if (!usePlugin.isNullOrBlank()) {
|
|
54
|
+
commands.add("--use-plugin")
|
|
55
|
+
commands.add(usePlugin)
|
|
56
|
+
}
|
|
57
|
+
val processBuilder = ProcessBuilder(commands)
|
|
52
58
|
|
|
53
59
|
if (workingDir != null) {
|
|
54
60
|
processBuilder.directory(File(workingDir))
|
|
@@ -101,13 +107,15 @@ object LinthisExecutor {
|
|
|
101
107
|
* @param originalFilePath Original file path (used to determine file extension)
|
|
102
108
|
* @param workingDir Working directory for the command
|
|
103
109
|
* @param customLinthisPath Custom path to linthis executable
|
|
110
|
+
* @param usePlugin Plugin URL to use (empty for none)
|
|
104
111
|
* @return FormatResult with formatted content or error message
|
|
105
112
|
*/
|
|
106
113
|
fun formatContent(
|
|
107
114
|
content: String,
|
|
108
115
|
originalFilePath: String,
|
|
109
116
|
workingDir: String?,
|
|
110
|
-
customLinthisPath: String
|
|
117
|
+
customLinthisPath: String?,
|
|
118
|
+
usePlugin: String? = null
|
|
111
119
|
): FormatResult {
|
|
112
120
|
val linthisPath = if (customLinthisPath.isNullOrBlank()) {
|
|
113
121
|
findLinthisExecutable()
|
|
@@ -119,14 +127,19 @@ object LinthisExecutor {
|
|
|
119
127
|
val extension = originalFilePath.substringAfterLast('.', "")
|
|
120
128
|
val tempFile = File.createTempFile("linthis_format_", if (extension.isNotEmpty()) ".$extension" else "")
|
|
121
129
|
|
|
122
|
-
LOG.info("FormatContent: originalPath=$originalFilePath, linthisPath=$linthisPath, tempFile=${tempFile.absolutePath}")
|
|
130
|
+
LOG.info("FormatContent: originalPath=$originalFilePath, linthisPath=$linthisPath, tempFile=${tempFile.absolutePath}, usePlugin=$usePlugin")
|
|
123
131
|
|
|
124
132
|
return try {
|
|
125
133
|
// Write content to temp file
|
|
126
134
|
tempFile.writeText(content)
|
|
127
135
|
LOG.info("FormatContent: wrote ${content.length} chars to temp file")
|
|
128
136
|
|
|
129
|
-
val
|
|
137
|
+
val commands = mutableListOf(linthisPath, "-f", "-i", tempFile.absolutePath)
|
|
138
|
+
if (!usePlugin.isNullOrBlank()) {
|
|
139
|
+
commands.add("--use-plugin")
|
|
140
|
+
commands.add(usePlugin)
|
|
141
|
+
}
|
|
142
|
+
val processBuilder = ProcessBuilder(commands)
|
|
130
143
|
|
|
131
144
|
if (workingDir != null) {
|
|
132
145
|
processBuilder.directory(File(workingDir))
|
|
@@ -198,6 +198,9 @@ impl Checker for PythonChecker {
|
|
|
198
198
|
// Try to find ruff config
|
|
199
199
|
if let Some(config_path) = Self::find_ruff_config(path) {
|
|
200
200
|
cmd.arg("--config").arg(&config_path);
|
|
201
|
+
} else {
|
|
202
|
+
// No config found - use sensible defaults (E=pycodestyle errors, W=warnings, F=pyflakes)
|
|
203
|
+
cmd.args(["--select", "E,W,F"]);
|
|
201
204
|
}
|
|
202
205
|
|
|
203
206
|
let output = cmd
|
|
@@ -212,7 +215,8 @@ impl Checker for PythonChecker {
|
|
|
212
215
|
if output.status.code() == Some(2) && stdout.is_empty() && stderr.contains("Failed to parse") {
|
|
213
216
|
let mut retry_cmd = Command::new("ruff");
|
|
214
217
|
retry_cmd.args(["check", "--output-format", "json"]);
|
|
215
|
-
//
|
|
218
|
+
// Use default rules instead of broken config
|
|
219
|
+
retry_cmd.args(["--select", "E,W,F"]);
|
|
216
220
|
let retry_output = retry_cmd
|
|
217
221
|
.arg(path)
|
|
218
222
|
.output()
|
|
@@ -122,6 +122,17 @@ pub struct Cli {
|
|
|
122
122
|
#[arg(long)]
|
|
123
123
|
pub no_plugin: bool,
|
|
124
124
|
|
|
125
|
+
/// Use specific plugin(s) directly, bypassing config files
|
|
126
|
+
/// Useful for debugging plugins or CI integration
|
|
127
|
+
///
|
|
128
|
+
/// Formats:
|
|
129
|
+
/// --use-plugin https://github.com/org/plugin.git
|
|
130
|
+
/// --use-plugin https://github.com/org/plugin.git@v1.0
|
|
131
|
+
/// --use-plugin /path/to/local/plugin
|
|
132
|
+
/// --use-plugin plugin1,plugin2 (comma-separated)
|
|
133
|
+
#[arg(long, value_delimiter = ',')]
|
|
134
|
+
pub use_plugin: Option<Vec<String>>,
|
|
135
|
+
|
|
125
136
|
/// Hook mode: enable compact output format for git hooks
|
|
126
137
|
/// Shows summary at top, lists errors with file:line, and provides fix commands
|
|
127
138
|
/// Optional value specifies hook type: pre-commit (default), pre-push, commit-msg
|
|
@@ -387,6 +398,7 @@ pub enum Commands {
|
|
|
387
398
|
/// Example usage:
|
|
388
399
|
/// linthis lsp # Start in stdio mode (default)
|
|
389
400
|
/// linthis lsp --mode tcp # Start in TCP mode on port 9257
|
|
401
|
+
/// linthis lsp --use-plugin https://github.com/org/plugin.git
|
|
390
402
|
Lsp {
|
|
391
403
|
/// Communication mode: stdio (default) or tcp
|
|
392
404
|
#[arg(long, default_value = "stdio")]
|
|
@@ -395,6 +407,12 @@ pub enum Commands {
|
|
|
395
407
|
/// TCP port (only used when mode is tcp)
|
|
396
408
|
#[arg(long, default_value = "9257")]
|
|
397
409
|
port: u16,
|
|
410
|
+
|
|
411
|
+
/// Use specific plugin(s) directly, bypassing config files
|
|
412
|
+
///
|
|
413
|
+
/// Example: --use-plugin https://github.com/zhlinh/linthis-plugin-template
|
|
414
|
+
#[arg(long, value_delimiter = ',')]
|
|
415
|
+
use_plugin: Option<Vec<String>>,
|
|
398
416
|
},
|
|
399
417
|
/// Generate reports and analyze lint results
|
|
400
418
|
///
|
|
@@ -176,7 +176,60 @@ fn main() -> ExitCode {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
// Handle lsp subcommand
|
|
179
|
-
if let Some(Commands::Lsp { mode, port }) = cli.command {
|
|
179
|
+
if let Some(Commands::Lsp { mode, port, use_plugin }) = cli.command {
|
|
180
|
+
// Load plugins before starting LSP (same logic as main command)
|
|
181
|
+
if let Some(ref plugin_specs) = use_plugin {
|
|
182
|
+
use linthis::plugin::{PluginLoader, PluginSource};
|
|
183
|
+
|
|
184
|
+
for spec in plugin_specs {
|
|
185
|
+
// Parse plugin spec: URL[@ref] or local path
|
|
186
|
+
let (url_or_path, git_ref) = if spec.contains('@') && !spec.starts_with('/') {
|
|
187
|
+
let parts: Vec<&str> = spec.rsplitn(2, '@').collect();
|
|
188
|
+
if parts.len() == 2 {
|
|
189
|
+
(parts[1].to_string(), Some(parts[0].to_string()))
|
|
190
|
+
} else {
|
|
191
|
+
(spec.clone(), None)
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
(spec.clone(), None)
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
let name = url_or_path
|
|
198
|
+
.rsplit('/')
|
|
199
|
+
.next()
|
|
200
|
+
.unwrap_or(&url_or_path)
|
|
201
|
+
.trim_end_matches(".git")
|
|
202
|
+
.to_string();
|
|
203
|
+
|
|
204
|
+
let source = if let Some(ref r) = git_ref {
|
|
205
|
+
PluginSource::new(&url_or_path).with_ref(r)
|
|
206
|
+
} else {
|
|
207
|
+
PluginSource::new(&url_or_path)
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
if let Ok(loader) = PluginLoader::new() {
|
|
211
|
+
if let Ok(configs) = loader.load_configs(&[source], false) {
|
|
212
|
+
// Copy plugin configs to .linthis/configs/
|
|
213
|
+
let linthis_dir = std::env::current_dir()
|
|
214
|
+
.unwrap_or_default()
|
|
215
|
+
.join(".linthis");
|
|
216
|
+
let config_dir = linthis_dir.join("configs");
|
|
217
|
+
|
|
218
|
+
for config in &configs {
|
|
219
|
+
if let Some(filename) = config.config_path.file_name() {
|
|
220
|
+
let lang_dir = config_dir.join(&config.language);
|
|
221
|
+
if std::fs::create_dir_all(&lang_dir).is_ok() {
|
|
222
|
+
let target = lang_dir.join(filename);
|
|
223
|
+
let _ = std::fs::copy(&config.config_path, &target);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
eprintln!("[lsp] Loaded {} config(s) from plugin '{}'", configs.len(), name);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
180
233
|
let lsp_mode = match mode.parse::<LspMode>() {
|
|
181
234
|
Ok(m) => m,
|
|
182
235
|
Err(e) => {
|
|
@@ -285,31 +338,53 @@ fn main() -> ExitCode {
|
|
|
285
338
|
// Track loaded plugins for display
|
|
286
339
|
let mut loaded_plugins: Vec<String> = Vec::new();
|
|
287
340
|
|
|
288
|
-
// Load plugins
|
|
341
|
+
// Load plugins: --use-plugin takes priority, then config files
|
|
289
342
|
if !cli.no_plugin {
|
|
290
343
|
use linthis::plugin::{PluginConfigManager, PluginLoader, PluginSource};
|
|
291
344
|
|
|
292
345
|
let mut plugins_to_load: Vec<(String, PluginSource)> = Vec::new();
|
|
293
346
|
|
|
294
|
-
// Check
|
|
295
|
-
if let
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
347
|
+
// Check --use-plugin first (takes priority over config files)
|
|
348
|
+
if let Some(ref plugin_specs) = cli.use_plugin {
|
|
349
|
+
for spec in plugin_specs {
|
|
350
|
+
// Parse plugin spec: URL[@ref] or local path
|
|
351
|
+
let (url_or_path, git_ref) = if spec.contains('@') && !spec.starts_with('/') {
|
|
352
|
+
// URL with ref: https://github.com/org/plugin.git@v1.0
|
|
353
|
+
let parts: Vec<&str> = spec.rsplitn(2, '@').collect();
|
|
354
|
+
if parts.len() == 2 {
|
|
355
|
+
(parts[1].to_string(), Some(parts[0].to_string()))
|
|
300
356
|
} else {
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
|
|
357
|
+
(spec.clone(), None)
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
(spec.clone(), None)
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// Generate plugin name from URL/path
|
|
364
|
+
let name = url_or_path
|
|
365
|
+
.rsplit('/')
|
|
366
|
+
.next()
|
|
367
|
+
.unwrap_or(&url_or_path)
|
|
368
|
+
.trim_end_matches(".git")
|
|
369
|
+
.to_string();
|
|
370
|
+
|
|
371
|
+
let source = if let Some(ref r) = git_ref {
|
|
372
|
+
PluginSource::new(&url_or_path).with_ref(r)
|
|
373
|
+
} else {
|
|
374
|
+
PluginSource::new(&url_or_path)
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
if cli.verbose {
|
|
378
|
+
eprintln!("Using plugin from CLI: {} ({})", name, url_or_path);
|
|
304
379
|
}
|
|
380
|
+
plugins_to_load.push((name, source));
|
|
305
381
|
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
for (name, url, git_ref) in global_plugins {
|
|
382
|
+
} else {
|
|
383
|
+
// No --use-plugin, load from config files (project first, then global)
|
|
384
|
+
// Check project config first
|
|
385
|
+
if let Ok(project_manager) = PluginConfigManager::project() {
|
|
386
|
+
if let Ok(project_plugins) = project_manager.list_plugins() {
|
|
387
|
+
for (name, url, git_ref) in project_plugins {
|
|
313
388
|
let source = if let Some(ref r) = git_ref {
|
|
314
389
|
PluginSource::new(&url).with_ref(r)
|
|
315
390
|
} else {
|
|
@@ -319,6 +394,22 @@ fn main() -> ExitCode {
|
|
|
319
394
|
}
|
|
320
395
|
}
|
|
321
396
|
}
|
|
397
|
+
|
|
398
|
+
// If no project plugins, check global config
|
|
399
|
+
if plugins_to_load.is_empty() {
|
|
400
|
+
if let Ok(global_manager) = PluginConfigManager::global() {
|
|
401
|
+
if let Ok(global_plugins) = global_manager.list_plugins() {
|
|
402
|
+
for (name, url, git_ref) in global_plugins {
|
|
403
|
+
let source = if let Some(ref r) = git_ref {
|
|
404
|
+
PluginSource::new(&url).with_ref(r)
|
|
405
|
+
} else {
|
|
406
|
+
PluginSource::new(&url)
|
|
407
|
+
};
|
|
408
|
+
plugins_to_load.push((name, source));
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
322
413
|
}
|
|
323
414
|
|
|
324
415
|
if !plugins_to_load.is_empty() {
|
|
@@ -55,18 +55,16 @@ impl PluginFetcher {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
/// Fetch a plugin from Git repository
|
|
58
|
+
/// Fetch a plugin from Git repository or use local path
|
|
59
59
|
///
|
|
60
60
|
/// If already cached, returns the cached version unless force_update is true.
|
|
61
|
+
/// For local paths, directly uses the path without cloning.
|
|
61
62
|
pub fn fetch(
|
|
62
63
|
&self,
|
|
63
64
|
source: &PluginSource,
|
|
64
65
|
cache: &PluginCache,
|
|
65
66
|
force_update: bool,
|
|
66
67
|
) -> Result<CachedPlugin> {
|
|
67
|
-
// Check Git availability first
|
|
68
|
-
Self::check_git_available()?;
|
|
69
|
-
|
|
70
68
|
let url = source
|
|
71
69
|
.url
|
|
72
70
|
.as_ref()
|
|
@@ -75,6 +73,14 @@ impl PluginFetcher {
|
|
|
75
73
|
message: "No URL provided for plugin".to_string(),
|
|
76
74
|
})?;
|
|
77
75
|
|
|
76
|
+
// Check if this is a local path
|
|
77
|
+
if source.is_local_path() {
|
|
78
|
+
return self.fetch_local(source, url);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Check Git availability first (only needed for remote URLs)
|
|
82
|
+
Self::check_git_available()?;
|
|
83
|
+
|
|
78
84
|
let cache_path = cache.url_to_cache_path(url);
|
|
79
85
|
|
|
80
86
|
// Check if already cached
|
|
@@ -114,6 +120,56 @@ impl PluginFetcher {
|
|
|
114
120
|
Ok(plugin)
|
|
115
121
|
}
|
|
116
122
|
|
|
123
|
+
/// Fetch a plugin from a local path (no cloning needed)
|
|
124
|
+
fn fetch_local(&self, source: &PluginSource, path: &str) -> Result<CachedPlugin> {
|
|
125
|
+
// Resolve the path (handle relative paths)
|
|
126
|
+
let local_path = std::path::PathBuf::from(path);
|
|
127
|
+
let resolved_path = if local_path.is_relative() {
|
|
128
|
+
std::env::current_dir()
|
|
129
|
+
.map_err(|e| PluginError::CacheError {
|
|
130
|
+
message: format!("Failed to get current directory: {}", e),
|
|
131
|
+
})?
|
|
132
|
+
.join(&local_path)
|
|
133
|
+
} else {
|
|
134
|
+
local_path
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// Canonicalize to get absolute path
|
|
138
|
+
let canonical_path =
|
|
139
|
+
std::fs::canonicalize(&resolved_path).map_err(|e| PluginError::CacheError {
|
|
140
|
+
message: format!("Local plugin path '{}' not found: {}", path, e),
|
|
141
|
+
})?;
|
|
142
|
+
|
|
143
|
+
// Check if manifest exists
|
|
144
|
+
let manifest_path = canonical_path.join("linthis-plugin.toml");
|
|
145
|
+
if !manifest_path.exists() {
|
|
146
|
+
return Err(PluginError::InvalidManifest {
|
|
147
|
+
path: manifest_path,
|
|
148
|
+
message: "linthis-plugin.toml not found in local plugin directory".to_string(),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
log_plugin_operation(
|
|
153
|
+
"local",
|
|
154
|
+
&format!("Using local plugin at {}", canonical_path.display()),
|
|
155
|
+
self.verbose,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// Get commit hash if it's a git repo
|
|
159
|
+
let commit_hash = self.get_local_commit_hash(&canonical_path);
|
|
160
|
+
|
|
161
|
+
let now = Utc::now();
|
|
162
|
+
Ok(CachedPlugin {
|
|
163
|
+
name: source.name.clone(),
|
|
164
|
+
url: path.to_string(),
|
|
165
|
+
git_ref: source.git_ref.clone(),
|
|
166
|
+
commit_hash,
|
|
167
|
+
cached_at: now,
|
|
168
|
+
last_updated: now,
|
|
169
|
+
cache_path: canonical_path,
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
|
|
117
173
|
/// Clone a plugin repository with shallow clone
|
|
118
174
|
fn clone_plugin(&self, url: &str, target_path: &Path, git_ref: Option<&str>) -> Result<()> {
|
|
119
175
|
// Ensure parent directory exists
|
|
@@ -168,7 +168,7 @@ pub struct PluginSource {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
impl PluginSource {
|
|
171
|
-
/// Create a new plugin source from a name (registry lookup) or
|
|
171
|
+
/// Create a new plugin source from a name (registry lookup), URL, or local path
|
|
172
172
|
pub fn new(name_or_url: &str) -> Self {
|
|
173
173
|
if name_or_url.contains("://") || name_or_url.starts_with("git@") {
|
|
174
174
|
// It's a URL
|
|
@@ -178,6 +178,17 @@ impl PluginSource {
|
|
|
178
178
|
git_ref: None,
|
|
179
179
|
enabled: true,
|
|
180
180
|
}
|
|
181
|
+
} else if name_or_url.starts_with('/')
|
|
182
|
+
|| name_or_url.starts_with("./")
|
|
183
|
+
|| name_or_url.starts_with("../")
|
|
184
|
+
{
|
|
185
|
+
// It's a local path
|
|
186
|
+
Self {
|
|
187
|
+
name: Self::name_from_url(name_or_url),
|
|
188
|
+
url: Some(name_or_url.to_string()),
|
|
189
|
+
git_ref: None,
|
|
190
|
+
enabled: true,
|
|
191
|
+
}
|
|
181
192
|
} else {
|
|
182
193
|
// It's a registry name
|
|
183
194
|
Self {
|
|
@@ -189,6 +200,15 @@ impl PluginSource {
|
|
|
189
200
|
}
|
|
190
201
|
}
|
|
191
202
|
|
|
203
|
+
/// Check if this is a local path source
|
|
204
|
+
pub fn is_local_path(&self) -> bool {
|
|
205
|
+
if let Some(ref url) = self.url {
|
|
206
|
+
url.starts_with('/') || url.starts_with("./") || url.starts_with("../")
|
|
207
|
+
} else {
|
|
208
|
+
false
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
192
212
|
/// Extract a short name from a URL
|
|
193
213
|
fn name_from_url(url: &str) -> String {
|
|
194
214
|
url.trim_end_matches(".git")
|
|
@@ -268,6 +288,39 @@ mod tests {
|
|
|
268
288
|
);
|
|
269
289
|
}
|
|
270
290
|
|
|
291
|
+
#[test]
|
|
292
|
+
fn test_plugin_source_new_from_local_path_absolute() {
|
|
293
|
+
let source = PluginSource::new("/path/to/local/plugin");
|
|
294
|
+
assert_eq!(source.name, "plugin");
|
|
295
|
+
assert_eq!(source.url, Some("/path/to/local/plugin".to_string()));
|
|
296
|
+
assert!(source.is_local_path());
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
#[test]
|
|
300
|
+
fn test_plugin_source_new_from_local_path_relative() {
|
|
301
|
+
let source = PluginSource::new("./my-plugin");
|
|
302
|
+
assert_eq!(source.name, "my-plugin");
|
|
303
|
+
assert_eq!(source.url, Some("./my-plugin".to_string()));
|
|
304
|
+
assert!(source.is_local_path());
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
#[test]
|
|
308
|
+
fn test_plugin_source_new_from_local_path_parent() {
|
|
309
|
+
let source = PluginSource::new("../parent-plugin");
|
|
310
|
+
assert_eq!(source.name, "parent-plugin");
|
|
311
|
+
assert_eq!(source.url, Some("../parent-plugin".to_string()));
|
|
312
|
+
assert!(source.is_local_path());
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
#[test]
|
|
316
|
+
fn test_plugin_source_is_not_local_path() {
|
|
317
|
+
let source = PluginSource::new("https://github.com/org/plugin.git");
|
|
318
|
+
assert!(!source.is_local_path());
|
|
319
|
+
|
|
320
|
+
let source2 = PluginSource::new("official");
|
|
321
|
+
assert!(!source2.is_local_path());
|
|
322
|
+
}
|
|
323
|
+
|
|
271
324
|
// ==================== PluginSource::with_ref tests ====================
|
|
272
325
|
|
|
273
326
|
#[test]
|