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.
Files changed (333) hide show
  1. {linthis-0.2.0 → linthis-0.2.1}/Cargo.lock +1 -1
  2. {linthis-0.2.0 → linthis-0.2.1}/Cargo.toml +1 -1
  3. {linthis-0.2.0 → linthis-0.2.1}/PKG-INFO +1 -1
  4. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisStreamConnectionProvider.kt +17 -2
  5. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/actions/LinthisFormatAction.kt +1 -1
  6. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/listeners/LinthisDocumentListener.kt +1 -1
  7. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/settings/LinthisSettings.kt +5 -0
  8. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/settings/LinthisSettingsConfigurable.kt +14 -0
  9. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/util/LinthisExecutor.kt +19 -6
  10. {linthis-0.2.0 → linthis-0.2.1}/pyproject.toml +1 -1
  11. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/python.rs +5 -1
  12. {linthis-0.2.0 → linthis-0.2.1}/src/cli/commands.rs +18 -0
  13. {linthis-0.2.0 → linthis-0.2.1}/src/main.rs +109 -18
  14. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/fetcher.rs +60 -4
  15. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/mod.rs +54 -1
  16. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/.vscodeignore +2 -0
  17. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/package.json +6 -17
  18. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/extension.ts +113 -60
  19. {linthis-0.2.0 → linthis-0.2.1}/.github/workflows/release.yml +0 -0
  20. {linthis-0.2.0 → linthis-0.2.1}/.gitignore +0 -0
  21. {linthis-0.2.0 → linthis-0.2.1}/.readthedocs.yaml +0 -0
  22. {linthis-0.2.0 → linthis-0.2.1}/CHANGELOG.md +0 -0
  23. {linthis-0.2.0 → linthis-0.2.1}/README.md +0 -0
  24. {linthis-0.2.0 → linthis-0.2.1}/defaults/.clang-tidy +0 -0
  25. {linthis-0.2.0 → linthis-0.2.1}/defaults/config.toml +0 -0
  26. {linthis-0.2.0 → linthis-0.2.1}/dev.sh +0 -0
  27. {linthis-0.2.0 → linthis-0.2.1}/docs/assets/README.md +0 -0
  28. {linthis-0.2.0 → linthis-0.2.1}/docs/assets/favicon.svg +0 -0
  29. {linthis-0.2.0 → linthis-0.2.1}/docs/assets/logo.svg +0 -0
  30. {linthis-0.2.0 → linthis-0.2.1}/docs/assets/preview.html +0 -0
  31. {linthis-0.2.0 → linthis-0.2.1}/docs/config-cli-design.md +0 -0
  32. {linthis-0.2.0 → linthis-0.2.1}/docs/development/changelog.md +0 -0
  33. {linthis-0.2.0 → linthis-0.2.1}/docs/development/changelog.zh.md +0 -0
  34. {linthis-0.2.0 → linthis-0.2.1}/docs/development/contributing.md +0 -0
  35. {linthis-0.2.0 → linthis-0.2.1}/docs/development/contributing.zh.md +0 -0
  36. {linthis-0.2.0 → linthis-0.2.1}/docs/development/roadmap.md +0 -0
  37. {linthis-0.2.0 → linthis-0.2.1}/docs/development/roadmap.zh.md +0 -0
  38. {linthis-0.2.0 → linthis-0.2.1}/docs/editors/vscode.md +0 -0
  39. {linthis-0.2.0 → linthis-0.2.1}/docs/editors/vscode.zh.md +0 -0
  40. {linthis-0.2.0 → linthis-0.2.1}/docs/features/auto-sync.md +0 -0
  41. {linthis-0.2.0 → linthis-0.2.1}/docs/features/auto-sync.zh.md +0 -0
  42. {linthis-0.2.0 → linthis-0.2.1}/docs/features/git-hooks.md +0 -0
  43. {linthis-0.2.0 → linthis-0.2.1}/docs/features/git-hooks.zh.md +0 -0
  44. {linthis-0.2.0 → linthis-0.2.1}/docs/features/plugins.md +0 -0
  45. {linthis-0.2.0 → linthis-0.2.1}/docs/features/plugins.zh.md +0 -0
  46. {linthis-0.2.0 → linthis-0.2.1}/docs/features/self-update.md +0 -0
  47. {linthis-0.2.0 → linthis-0.2.1}/docs/features/self-update.zh.md +0 -0
  48. {linthis-0.2.0 → linthis-0.2.1}/docs/features/watch-mode.md +0 -0
  49. {linthis-0.2.0 → linthis-0.2.1}/docs/features/watch-mode.zh.md +0 -0
  50. {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/configuration.md +0 -0
  51. {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/configuration.zh.md +0 -0
  52. {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/installation.md +0 -0
  53. {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/installation.zh.md +0 -0
  54. {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/quickstart.md +0 -0
  55. {linthis-0.2.0 → linthis-0.2.1}/docs/getting-started/quickstart.zh.md +0 -0
  56. {linthis-0.2.0 → linthis-0.2.1}/docs/index.md +0 -0
  57. {linthis-0.2.0 → linthis-0.2.1}/docs/index.zh.md +0 -0
  58. {linthis-0.2.0 → linthis-0.2.1}/docs/init-hooks-design.md +0 -0
  59. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/cpp.md +0 -0
  60. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/cpp.zh.md +0 -0
  61. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/csharp.md +0 -0
  62. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/csharp.zh.md +0 -0
  63. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/dart.md +0 -0
  64. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/dart.zh.md +0 -0
  65. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/go.md +0 -0
  66. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/go.zh.md +0 -0
  67. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/index.md +0 -0
  68. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/index.zh.md +0 -0
  69. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/java.md +0 -0
  70. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/java.zh.md +0 -0
  71. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/javascript.md +0 -0
  72. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/javascript.zh.md +0 -0
  73. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/kotlin.md +0 -0
  74. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/kotlin.zh.md +0 -0
  75. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/lua.md +0 -0
  76. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/lua.zh.md +0 -0
  77. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/objc.md +0 -0
  78. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/objc.zh.md +0 -0
  79. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/php.md +0 -0
  80. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/php.zh.md +0 -0
  81. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/python.md +0 -0
  82. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/python.zh.md +0 -0
  83. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/ruby.md +0 -0
  84. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/ruby.zh.md +0 -0
  85. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/rust.md +0 -0
  86. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/rust.zh.md +0 -0
  87. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/scala.md +0 -0
  88. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/scala.zh.md +0 -0
  89. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/shell.md +0 -0
  90. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/shell.zh.md +0 -0
  91. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/swift.md +0 -0
  92. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/swift.zh.md +0 -0
  93. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/typescript.md +0 -0
  94. {linthis-0.2.0 → linthis-0.2.1}/docs/languages/typescript.zh.md +0 -0
  95. {linthis-0.2.0 → linthis-0.2.1}/docs/plan-ruff-integration.md +0 -0
  96. {linthis-0.2.0 → linthis-0.2.1}/docs/reference/cli.md +0 -0
  97. {linthis-0.2.0 → linthis-0.2.1}/docs/reference/cli.zh.md +0 -0
  98. {linthis-0.2.0 → linthis-0.2.1}/docs/reference/configuration.md +0 -0
  99. {linthis-0.2.0 → linthis-0.2.1}/docs/reference/configuration.zh.md +0 -0
  100. {linthis-0.2.0 → linthis-0.2.1}/docs/requirements.txt +0 -0
  101. {linthis-0.2.0 → linthis-0.2.1}/docs/tasks.md +0 -0
  102. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/.gitignore +0 -0
  103. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/PUBLISHING.md +0 -0
  104. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/PUBLISHING.zh.md +0 -0
  105. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/README.md +0 -0
  106. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/build.gradle.kts +0 -0
  107. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/docs/images/settings.png +0 -0
  108. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/docs/images/tools-menu.png +0 -0
  109. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradle/wrapper/gradle-wrapper.jar +0 -0
  110. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradle/wrapper/gradle-wrapper.properties +0 -0
  111. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradle.properties +0 -0
  112. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradlew +0 -0
  113. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/gradlew.bat +0 -0
  114. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/settings.gradle.kts +0 -0
  115. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisLanguageClient.kt +0 -0
  116. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisLanguageServerFactory.kt +0 -0
  117. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/LinthisStartupListener.kt +0 -0
  118. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/actions/LinthisLintAction.kt +0 -0
  119. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/kotlin/com/mojeter/linthis/plugin/listeners/LinthisFileOpenListener.kt +0 -0
  120. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/META-INF/plugin.xml +0 -0
  121. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/META-INF/pluginIcon.svg +0 -0
  122. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/META-INF/pluginIcon_dark.svg +0 -0
  123. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/images/settings.png +0 -0
  124. {linthis-0.2.0 → linthis-0.2.1}/jetbrains-linthis/src/main/resources/messages/LinthisBundle.properties +0 -0
  125. {linthis-0.2.0 → linthis-0.2.1}/mkdocs.yml +0 -0
  126. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/LICENSE +0 -0
  127. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/PUBLISHING.md +0 -0
  128. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/PUBLISHING.zh.md +0 -0
  129. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/README.md +0 -0
  130. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/doc/linthis.txt +0 -0
  131. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/lua/linthis/config.lua +0 -0
  132. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/lua/linthis/init.lua +0 -0
  133. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/plugin/linthis.vim +0 -0
  134. {linthis-0.2.0 → linthis-0.2.1}/nvim-linthis/test.sh +0 -0
  135. {linthis-0.2.0 → linthis-0.2.1}/scripts/release.sh +0 -0
  136. {linthis-0.2.0 → linthis-0.2.1}/src/ai/context.rs +0 -0
  137. {linthis-0.2.0 → linthis-0.2.1}/src/ai/mod.rs +0 -0
  138. {linthis-0.2.0 → linthis-0.2.1}/src/ai/prompts.rs +0 -0
  139. {linthis-0.2.0 → linthis-0.2.1}/src/ai/provider.rs +0 -0
  140. {linthis-0.2.0 → linthis-0.2.1}/src/ai/suggestions.rs +0 -0
  141. {linthis-0.2.0 → linthis-0.2.1}/src/benchmark.rs +0 -0
  142. {linthis-0.2.0 → linthis-0.2.1}/src/cache/hash.rs +0 -0
  143. {linthis-0.2.0 → linthis-0.2.1}/src/cache/mod.rs +0 -0
  144. {linthis-0.2.0 → linthis-0.2.1}/src/cache/storage.rs +0 -0
  145. {linthis-0.2.0 → linthis-0.2.1}/src/cache/types.rs +0 -0
  146. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/cpp.rs +0 -0
  147. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/csharp.rs +0 -0
  148. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/dart.rs +0 -0
  149. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/go.rs +0 -0
  150. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/java.rs +0 -0
  151. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/kotlin.rs +0 -0
  152. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/lua.rs +0 -0
  153. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/mod.rs +0 -0
  154. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/php.rs +0 -0
  155. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/ruby.rs +0 -0
  156. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/rust.rs +0 -0
  157. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/scala.rs +0 -0
  158. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/shell.rs +0 -0
  159. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/swift.rs +0 -0
  160. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/traits.rs +0 -0
  161. {linthis-0.2.0 → linthis-0.2.1}/src/checkers/typescript.rs +0 -0
  162. {linthis-0.2.0 → linthis-0.2.1}/src/cli/cache.rs +0 -0
  163. {linthis-0.2.0 → linthis-0.2.1}/src/cli/complexity.rs +0 -0
  164. {linthis-0.2.0 → linthis-0.2.1}/src/cli/doctor.rs +0 -0
  165. {linthis-0.2.0 → linthis-0.2.1}/src/cli/fix.rs +0 -0
  166. {linthis-0.2.0 → linthis-0.2.1}/src/cli/helpers.rs +0 -0
  167. {linthis-0.2.0 → linthis-0.2.1}/src/cli/hook.rs +0 -0
  168. {linthis-0.2.0 → linthis-0.2.1}/src/cli/init.rs +0 -0
  169. {linthis-0.2.0 → linthis-0.2.1}/src/cli/license.rs +0 -0
  170. {linthis-0.2.0 → linthis-0.2.1}/src/cli/mod.rs +0 -0
  171. {linthis-0.2.0 → linthis-0.2.1}/src/cli/paths.rs +0 -0
  172. {linthis-0.2.0 → linthis-0.2.1}/src/cli/plugin.rs +0 -0
  173. {linthis-0.2.0 → linthis-0.2.1}/src/cli/recheck.rs +0 -0
  174. {linthis-0.2.0 → linthis-0.2.1}/src/cli/report.rs +0 -0
  175. {linthis-0.2.0 → linthis-0.2.1}/src/cli/runner.rs +0 -0
  176. {linthis-0.2.0 → linthis-0.2.1}/src/cli/security.rs +0 -0
  177. {linthis-0.2.0 → linthis-0.2.1}/src/cli/watch.rs +0 -0
  178. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/analyzer.rs +0 -0
  179. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/go.rs +0 -0
  180. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/java.rs +0 -0
  181. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/mod.rs +0 -0
  182. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/python.rs +0 -0
  183. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/rust.rs +0 -0
  184. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/languages/typescript.rs +0 -0
  185. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/metrics.rs +0 -0
  186. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/mod.rs +0 -0
  187. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/report.rs +0 -0
  188. {linthis-0.2.0 → linthis-0.2.1}/src/complexity/thresholds.rs +0 -0
  189. {linthis-0.2.0 → linthis-0.2.1}/src/config/cli.rs +0 -0
  190. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/eslint.rs +0 -0
  191. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/mod.rs +0 -0
  192. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/prettier.rs +0 -0
  193. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/converters/python.rs +0 -0
  194. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/detect.rs +0 -0
  195. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/mod.rs +0 -0
  196. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/eslint.rs +0 -0
  197. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/mod.rs +0 -0
  198. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/prettier.rs +0 -0
  199. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/parsers/python.rs +0 -0
  200. {linthis-0.2.0 → linthis-0.2.1}/src/config/migrate/validate.rs +0 -0
  201. {linthis-0.2.0 → linthis-0.2.1}/src/config/mod.rs +0 -0
  202. {linthis-0.2.0 → linthis-0.2.1}/src/fixers/cpplint.rs +0 -0
  203. {linthis-0.2.0 → linthis-0.2.1}/src/fixers/mod.rs +0 -0
  204. {linthis-0.2.0 → linthis-0.2.1}/src/fixers/source.rs +0 -0
  205. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/cpp.rs +0 -0
  206. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/csharp.rs +0 -0
  207. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/dart.rs +0 -0
  208. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/go.rs +0 -0
  209. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/java.rs +0 -0
  210. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/kotlin.rs +0 -0
  211. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/lua.rs +0 -0
  212. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/mod.rs +0 -0
  213. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/php.rs +0 -0
  214. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/python.rs +0 -0
  215. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/ruby.rs +0 -0
  216. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/rust.rs +0 -0
  217. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/scala.rs +0 -0
  218. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/shell.rs +0 -0
  219. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/swift.rs +0 -0
  220. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/traits.rs +0 -0
  221. {linthis-0.2.0 → linthis-0.2.1}/src/formatters/typescript.rs +0 -0
  222. {linthis-0.2.0 → linthis-0.2.1}/src/interactive/ai_fix.rs +0 -0
  223. {linthis-0.2.0 → linthis-0.2.1}/src/interactive/editor.rs +0 -0
  224. {linthis-0.2.0 → linthis-0.2.1}/src/interactive/menu.rs +0 -0
  225. {linthis-0.2.0 → linthis-0.2.1}/src/interactive/mod.rs +0 -0
  226. {linthis-0.2.0 → linthis-0.2.1}/src/interactive/nolint.rs +0 -0
  227. {linthis-0.2.0 → linthis-0.2.1}/src/interactive/quickfix.rs +0 -0
  228. {linthis-0.2.0 → linthis-0.2.1}/src/lib.rs +0 -0
  229. {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/go.rs +0 -0
  230. {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/java.rs +0 -0
  231. {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/mod.rs +0 -0
  232. {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/node.rs +0 -0
  233. {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/python.rs +0 -0
  234. {linthis-0.2.0 → linthis-0.2.1}/src/license/languages/rust.rs +0 -0
  235. {linthis-0.2.0 → linthis-0.2.1}/src/license/mod.rs +0 -0
  236. {linthis-0.2.0 → linthis-0.2.1}/src/license/policy.rs +0 -0
  237. {linthis-0.2.0 → linthis-0.2.1}/src/license/report.rs +0 -0
  238. {linthis-0.2.0 → linthis-0.2.1}/src/license/scanner.rs +0 -0
  239. {linthis-0.2.0 → linthis-0.2.1}/src/license/spdx.rs +0 -0
  240. {linthis-0.2.0 → linthis-0.2.1}/src/lsp/diagnostics.rs +0 -0
  241. {linthis-0.2.0 → linthis-0.2.1}/src/lsp/document.rs +0 -0
  242. {linthis-0.2.0 → linthis-0.2.1}/src/lsp/mod.rs +0 -0
  243. {linthis-0.2.0 → linthis-0.2.1}/src/lsp/server.rs +0 -0
  244. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/auto_sync.rs +0 -0
  245. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/cache.rs +0 -0
  246. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/config_manager.rs +0 -0
  247. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/loader.rs +0 -0
  248. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/manifest.rs +0 -0
  249. {linthis-0.2.0 → linthis-0.2.1}/src/plugin/registry.rs +0 -0
  250. {linthis-0.2.0 → linthis-0.2.1}/src/presets/mod.rs +0 -0
  251. {linthis-0.2.0 → linthis-0.2.1}/src/reports/consistency.rs +0 -0
  252. {linthis-0.2.0 → linthis-0.2.1}/src/reports/html.rs +0 -0
  253. {linthis-0.2.0 → linthis-0.2.1}/src/reports/mod.rs +0 -0
  254. {linthis-0.2.0 → linthis-0.2.1}/src/reports/statistics.rs +0 -0
  255. {linthis-0.2.0 → linthis-0.2.1}/src/reports/templates.rs +0 -0
  256. {linthis-0.2.0 → linthis-0.2.1}/src/reports/trends.rs +0 -0
  257. {linthis-0.2.0 → linthis-0.2.1}/src/rules/config.rs +0 -0
  258. {linthis-0.2.0 → linthis-0.2.1}/src/rules/custom_checker.rs +0 -0
  259. {linthis-0.2.0 → linthis-0.2.1}/src/rules/filter.rs +0 -0
  260. {linthis-0.2.0 → linthis-0.2.1}/src/rules/mod.rs +0 -0
  261. {linthis-0.2.0 → linthis-0.2.1}/src/security/advisories.rs +0 -0
  262. {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/go.rs +0 -0
  263. {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/java.rs +0 -0
  264. {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/mod.rs +0 -0
  265. {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/node.rs +0 -0
  266. {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/python.rs +0 -0
  267. {linthis-0.2.0 → linthis-0.2.1}/src/security/languages/rust.rs +0 -0
  268. {linthis-0.2.0 → linthis-0.2.1}/src/security/mod.rs +0 -0
  269. {linthis-0.2.0 → linthis-0.2.1}/src/security/report.rs +0 -0
  270. {linthis-0.2.0 → linthis-0.2.1}/src/security/scanner.rs +0 -0
  271. {linthis-0.2.0 → linthis-0.2.1}/src/security/vulnerability.rs +0 -0
  272. {linthis-0.2.0 → linthis-0.2.1}/src/self_update.rs +0 -0
  273. {linthis-0.2.0 → linthis-0.2.1}/src/templates/linter_configs.rs +0 -0
  274. {linthis-0.2.0 → linthis-0.2.1}/src/templates/mod.rs +0 -0
  275. {linthis-0.2.0 → linthis-0.2.1}/src/templates/plugin_templates.rs +0 -0
  276. {linthis-0.2.0 → linthis-0.2.1}/src/templates/readme.rs +0 -0
  277. {linthis-0.2.0 → linthis-0.2.1}/src/tui/app.rs +0 -0
  278. {linthis-0.2.0 → linthis-0.2.1}/src/tui/event.rs +0 -0
  279. {linthis-0.2.0 → linthis-0.2.1}/src/tui/mod.rs +0 -0
  280. {linthis-0.2.0 → linthis-0.2.1}/src/tui/ui.rs +0 -0
  281. {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/file_tree.rs +0 -0
  282. {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/help.rs +0 -0
  283. {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/issue_list.rs +0 -0
  284. {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/mod.rs +0 -0
  285. {linthis-0.2.0 → linthis-0.2.1}/src/tui/widgets/status_bar.rs +0 -0
  286. {linthis-0.2.0 → linthis-0.2.1}/src/utils/language.rs +0 -0
  287. {linthis-0.2.0 → linthis-0.2.1}/src/utils/mod.rs +0 -0
  288. {linthis-0.2.0 → linthis-0.2.1}/src/utils/output.rs +0 -0
  289. {linthis-0.2.0 → linthis-0.2.1}/src/utils/types.rs +0 -0
  290. {linthis-0.2.0 → linthis-0.2.1}/src/utils/unicode.rs +0 -0
  291. {linthis-0.2.0 → linthis-0.2.1}/src/utils/walker.rs +0 -0
  292. {linthis-0.2.0 → linthis-0.2.1}/src/watch/debounce.rs +0 -0
  293. {linthis-0.2.0 → linthis-0.2.1}/src/watch/mod.rs +0 -0
  294. {linthis-0.2.0 → linthis-0.2.1}/src/watch/notifications.rs +0 -0
  295. {linthis-0.2.0 → linthis-0.2.1}/src/watch/state.rs +0 -0
  296. {linthis-0.2.0 → linthis-0.2.1}/src/watch/watcher.rs +0 -0
  297. {linthis-0.2.0 → linthis-0.2.1}/test-plugin-check/README.md +0 -0
  298. {linthis-0.2.0 → linthis-0.2.1}/test-plugin-check/linthis-plugin.toml +0 -0
  299. {linthis-0.2.0 → linthis-0.2.1}/tests/cli_tests.rs +0 -0
  300. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/python/bad.py +0 -0
  301. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/python/good.py +0 -0
  302. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/python/unformatted.py +0 -0
  303. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/rust/bad.rs +0 -0
  304. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/linthis-plugin.toml +0 -0
  305. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/python/ruff.toml +0 -0
  306. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/rust/clippy.toml +0 -0
  307. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/test-plugin/rust/rustfmt.toml +0 -0
  308. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/us1/good.rs +0 -0
  309. {linthis-0.2.0 → linthis-0.2.1}/tests/fixtures/us1/unformatted.rs +0 -0
  310. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/cache_tests.rs +0 -0
  311. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/check_tests.rs +0 -0
  312. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/common.rs +0 -0
  313. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/config_tests.rs +0 -0
  314. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/error_tests.rs +0 -0
  315. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/format_tests.rs +0 -0
  316. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/language_tests.rs +0 -0
  317. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/mod.rs +0 -0
  318. {linthis-0.2.0 → linthis-0.2.1}/tests/integration/plugin_tests.rs +0 -0
  319. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/.gitignore +0 -0
  320. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/.linthis.toml +0 -0
  321. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/CHANGELOG.md +0 -0
  322. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/LICENSE +0 -0
  323. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/PUBLISHING.md +0 -0
  324. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/PUBLISHING.zh.md +0 -0
  325. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/README.md +0 -0
  326. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/icon.png +0 -0
  327. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/icon.svg +0 -0
  328. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/package-lock.json +0 -0
  329. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/test/runTest.ts +0 -0
  330. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/test/suite/extension.test.ts +0 -0
  331. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/src/test/suite/index.ts +0 -0
  332. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/tsconfig.json +0 -0
  333. {linthis-0.2.0 → linthis-0.2.1}/vscode-linthis/webpack.config.js +0 -0
@@ -1330,7 +1330,7 @@ dependencies = [
1330
1330
 
1331
1331
  [[package]]
1332
1332
  name = "linthis"
1333
- version = "0.2.0"
1333
+ version = "0.2.1"
1334
1334
  dependencies = [
1335
1335
  "anyhow",
1336
1336
  "async-trait",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "linthis"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  edition = "2021"
5
5
  authors = ["zhlinh"]
6
6
  description = "A fast, cross-platform multi-language linter and formatter"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: linthis
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -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 linthisPath = findLinthisExecutable()
35
- return listOf(linthisPath, "lsp")
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 processBuilder = ProcessBuilder(linthisPath, "-f", "-i", filePath)
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 processBuilder = ProcessBuilder(linthisPath, "-f", "-i", tempFile.absolutePath)
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))
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "linthis"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "A fast, cross-platform multi-language linter and formatter"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -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
- // Don't use config - let ruff use defaults
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 from config files (project first, then global)
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 project config first
295
- if let Ok(project_manager) = PluginConfigManager::project() {
296
- if let Ok(project_plugins) = project_manager.list_plugins() {
297
- for (name, url, git_ref) in project_plugins {
298
- let source = if let Some(ref r) = git_ref {
299
- PluginSource::new(&url).with_ref(r)
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
- PluginSource::new(&url)
302
- };
303
- plugins_to_load.push((name, source));
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
- // If no project plugins, check global config
309
- if plugins_to_load.is_empty() {
310
- if let Ok(global_manager) = PluginConfigManager::global() {
311
- if let Ok(global_plugins) = global_manager.list_plugins() {
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 URL
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]
@@ -13,6 +13,8 @@ webpack.config.js
13
13
  *.vsix
14
14
  .DS_Store
15
15
  .linthis.toml
16
+ .linthis/**
17
+ .ruff_cache/**
16
18
  PUBLISHING.md
17
19
  PUBLISHING.zh.md
18
20
  !dist/**