Skip to content

Commit 30cd5e9

Browse files
authored
feat: Added table output to blame mode along with some UI tweaks (#16)
1 parent 7eabde9 commit 30cd5e9

File tree

8 files changed

+101
-53
lines changed

8 files changed

+101
-53
lines changed

.github/workflows/format.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
name: Format and Lint
22

33
on:
4-
push:
5-
branches: [main, master]
64
pull_request:
7-
branches: [main, master]
5+
branches: [main]
86

97
env:
108
CARGO_TERM_COLOR: always

CONTRIBUTING.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,8 @@ cargo fmt --all -- --check
9797
# Run Clippy linter
9898
cargo clippy --all-targets --all-features -- -D warnings
9999

100-
# Run tests
101-
cargo test
102-
103100
# Build the project
104-
cargo build --release
101+
cargo build
105102
```
106103

107104
#### Automated Checks

README.md

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# wer ⁉️
1+
# ⁉️ wer ⁉️
22

33
`wer` (German "who") is a command-line tool for answering that everyday question:
44

@@ -7,7 +7,9 @@
77
No more complex `git log` commands, no more hunting for exact file paths. `wer` gives you context aware file / directory search.
88
`wer` offers both file-level recency and line-specific history through its `blame mode`, bridging the gap between `git blame` and `git-who` plus offering features like smart file finding and syntax highlighting.
99

10-
## Quick Start
10+
![Normal Mode](./screenshots/normal-mode.png)
11+
12+
## 🚀 Quick Start
1113

1214
```bash
1315
# install wer
@@ -20,25 +22,45 @@ wer main.rs
2022
wer -l 3 src/
2123
```
2224

23-
## Installation
25+
## 📚 Table of Contents
26+
27+
- [📦 Installation](#-installation)
28+
- [🎮 Usage](#usage)
29+
- [🏁 All Flags](#-all-flags)
30+
- [✨ Smart Path Resolution](#-smart-path-resolution)
31+
- [🎮 Basic Usage](#-basic-usage)
32+
- [👥 Last Contributors](#-last-contributors)
33+
- [🫵 Blame Mode](#-blame-mode)
34+
- [🎨 Display Options](#-display-options)
35+
- [👨‍💻 Contributing](#-contributing)
36+
- [📑 License](#-license)
37+
38+
## 📦 Installation
2439

2540
**From crates.io (Recommended)**
2641

2742
```bash
43+
#install cargo
44+
curl https://sh.rustup.rs -sSf | sh
45+
# install wer crate
2846
cargo install wer
2947
```
3048

3149
**From Source**
3250

3351
```bash
52+
#install cargo
53+
curl https://sh.rustup.rs -sSf | sh
54+
# clone repository
3455
git clone https://github.com/matsjfunke/wer
56+
# install wer
3557
cd wer
3658
cargo install --path .
3759
```
3860

3961
## Usage
4062

41-
### All Flags
63+
### 🏁 All Flags
4264

4365
| Flag | Description |
4466
| ---------------------- | ------------------------------------------------- |
@@ -50,9 +72,7 @@ cargo install --path .
5072
| `-v, --version` | Print version information |
5173
| `-h, --help` | Show help information |
5274

53-
### Examples
54-
55-
#### Smart Path Resolution ✨
75+
### ✨ Smart Path Resolution
5676

5777
`wer` automatically finds files and directories by name - no need to remember exact paths!
5878

@@ -68,7 +88,7 @@ wer src/ # Works from anywhere in the repository
6888
wer ~/Documents/file.txt # Uses absolute path directly
6989
wer /full/path/to/file # No search, direct access
7090

71-
# shows multiples matches in normal mode
91+
# Shows multiples matches in normal mode
7292
wer config.toml
7393
# → src/config.toml:
7494
# → 61fcdda Mats Julius Funke - 07 Jun 2025: Update config
@@ -77,7 +97,7 @@ wer config.toml
7797
# → a1b2c3d Jane Doe - 05 Jun 2025: Add test config
7898
```
7999

80-
#### Basic Usage
100+
### 🎮 Basic Usage
81101

82102
```bash
83103
# Check who last edited a file
@@ -93,7 +113,9 @@ wer
93113
# → 61fcdda Mats Julius Funke - 07 Jun 2025: Latest changes
94114
```
95115

96-
#### Last Contributors
116+
### 👥 Last Contributors
117+
118+
![Last Mode](./screenshots/last-mode.png)
97119

98120
Find the last N unique people who touched a file or directory:
99121

@@ -107,7 +129,9 @@ wer -l 5 src/
107129
# Searched for 5 but only 4 contributed # (if fewer found)
108130
```
109131

110-
#### Blame Mode
132+
### 🫵 Blame Mode
133+
134+
![Blame Mode](./screenshots/blame-mode.png)
111135

112136
Show git blame with syntax highlighting for any file:
113137

@@ -118,7 +142,9 @@ wer -b main.rs # Automatically finds src/main.rs
118142
# → 6b70ffb (Mats Julius Fun - 07 Jun) | 2 | use clap::Parser;
119143
```
120144

121-
#### Display Options
145+
### 🎨 Display Options
146+
147+
![Blame Mode date-only](./screenshots/blame-mode-date-only.png)
122148

123149
```bash
124150
# Show only dates
@@ -141,10 +167,10 @@ wer -b -m main.rs # Blame with commit messages
141167
wer --no-color -b main.rs
142168
```
143169

144-
## Contributing
170+
## 👨‍💻 Contributing
145171

146172
Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
147173

148-
## License
174+
## 📑 License
149175

150176
This project is licensed under the MIT License - see [LICENSE.md](LICENSE.md) for details.
75.6 KB
Loading

screenshots/blame-mode.png

121 KB
Loading

screenshots/last-mode.png

107 KB
Loading

screenshots/normal-mode.png

39.6 KB
Loading

src/git.rs

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl CommitInfo {
7474
fn format_regular(&self, colors: &ColorScheme, commit_message_separate: bool) -> String {
7575
if commit_message_separate {
7676
format!(
77-
"{}{}{} {} - {}{}{}\n {}",
77+
"{}{}{} {} - {}{}{}\n└─ {}",
7878
colors.commit,
7979
self.hash,
8080
colors.reset,
@@ -104,13 +104,12 @@ impl CommitInfo {
104104
&self,
105105
colors: &ColorScheme,
106106
line_num: usize,
107-
line_width: usize,
108107
highlighted_line: &str,
109108
commit_message_separate: bool,
110109
) -> String {
111110
if commit_message_separate {
112111
format!(
113-
"| {}{:>7}{} | {:>15} - {}{:>6}{} | {:>width$} | {}\n {}|\n",
112+
" {}{:<7}{} {:<15} {}{:<6}{} {:>4} │ {}\n│ {:<7} │ {:<15} │ {:<6} │ {:<4} │ └─ {}\n",
114113
colors.commit,
115114
self.hash,
116115
colors.reset,
@@ -120,12 +119,15 @@ impl CommitInfo {
120119
colors.reset,
121120
line_num,
122121
highlighted_line,
122+
"",
123+
"",
124+
"",
125+
"",
123126
self.message,
124-
width = line_width
125127
)
126128
} else {
127129
format!(
128-
"{}{:>7}{} ({:>15} - {}{:>6}{}) | {:>width$} | {}\n",
130+
"{}{:<7}{} │ {:<15} {}{:<6}{} {:>4} │ {}\n",
129131
colors.commit,
130132
self.hash,
131133
colors.reset,
@@ -135,7 +137,6 @@ impl CommitInfo {
135137
colors.reset,
136138
line_num,
137139
highlighted_line,
138-
width = line_width
139140
)
140141
}
141142
}
@@ -145,17 +146,11 @@ impl CommitInfo {
145146
&self,
146147
colors: &ColorScheme,
147148
line_num: usize,
148-
line_width: usize,
149149
highlighted_line: &str,
150150
) -> String {
151151
format!(
152-
"{}{:>6}{} | {:>width$} | {}\n",
153-
colors.date,
154-
self.date,
155-
colors.reset,
156-
line_num,
157-
highlighted_line,
158-
width = line_width
152+
"│ {}{:<6}{} │ {:>4} │ {}\n",
153+
colors.date, self.date, colors.reset, line_num, highlighted_line,
159154
)
160155
}
161156
}
@@ -231,8 +226,6 @@ pub fn get_blame(
231226
std::fs::read_to_string(&full_path).map_err(|e| anyhow!("Failed to read file: {}", e))?;
232227

233228
let lines: Vec<&str> = file_content.lines().collect();
234-
let line_count = lines.len();
235-
let line_width = line_count.to_string().len();
236229

237230
// Initialize syntax highlighter if colors are enabled
238231
let highlighter = if !no_color {
@@ -244,6 +237,39 @@ pub fn get_blame(
244237
let colors = ColorScheme::new(no_color);
245238
let mut result = String::new();
246239

240+
if date_only {
241+
// Add header for date-only mode (Date, Line, Code only)
242+
let header_line = format!("┌{:─<8}┬{:─<6}┬{:─<100}┐", "", "", "");
243+
result.push_str(&header_line);
244+
result.push('\n');
245+
246+
result.push_str(&format!("│ {:<6} │ {:<4} │ {}\n", "Date", "Line", "Code"));
247+
248+
let separator_line = format!("├{:─<8}┼{:─<6}┼{:─<100}┤", "", "", "");
249+
result.push_str(&separator_line);
250+
result.push('\n');
251+
} else {
252+
// Add header for the full blame table
253+
let header_line = format!(
254+
"┌{:─<9}┬{:─<17}┬{:─<8}┬{:─<6}┬{:─<100}┐",
255+
"", "", "", "", ""
256+
);
257+
result.push_str(&header_line);
258+
result.push('\n');
259+
260+
result.push_str(&format!(
261+
"│ {:<7} │ {:<15} │ {:<6} │ {:<4} │ {}\n",
262+
"Commit", "Name", "Date", "Line", "Code"
263+
));
264+
265+
let separator_line = format!(
266+
"├{:─<9}┼{:─<17}┼{:─<8}┼{:─<6}┼{:─<100}┤",
267+
"", "", "", "", ""
268+
);
269+
result.push_str(&separator_line);
270+
result.push('\n');
271+
}
272+
247273
for (line_num, line_content) in lines.iter().enumerate() {
248274
let hunk_result = blame.get_line(line_num + 1);
249275

@@ -260,35 +286,36 @@ pub fn get_blame(
260286
let commit_info = CommitInfo::from_hunk(&repo, hunk, false)?;
261287

262288
if date_only {
263-
commit_info.format_date_only(&colors, line_num + 1, line_width, &highlighted_line)
289+
commit_info.format_date_only(&colors, line_num + 1, &highlighted_line)
264290
} else {
265-
commit_info.format_blame(
266-
&colors,
267-
line_num + 1,
268-
line_width,
269-
&highlighted_line,
270-
commit_message,
271-
)
291+
commit_info.format_blame(&colors, line_num + 1, &highlighted_line, commit_message)
272292
}
273293
} else {
274294
let commit_info = CommitInfo::unknown(false);
275295

276296
if date_only {
277-
commit_info.format_date_only(&colors, line_num + 1, line_width, &highlighted_line)
297+
commit_info.format_date_only(&colors, line_num + 1, &highlighted_line)
278298
} else {
279-
commit_info.format_blame(
280-
&colors,
281-
line_num + 1,
282-
line_width,
283-
&highlighted_line,
284-
commit_message,
285-
)
299+
commit_info.format_blame(&colors, line_num + 1, &highlighted_line, commit_message)
286300
}
287301
};
288302

289303
result.push_str(&line_output);
290304
}
291305

306+
// Add bottom border to complete the table
307+
if date_only {
308+
let bottom_line = format!("└{:─<8}┴{:─<6}┴{:─<100}┘", "", "", "");
309+
result.push_str(&bottom_line);
310+
} else {
311+
let bottom_line = format!(
312+
"└{:─<9}┴{:─<17}┴{:─<8}┴{:─<6}┴{:─<100}┘",
313+
"", "", "", "", ""
314+
);
315+
result.push_str(&bottom_line);
316+
}
317+
result.push('\n');
318+
292319
Ok(result)
293320
}
294321

0 commit comments

Comments
 (0)