Skip to content

Commit 667d30f

Browse files
author
Luctius
committed
WIP
1 parent 0aa4390 commit 667d30f

File tree

8 files changed

+333
-0
lines changed

8 files changed

+333
-0
lines changed

Cargo.lock

+107
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ members = [
66
"helix-tui",
77
"helix-syntax",
88
"helix-lsp",
9+
"helix-vcs",
910
]
1011

1112
# Build helix-syntax in release mode to make the code path faster in development.

helix-term/src/ui/editor.rs

+18
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,24 @@ impl EditorView {
329329

330330
for (i, line) in (view.first_line..last_line).enumerate() {
331331
use helix_core::diagnostic::Severity;
332+
if let Some(line_changes) = doc.vcs_line_changes() {
333+
if let Some(line_change) = line_changes.get(&i) {
334+
surface.set_stringn(
335+
viewport.x - OFFSET,
336+
viewport.y + i as u16,
337+
line_change.as_str(),
338+
1,
339+
info,
340+
/*
341+
match diagnostic.severity {
342+
Some(Severity::Error) => error,
343+
Some(Severity::Warning) | None => warning,
344+
Some(Severity::Info) => info,
345+
Some(Severity::Hint) => hint,
346+
},*/
347+
);
348+
}
349+
}
332350
if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
333351
surface.set_stringn(
334352
viewport.x - OFFSET,

helix-vcs/Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "helix-vcs"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
git2 = "0.13"
10+
helix-core = { version = "0.3", path = "../helix-core" }

helix-vcs/src/git.rs

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
use std::collections::HashMap;
2+
use std::fs;
3+
use std::path::{Path, PathBuf};
4+
5+
use git2::{DiffOptions, IntoCString, Repository};
6+
7+
use crate::{LineChange, LineChanges, OffsetEncoding};
8+
use helix_core::Rope;
9+
10+
pub struct Git {
11+
absolute_path: PathBuf,
12+
relative_path: PathBuf,
13+
repo: Repository,
14+
pub line_changes: Option<LineChanges>,
15+
}
16+
impl Git {
17+
pub fn from_path(filename: &Path) -> Option<Self> {
18+
if let Ok(repo) = Repository::discover(&filename) {
19+
let repo_path_absolute = fs::canonicalize(repo.workdir()?).ok()?;
20+
21+
let absolute_path = fs::canonicalize(&filename).ok()?.to_path_buf();
22+
let relative_path = absolute_path
23+
.strip_prefix(&repo_path_absolute)
24+
.ok()?
25+
.to_path_buf();
26+
Some(Git {
27+
repo,
28+
absolute_path,
29+
relative_path,
30+
line_changes: None,
31+
})
32+
} else {
33+
None
34+
}
35+
}
36+
37+
/// Taken from https://github.com/sharkdp/bat/blob/master/src/diff.rs
38+
pub fn diff(&mut self, doc: &Rope /*, offset_encoding: OffsetEncoding*/) {
39+
let mut diff_options = DiffOptions::new();
40+
let pathspec = if let Ok(p) = self.relative_path.clone().into_c_string() {
41+
p
42+
} else {
43+
return;
44+
};
45+
diff_options.pathspec(pathspec);
46+
diff_options.context_lines(0);
47+
48+
let diff = if let Ok(d) = self
49+
.repo
50+
.diff_index_to_workdir(None, Some(&mut diff_options))
51+
{
52+
d
53+
} else {
54+
return;
55+
};
56+
57+
let mut line_changes: LineChanges = HashMap::new();
58+
59+
let mark_section =
60+
|line_changes: &mut LineChanges, start: u32, end: i32, change: LineChange| {
61+
for line in start..=end as u32 {
62+
line_changes.insert(line as usize, change);
63+
}
64+
};
65+
66+
let _ = diff.foreach(
67+
&mut |_, _| true,
68+
None,
69+
Some(&mut |delta, hunk| {
70+
let path = delta.new_file().path().unwrap_or_else(|| Path::new(""));
71+
72+
if self.relative_path != path {
73+
return false;
74+
}
75+
76+
let old_lines = hunk.old_lines();
77+
let new_start = hunk.new_start();
78+
let new_lines = hunk.new_lines();
79+
let new_end = (new_start + new_lines) as i32 - 1;
80+
81+
if old_lines == 0 && new_lines > 0 {
82+
mark_section(&mut line_changes, new_start, new_end, LineChange::Added);
83+
} else if new_lines == 0 && old_lines > 0 {
84+
if new_start == 0 {
85+
mark_section(&mut line_changes, 1, 1, LineChange::RemovedAbove);
86+
} else {
87+
mark_section(
88+
&mut line_changes,
89+
new_start,
90+
new_start as i32,
91+
LineChange::RemovedBelow,
92+
);
93+
}
94+
} else {
95+
mark_section(&mut line_changes, new_start, new_end, LineChange::Modified);
96+
}
97+
98+
true
99+
}),
100+
None,
101+
);
102+
103+
self.line_changes = Some(line_changes);
104+
}
105+
}
106+
/*
107+
impl Clone for Git {
108+
fn clone(&self) -> Self {
109+
Git::from_path(&self.absolute_path).unwrap() // We *know* it exists..
110+
}
111+
}
112+
*/

helix-vcs/src/lib.rs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use std::collections::HashMap;
2+
use std::path::Path;
3+
4+
mod git;
5+
use git::Git;
6+
7+
use helix_core::Rope;
8+
9+
#[derive(Copy, Clone, Debug)]
10+
pub enum LineChange {
11+
Added,
12+
RemovedAbove,
13+
RemovedBelow,
14+
Modified,
15+
}
16+
impl LineChange {
17+
pub fn as_str(&self) -> &'static str {
18+
match self {
19+
LineChange::Added => &"+",
20+
LineChange::RemovedAbove => &"-",
21+
LineChange::RemovedBelow => &"_",
22+
LineChange::Modified => &"~",
23+
}
24+
}
25+
}
26+
27+
#[derive(Clone, Copy, Debug)]
28+
pub enum OffsetEncoding {
29+
/// UTF-8 code units aka bytes
30+
Utf8,
31+
/// UTF-16 code units
32+
Utf16,
33+
}
34+
35+
pub type LineChanges = HashMap<usize, LineChange>;
36+
37+
//#[derive(Clone)]
38+
pub enum VCS {
39+
Git(Git),
40+
}
41+
impl VCS {
42+
pub fn from_path(filename: &Path) -> Option<Self> {
43+
Some(VCS::Git(Git::from_path(filename)?))
44+
}
45+
pub fn get_line_changes(&self) -> Option<&LineChanges> {
46+
match self {
47+
VCS::Git(git) => git.line_changes.as_ref(),
48+
}
49+
}
50+
pub fn diff(&mut self, doc: &Rope /*, offset_encoding: OffsetEncoding*/) {
51+
match self {
52+
VCS::Git(git) => git.diff(doc /*, offset_encoding*/),
53+
}
54+
}
55+
}

helix-view/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ bitflags = "1.0"
1818
anyhow = "1"
1919
helix-core = { version = "0.3", path = "../helix-core" }
2020
helix-lsp = { version = "0.3", path = "../helix-lsp"}
21+
helix-vcs = { version = "0.1", path = "../helix-vcs"}
2122
crossterm = { version = "0.20", optional = true }
2223

2324
# Conversion traits

0 commit comments

Comments
 (0)