linthis 0.5.0

A fast, cross-platform multi-language linter and formatter
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
# linthis

[![Crates.io](https://img.shields.io/crates/v/linthis.svg)](https://crates.io/crates/linthis)
[![PyPI](https://img.shields.io/pypi/v/linthis.svg)](https://pypi.org/project/linthis/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A fast, cross-platform multi-language linter and formatter written in Rust.

## Features

- 🚀 **Single Command**: Run both linting and formatting simultaneously
- 🌍 **Multi-Language Support**: Rust, Python, TypeScript, JavaScript, Go, Java, C++, Swift, Kotlin, Lua, and more
- 🎯 **Auto-Detection**: Automatically detect programming languages used in your project
- ⚙️ **Flexible Configuration**: Support for project config, global config, and CLI parameters
- 📦 **Plugin System**: Share and reuse configurations via Git repositories
- 🎨 **Format Presets**: Support for popular code styles like Google, Airbnb, Standard
-**Parallel Processing**: Leverage multi-core CPU for faster file processing

## Installation

### Method 1: Install via PyPI (Recommended for Python users)

```bash
# Using pip
pip install linthis

# Using uv (recommended)
# pip install uv
uv pip install linthis
```

### Method 2: Install via Cargo (Recommended for Rust users)

```bash
cargo install linthis
```

### Method 3: Build from Source

```bash
git clone https://github.com/zhlinh/linthis.git
cd linthis
cargo build --release
```

## Quick Start

### Initialize Configuration (Optional)

```bash
# Create project configuration file
linthis init

# Create global configuration file
linthis init -g

# Install pre-commit hooks (project-level)
linthis hook install --type prek
linthis hook install --type pre-commit
linthis hook install --type git

# Install pre-push hook
linthis hook install --type git --event pre-push

# Install commit-msg hook
linthis hook install --type git --event commit-msg

# Force overwrite existing files
linthis init --force
linthis hook install --type prek --force
```

### Basic Usage

```bash
# Check and format current directory (default behavior)
linthis

# Check and format specific directories
linthis -i src/
linthis --include src/ --include lib/

# Check only, no formatting
linthis -c
linthis --check-only

# Format only, no checking
linthis -f
linthis --format-only

# Check Git staged files (suitable for pre-commit hook)
linthis -s
linthis --staged
```

### Specify Languages

```bash
# Check specific language
linthis -l python
linthis --lang rust

# Check multiple languages
linthis -l python,rust,cpp
linthis --lang "python,javascript,go"
```

### Exclude Files

```bash
# Exclude specific patterns
linthis -e "*.test.js" -e "dist/**"
linthis --exclude "target/**" --exclude "node_modules/**"
```

## Plugin System

linthis supports Git-based configuration plugins for easy sharing of code standards across projects and teams.

### Add Plugin

```bash
# Add plugin to project config (.linthis/config.toml)
linthis plugin add <alias> <git-url>

# Example: Add a custom plugin
linthis plugin add myplugin https://github.com/zhlinh/linthis-plugin.git

# Add to global config (~/.linthis/config.toml)
linthis plugin add -g <alias> <git-url>
linthis plugin add --global <alias> <git-url>
```

### Use Plugin

Plugins are automatically loaded when running linthis. After adding a plugin:

```bash
# Plugin configs are auto-loaded
linthis

# Combine with other options
linthis -i src/
# Check only
linthis -c
# Format only
linthis -f
# Check and format files staged
linthis -s
```

### Remove Plugin

```bash
# Remove plugin from project config
linthis plugin remove <alias>
linthis plugin remove myplugin

# Remove plugin from global config
linthis plugin remove -g <alias>
linthis plugin remove --global myplugin

# Supports flexible parameter ordering
linthis plugin remove --global myplugin
```

### View and Manage Plugins

```bash
# View project config plugins
linthis plugin list

# View global config plugins
linthis plugin list -g
linthis plugin list --global

# Sync (update) plugins
linthis plugin sync          # Sync local plugins
linthis plugin sync --global # Sync global plugins

# Initialize new plugin
linthis plugin init my-config

# Validate plugin structure
linthis plugin validate /path/to/plugin

# Clean plugin cache
linthis plugin clean          # Interactive cleanup
linthis plugin clean --all    # Clean all caches
```

## Configuration Files

### Project Configuration

Use `linthis init` to create the configuration file:

```bash
linthis init
```

This creates `.linthis/config.toml` in your project root:

```toml
# Specify languages to check (omit for auto-detection)
languages = ["rust", "python", "javascript"]

# Exclude files and directories
excludes = [
    "target/**",
    "node_modules/**",
    "*.generated.rs",
    "dist/**"
]

# Maximum cyclomatic complexity
max_complexity = 20

# Format preset
preset = "google"  # Options: google, airbnb, standard

# Configure plugins
[plugins]
sources = [
    { name = "official" },
    { name = "myplugin", url = "https://github.com/zhlinh/linthis-plugin.git", ref = "main" }
]

# Language-specific configuration
# [rust]
# max_complexity = 15

# [python]
# excludes = ["*_test.py"]
```

### Global Configuration

Global configuration file is located at `~/.linthis/config.toml`, with the same format as project config.

### Configuration Priority

Configuration merge priority (from high to low):

1. **CLI Parameters**: `--option value`
2. **Project Config**: `.linthis/config.toml`
3. **Global Config**: `~/.linthis/config.toml`
4. **Built-in Defaults**

For tool-specific configs (ruff.toml, .eslintrc.js, etc.), the priority is:

1. **Local manual configs** (highest) - ruff.toml, pyproject.toml, .eslintrc.js in project
2. **CLI plugin configs** - from `--use-plugin` option
3. **Project plugin configs** - from `.linthis/config.toml` plugins section
4. **Global plugin configs** - from `~/.linthis/config.toml` plugins
5. **Tool defaults** (lowest)

## Configuration Management

linthis provides a `config` subcommand for convenient command-line configuration management without manual TOML editing.

### Array Field Operations

Supported array fields: `includes`, `excludes`, `languages`

#### Add Values (add)

```bash
# Add to project config
linthis config add includes "src/**"
linthis config add excludes "*.log"
linthis config add languages "rust"

# Add to global config (-g or --global)
linthis config add -g includes "lib/**"
linthis config add --global excludes "node_modules/**"

# Add multiple values (automatically deduped)
linthis config add includes "src/**"
linthis config add includes "lib/**"
```

#### Remove Values (remove)

```bash
# Remove from project config
linthis config remove excludes "*.log"
linthis config remove languages "python"

# Remove from global config
linthis config remove -g includes "lib/**"
linthis config remove --global excludes "target/**"
```

#### Clear Field (clear)

```bash
# Clear project config field
linthis config clear languages
linthis config clear includes

# Clear global config field
linthis config clear -g excludes
linthis config clear --global languages
```

### Scalar Field Operations

Supported scalar fields: `max_complexity`, `preset`, `verbose`

#### Set Value (set)

```bash
# Set complexity limit
linthis config set max_complexity 15
linthis config set max_complexity 30 -g

# Set format preset (google, standard, airbnb)
linthis config set preset google
linthis config set preset airbnb --global

# Set verbose output
linthis config set verbose true
linthis config set verbose false -g
```

#### Unset Value (unset)

```bash
# Remove field from project config
linthis config unset max_complexity
linthis config unset preset

# Remove field from global config
linthis config unset -g verbose
linthis config unset --global max_complexity
```

### Query Operations

#### Get Single Field Value (get)

```bash
# View project config field
linthis config get includes
linthis config get max_complexity
linthis config get preset

# View global config field
linthis config get -g excludes
linthis config get --global languages
```

#### List All Configuration (list)

```bash
# List project config
linthis config list

# List global config
linthis config list -g
linthis config list --global

# Verbose mode (show all fields including empty values)
linthis config list -v
linthis config list --verbose
linthis config list --global --verbose
```

### Configuration Management Examples

```bash
# Initialize project config
linthis config add includes "src/**"
linthis config add includes "lib/**"
linthis config add excludes "target/**"
linthis config add excludes "*.log"
linthis config add languages "rust"
linthis config add languages "python"
linthis config set max_complexity 20
linthis config set preset google

# View config
linthis config list

# Adjust config
linthis config set max_complexity 15
linthis config remove excludes "*.log"
linthis config add excludes "*.tmp"

# Set global defaults
linthis config set -g max_complexity 20
linthis config add -g excludes "node_modules/**"
linthis config add -g excludes ".git/**"
```

### Configuration Migration

linthis can automatically detect and migrate existing linter/formatter configurations to linthis format.

#### Supported Tools

| Tool     | Detected Files                                                                                |
| -------- | --------------------------------------------------------------------------------------------- |
| ESLint   | `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`, `.eslintrc`, `eslint.config.js`, `package.json[eslintConfig]` |
| Prettier | `.prettierrc`, `.prettierrc.json`, `.prettierrc.yml`, `.prettierrc.js`, `prettier.config.js`, `package.json[prettier]` |
| Black    | `pyproject.toml[tool.black]`                                                                  |
| isort    | `pyproject.toml[tool.isort]`                                                                  |

#### Migration Commands

```bash
# Auto-detect and migrate all configs
linthis config migrate

# Migrate specific tool only
linthis config migrate --from eslint
linthis config migrate --from prettier
linthis config migrate --from black
linthis config migrate --from isort

# Preview changes without applying
linthis config migrate --dry-run

# Create backup of original files
linthis config migrate --backup

# Verbose output
linthis config migrate --verbose
```

#### Migration Output

Migrated configurations are placed in `.linthis/configs/{language}/`:

- ESLint → `.linthis/configs/javascript/.eslintrc.js`
- Prettier → `.linthis/configs/javascript/prettierrc.js`
- Black/isort → `.linthis/configs/python/ruff.toml`

### Initialize Configuration File

Use the `init` subcommand to explicitly create configuration files:

```bash
# Create project config (.linthis/config.toml)
linthis init

# Create global config (~/.linthis/config.toml)
linthis init -g
linthis init --global

# Backward compatible: can also use --init flag
linthis --init
```

### Auto-Create Configuration Files

When using the `config` command, configuration files are automatically created if they don't exist:

- **Project Config**: Creates `.linthis/config.toml` in current directory
- **Global Config**: Creates `config.toml` in `~/.linthis/` directory

All modifications preserve TOML file format and comments.

## Command Line Options

### Main Command Options

| Short | Long                    | Description                                   | Example                 |
| ----- | ----------------------- | --------------------------------------------- | ----------------------- |
| `-i`  | `--include`             | Specify files or directories to check         | `-i src -i lib`         |
| `-e`  | `--exclude`             | Exclude patterns (can be used multiple times) | `-e "*.test.js"`        |
| `-c`  | `--check-only`          | Check only, no formatting                     | `-c`                    |
| `-f`  | `--format-only`         | Format only, no checking                      | `-f`                    |
| `-s`  | `--staged`              | Check only Git staged files                   | `-s`                    |
| `-l`  | `--lang`                | Specify languages (comma-separated)           | `-l python,rust`        |
| `-o`  | `--output`              | Output format: human, json, github-actions    | `-o json`               |
| `-v`  | `--verbose`             | Verbose output                                | `-v`                    |
| `-q`  | `--quiet`               | Quiet mode (errors only)                      | `-q`                    |
|       | `--config`              | Specify config file path                      | `--config custom.toml`  |
|       | `--init`                | Initialize .linthis/config.toml config file   | `--init`                |
|       | `--preset`              | Format preset                                 | `--preset google`       |
|       | `--no-default-excludes` | Disable default exclude rules                 | `--no-default-excludes` |
|       | `--no-gitignore`        | Disable .gitignore rules                      | `--no-gitignore`        |
|       | `--no-plugin`           | Skip loading plugins, use default config      | `--no-plugin`           |

### Plugin Management Subcommands

| Command                    | Short | Long        | Description                |
| -------------------------- | ----- | ----------- | -------------------------- |
| `plugin add <alias> <url>` | `-g`  | `--global`  | Add to global config       |
|                            |       | `--ref`     | Specify Git reference      |
| `plugin remove <alias>`    | `-g`  | `--global`  | Remove from global config  |
| `plugin list`              | `-g`  | `--global`  | Show global config plugins |
|                            | `-v`  | `--verbose` | Show detailed info         |
| `plugin clean`             |       | `--all`     | Clean all caches           |
| `plugin init <name>`       |       |             | Initialize new plugin      |
| `plugin validate <path>`   |       |             | Validate plugin structure  |

### Configuration Management Subcommands

| Command                         | Short | Long        | Description                                 |
| ------------------------------- | ----- | ----------- | ------------------------------------------- |
| `config add <field> <value>`    | `-g`  | `--global`  | Add value to array field                    |
| `config remove <field> <value>` | `-g`  | `--global`  | Remove value from array field               |
| `config clear <field>`          | `-g`  | `--global`  | Clear array field                           |
| `config set <field> <value>`    | `-g`  | `--global`  | Set scalar field value                      |
| `config unset <field>`          | `-g`  | `--global`  | Remove scalar field                         |
| `config get <field>`            | `-g`  | `--global`  | Get field value                             |
| `config list`                   | `-g`  | `--global`  | List all configuration                      |
|                                 | `-v`  | `--verbose` | Show detailed info (including empty values) |
| `config migrate`                |       | `--from`    | Migrate from specific tool                  |
|                                 |       | `--dry-run` | Preview changes without applying            |
|                                 |       | `--backup`  | Create backup of original files             |
|                                 | `-v`  | `--verbose` | Show detailed output                        |

**Supported array fields**: `includes`, `excludes`, `languages`
**Supported scalar fields**: `max_complexity`, `preset`, `verbose`

### Init Subcommand

| Command | Short | Long          | Description                      |
| ------- | ----- | ------------- | -------------------------------- |
| `init`  | `-g`  | `--global`    | Create global config file        |
|         |       | `--with-hook` | Also install git hook after init |
|         |       | `--force`     | Force overwrite existing files   |

**Created configuration files**:

- Without `-g`: Creates `.linthis/config.toml` (current directory)
- With `-g`: Creates `~/.linthis/config.toml` (global config)

### Hook Subcommand

| Command          | Short | Long            | Description                            |
| ---------------- | ----- | --------------- | -------------------------------------- |
| `hook install`   |       | `--type`        | Hook type (prek/pre-commit/git)        |
|                  |       | `--event`       | Hook event (pre-commit/pre-push/commit-msg) |
|                  | `-c`  | `--check-only`  | Hook only runs check                   |
|                  | `-f`  | `--format-only` | Hook only runs format                  |
|                  |       | `--force`       | Force overwrite existing hook          |
|                  | `-y`  | `--yes`         | Non-interactive mode                   |
| `hook uninstall` |       | `--event`       | Hook event to uninstall                |
|                  | `-y`  | `--yes`         | Non-interactive mode                   |
| `hook status`    |       |                 | Show git hook status                   |
| `hook check`     |       |                 | Check for hook conflicts               |

**Hook types**:

- `prek`: Rust-based pre-commit tool (faster)
- `pre-commit`: Python-based standard tool
- `git`: Traditional git hook

**Hook events**:

- `pre-commit`: Run before commit (default, checks staged files)
- `pre-push`: Run before push (checks all files)
- `commit-msg`: Validate commit message format

## Supported Languages

| Language    | Linter                        | Formatter          |
| ----------- | ----------------------------- | ------------------ |
| Rust        | clippy                        | rustfmt            |
| Python      | ruff, pylint, flake8          | ruff, black        |
| TypeScript  | eslint                        | prettier           |
| JavaScript  | eslint                        | prettier           |
| Go          | golangci-lint                 | gofmt              |
| Java        | checkstyle                    | google-java-format |
| C           | clang-tidy, cppcheck          | clang-format       |
| C++         | clang-tidy, cpplint, cppcheck | clang-format       |
| Objective-C | clang-tidy                    | clang-format       |
| Swift       | swiftlint                     | swift-format       |
| Kotlin      | detekt                        | ktlint             |
| Lua         | luacheck                      | stylua             |
| Dart        | dart analyze                  | dart format        |
| Shell/Bash  | shellcheck                    | shfmt              |
| Ruby        | rubocop                       | rubocop            |
| PHP         | phpcs                         | php-cs-fixer       |
| Scala       | scalafix                      | scalafmt           |
| C#          | dotnet format                 | dotnet format      |

## Editor Plugins

linthis provides official plugins for popular editors, offering seamless integration with format-on-save, manual lint/format commands, and configurable settings.

### VSCode

Install from [VS Marketplace](https://marketplace.visualstudio.com/items?itemName=zhlinh.linthis) or search "linthis" in VSCode Extensions.

**Features:**
- Format on Save (configurable)
- Manual Lint/Format commands via Command Palette
- Configurable executable path and additional arguments
- Status bar integration

**Installation via Command Palette:**
```
ext install zhlinh.linthis
```

**Configuration (settings.json):**
```json
{
  "linthis.formatOnSave": true,
  "linthis.executable.path": "",
  "linthis.executable.additionalArguments": ""
}
```

📁 Source: [vscode-linthis](./vscode-linthis/)

### JetBrains (IntelliJ IDEA, WebStorm, PyCharm, etc.)

Install from [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/XXXXX-linthis) or search "linthis" in IDE Settings → Plugins.

**Features:**
- Format on Save (configurable)
- Manual Lint/Format via Tools menu
- Configurable executable path and additional arguments
- Settings UI in Preferences → Tools → Linthis

**Installation:**
1. Open Settings/Preferences → Plugins
2. Search for "linthis"
3. Click Install and restart IDE

**Configuration:**
- Settings → Tools → Linthis
- Enable/disable Format on Save
- Set custom executable path
- Add additional command-line arguments

📁 Source: [jetbrains-linthis](./jetbrains-linthis/)

### Neovim

Install using your favorite plugin manager. Distributed via GitHub.

#### lazy.nvim (Recommended)

```lua
-- For monorepo (plugin in subdirectory)
{
  "zhlinh/linthis",
  subdir = "nvim-linthis",
  config = function()
    require("linthis").setup()
  end,
}

-- For standalone repository
{
  "zhlinh/nvim-linthis",
  config = function()
    require("linthis").setup()
  end,
}
```

#### packer.nvim

```lua
-- For monorepo
use {
  "zhlinh/linthis",
  rtp = "nvim-linthis",
  config = function()
    require("linthis").setup()
  end,
}
```

#### vim-plug

```vim
" For monorepo
Plug 'zhlinh/linthis', { 'rtp': 'nvim-linthis' }
```

**Features:**
- Format on Save (configurable)
- Commands: `:LinthisLint`, `:LinthisFormat`, `:LinthisLintFormat`
- Configurable via `setup()` options

**Configuration:**
```lua
require("linthis").setup({
  format_on_save = true,
  executable = "linthis",
  additional_args = {},
})
```

📁 Source: [nvim-linthis](./nvim-linthis/)

## Usage Scenarios

### Pre-commit Hook

#### Method 1: Using prek (Recommended for Teams)

[prek](https://prek.j178.dev) is a high-performance Git hooks manager written in Rust, fully compatible with pre-commit config format but much faster.

Install prek:

```bash
# Using cargo
cargo install prek

# Or using pip
pip install prek
```

Create `.pre-commit-config.yaml` in your project:

```yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: linthis
        name: linthis
        entry: linthis --staged --check-only
        language: system
        pass_filenames: false
```

Install hook:

```bash
prek install
```

#### Method 2: Traditional Git Hook (Project-level)

Add to `.git/hooks/pre-commit`:

```bash
#!/bin/sh
linthis --staged --check-only
```

Or use linthis to create it automatically:

```bash
linthis hook install --type git
```

#### Method 3: Using pre-commit Framework

Using the [pre-commit](https://pre-commit.com/) framework:

```yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: linthis
        name: linthis
        entry: linthis --staged --check-only
        language: system
        pass_filenames: false
```

### CI/CD Integration

#### GitHub Actions

```yaml
name: Lint

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install linthis
        run: pip install linthis
      - name: Run linthis
        run: linthis --check-only --output github-actions
```

#### GitLab CI

```yaml
lint:
  image: rust:latest
  script:
    - cargo install linthis
    - linthis --check-only
```

## Creating Custom Plugins

### 1. Initialize Plugin

```bash
linthis plugin init my-company-standards
cd my-company-standards
```

### 2. Edit Plugin Configuration

Edit `linthis-plugin.toml`:

```toml
[plugin]
name = "my-company-standards"
version = "1.0.0"
description = "My company's coding standards"

["language.python"]
config_count = 2

["language.python".tools.flake8]
priority = "P0"
files = [".flake8"]

["language.python".tools.black]
priority = "P1"
files = ["pyproject.toml"]
```

### 3. Add Configuration Files

```bash
mkdir -p python
# Add your config files to corresponding language directories
cp /path/to/.flake8 python/
cp /path/to/pyproject.toml python/
```

### 4. Publish to Git

```bash
git init
git add .
git commit -m "feat: Initial commit of my company coding standards"
git remote add origin git@github.com:mycompany/linthis-standards.git
git push -u origin main
```

### 5. Use Your Plugin

```bash
linthis plugin add company https://github.com/mycompany/linthis-standards.git
linthis  # Plugin configs are auto-loaded
```

## FAQ

### Q: How to specify multiple paths?

```bash
linthis -i src -i lib -i tests
```

### Q: How to check only specific file types?

```bash
linthis -l python  # Only check Python files
```

### Q: Where is the plugin cache?

- macOS: `~/Library/Caches/linthis/plugins`
- Linux: `~/.cache/linthis/plugins`
- Windows: `%LOCALAPPDATA%\linthis\cache\plugins`

### Q: How to update plugins?

```bash
linthis plugin sync          # Sync local plugins
linthis plugin sync --global # Sync global plugins
```

### Q: What is the plugin Git reference (ref) used for?

The ref can specify:

- Branch name: `--ref main`
- Tag: `--ref v1.0.0`
- Commit hash: `--ref abc1234`

This allows you to lock plugin versions or use development versions.

## Documentation

- [Plugin Auto-Sync]docs/AUTO_SYNC.md - Automatic plugin synchronization (inspired by oh-my-zsh)
- [Self Auto-Update]docs/SELF_UPDATE.md - Automatic self-update functionality

## Development

### Build

```bash
cargo build
```

### Test

```bash
cargo test
```

### Release

```bash
cargo build --release
```

## Contributing

Issues and Pull Requests are welcome!

## License

MIT License - See [LICENSE](LICENSE) file for details