Skip to content

Commit 29dfea5

Browse files
alexander-akhmetovumputun
authored andcommitted
feat: add --line-numbers config option
The line numbers toggle (L key) from umputun#21 was runtime-only. This adds a CLI flag, env var, and config file option so users can enable line numbers by default.
1 parent e09686d commit 29dfea5

7 files changed

Lines changed: 50 additions & 0 deletions

File tree

.claude-plugin/skills/revdiff/references/config.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Then uncomment and edit the values you want to change.
2525
| `--no-status-bar` | `REVDIFF_NO_STATUS_BAR` | Hide the status bar | `false` |
2626
| `--wrap` | `REVDIFF_WRAP` | Enable line wrapping in diff view | `false` |
2727
| `--collapsed` | `REVDIFF_COLLAPSED` | Start in collapsed diff mode | `false` |
28+
| `--line-numbers` | `REVDIFF_LINE_NUMBERS` | Show line numbers in diff gutter | `false` |
2829
| `--no-confirm-discard` | `REVDIFF_NO_CONFIRM_DISCARD` | Skip confirmation when discarding annotations with Q | `false` |
2930
| `--chroma-style` | `REVDIFF_CHROMA_STYLE` | Chroma color theme for syntax highlighting | `catppuccin-macchiato` |
3031
| `--theme` | `REVDIFF_THEME` | Load color theme from `~/.config/revdiff/themes/` | |

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ Positional arguments support several forms:
160160
| `--no-status-bar` | Hide the status bar, env: `REVDIFF_NO_STATUS_BAR` | `false` |
161161
| `--wrap` | Enable line wrapping in diff view, env: `REVDIFF_WRAP` | `false` |
162162
| `--collapsed` | Start in collapsed diff mode, env: `REVDIFF_COLLAPSED` | `false` |
163+
| `--line-numbers` | Show line numbers in diff gutter, env: `REVDIFF_LINE_NUMBERS` | `false` |
163164
| `--no-confirm-discard` | Skip confirmation when discarding annotations with Q, env: `REVDIFF_NO_CONFIRM_DISCARD` | `false` |
164165
| `--chroma-style` | Chroma color theme for syntax highlighting, env: `REVDIFF_CHROMA_STYLE` | `catppuccin-macchiato` |
165166
| `--theme` | Load color theme from `~/.config/revdiff/themes/`, env: `REVDIFF_THEME` | |

cmd/revdiff/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type options struct {
3636
NoConfirmDiscard bool `long:"no-confirm-discard" ini-name:"no-confirm-discard" env:"REVDIFF_NO_CONFIRM_DISCARD" description:"skip confirmation prompt when discarding annotations with Q"`
3737
Wrap bool `long:"wrap" ini-name:"wrap" env:"REVDIFF_WRAP" description:"enable line wrapping in diff view"`
3838
Collapsed bool `long:"collapsed" ini-name:"collapsed" env:"REVDIFF_COLLAPSED" description:"start in collapsed diff mode"`
39+
LineNumbers bool `long:"line-numbers" ini-name:"line-numbers" env:"REVDIFF_LINE_NUMBERS" description:"show line numbers in diff gutter"`
3940
ChromaStyle string `long:"chroma-style" ini-name:"chroma-style" env:"REVDIFF_CHROMA_STYLE" default:"catppuccin-macchiato" description:"chroma style for syntax highlighting"`
4041
AllFiles bool `long:"all-files" short:"A" no-ini:"true" description:"browse all git-tracked files, not just diffs"`
4142
Exclude []string `long:"exclude" short:"X" ini-name:"exclude" env:"REVDIFF_EXCLUDE" env-delim:"," description:"exclude files matching prefix (may be repeated)"`
@@ -286,6 +287,7 @@ func run(opts options) error {
286287
NoConfirmDiscard: opts.NoConfirmDiscard,
287288
Wrap: opts.Wrap,
288289
Collapsed: opts.Collapsed,
290+
LineNumbers: opts.LineNumbers,
289291
TabWidth: opts.TabWidth,
290292
Ref: opts.ref(),
291293
Staged: opts.Staged,

cmd/revdiff/main_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,31 @@ func TestParseArgs_Collapsed(t *testing.T) {
115115
})
116116
}
117117

118+
func TestParseArgs_LineNumbers(t *testing.T) {
119+
t.Run("flag", func(t *testing.T) {
120+
opts, err := parseArgs(append(noConfigArgs(t), "--line-numbers"))
121+
require.NoError(t, err)
122+
assert.True(t, opts.LineNumbers)
123+
})
124+
125+
t.Run("env", func(t *testing.T) {
126+
t.Setenv("REVDIFF_LINE_NUMBERS", "true")
127+
opts, err := parseArgs(noConfigArgs(t))
128+
require.NoError(t, err)
129+
assert.True(t, opts.LineNumbers)
130+
})
131+
132+
t.Run("config file", func(t *testing.T) {
133+
cfgDir := t.TempDir()
134+
cfgPath := filepath.Join(cfgDir, "config")
135+
err := os.WriteFile(cfgPath, []byte("[Application Options]\nline-numbers = true\n"), 0o600)
136+
require.NoError(t, err)
137+
opts, err := parseArgs([]string{"--config", cfgPath})
138+
require.NoError(t, err)
139+
assert.True(t, opts.LineNumbers)
140+
})
141+
}
142+
118143
func TestParseArgs_OutputFlag(t *testing.T) {
119144
opts, err := parseArgs([]string{"-o", "/tmp/out.txt"})
120145
require.NoError(t, err)

site/docs.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ <h2 id="options">Options</h2>
187187
<tr><td><code>--no-status-bar</code></td><td>Hide the status bar</td><td><code>false</code></td></tr>
188188
<tr><td><code>--wrap</code></td><td>Enable line wrapping</td><td><code>false</code></td></tr>
189189
<tr><td><code>--collapsed</code></td><td>Start in collapsed diff mode</td><td><code>false</code></td></tr>
190+
<tr><td><code>--line-numbers</code></td><td>Show line numbers in diff gutter</td><td><code>false</code></td></tr>
190191
<tr><td><code>--no-confirm-discard</code></td><td>Skip discard confirmation</td><td><code>false</code></td></tr>
191192
<tr><td><code>--chroma-style</code></td><td>Syntax highlighting theme</td><td><code>catppuccin-macchiato</code></td></tr>
192193
<tr><td><code>--theme</code></td><td>Load color theme from <code>~/.config/revdiff/themes/</code></td><td></td></tr>

ui/model.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ type ModelConfig struct {
133133
NoConfirmDiscard bool // skip confirmation prompt when discarding annotations
134134
Wrap bool // enable line wrapping
135135
Collapsed bool // start in collapsed diff mode
136+
LineNumbers bool // show line numbers in diff gutter
136137
Only []string // show only these files (match by exact path or path suffix)
137138
WorkDir string // working directory for resolving absolute --only paths
138139
Keymap *keymap.Keymap // custom key bindings (nil uses defaults)
@@ -168,6 +169,7 @@ func NewModel(renderer Renderer, store *annotation.Store, highlighter SyntaxHigh
168169
noStatusBar: cfg.NoStatusBar,
169170
noConfirmDiscard: cfg.NoConfirmDiscard,
170171
wrapMode: cfg.Wrap,
172+
lineNumbers: cfg.LineNumbers,
171173
collapsed: collapsedState{enabled: cfg.Collapsed},
172174
focus: paneTree,
173175
treeWidthRatio: cfg.TreeWidthRatio,

ui/model_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,24 @@ func TestModel_CollapsedModeFromConfig(t *testing.T) {
433433
})
434434
}
435435

436+
func TestModel_LineNumbersFromConfig(t *testing.T) {
437+
renderer := &mocks.RendererMock{
438+
ChangedFilesFunc: func(string, bool) ([]string, error) { return nil, nil },
439+
FileDiffFunc: func(string, string, bool) ([]diff.DiffLine, error) { return nil, nil },
440+
}
441+
store := annotation.NewStore()
442+
443+
t.Run("line numbers enabled via config", func(t *testing.T) {
444+
m := NewModel(renderer, store, noopHighlighter(), ModelConfig{LineNumbers: true, TreeWidthRatio: 2})
445+
assert.True(t, m.lineNumbers)
446+
})
447+
448+
t.Run("line numbers disabled by default", func(t *testing.T) {
449+
m := NewModel(renderer, store, noopHighlighter(), ModelConfig{TreeWidthRatio: 2})
450+
assert.False(t, m.lineNumbers)
451+
})
452+
}
453+
436454
func TestModel_StatusModeIcons(t *testing.T) {
437455
t.Run("all icons always present", func(t *testing.T) {
438456
m := testModel(nil, nil)

0 commit comments

Comments
 (0)