Support merge conflict formatting

This commit is contained in:
Joshua Barretto 2025-09-24 13:36:40 +01:00
parent 6580432286
commit 9c002841ff
4 changed files with 39 additions and 20 deletions

View file

@ -34,6 +34,8 @@ pub enum TokenKind {
Constant,
/// A function call or some other active operation
Function,
/// An active merge conflict
MergeConflict,
}
#[derive(Default)]

View file

@ -15,39 +15,39 @@ impl LangPack {
file_name.extension().and_then(|e| e.to_str()).unwrap_or(""),
) {
(_, "rs") => Self {
highlighter: Highlighter::default().rust(),
highlighter: Highlighter::default().rust().git(),
comment_syntax: Some(vec!['/', '/', ' ']),
},
(_, "md") => Self {
highlighter: Highlighter::default().markdown(),
highlighter: Highlighter::default().markdown().git(),
comment_syntax: None,
},
(_, "toml") => Self {
highlighter: Highlighter::default().toml(),
highlighter: Highlighter::default().toml().git(),
comment_syntax: Some(vec!['#', ' ']),
},
(_, "c" | "h" | "cpp" | "hpp" | "cxx" | "js" | "ts" | "go") => Self {
highlighter: Highlighter::default().generic_clike(),
highlighter: Highlighter::default().generic_clike().git(),
comment_syntax: Some(vec!['/', '/', ' ']),
},
(_, "glsl" | "vert" | "frag") => Self {
highlighter: Highlighter::default().glsl(),
highlighter: Highlighter::default().glsl().git(),
comment_syntax: Some(vec!['/', '/', ' ']),
},
(_, "py") => Self {
highlighter: Highlighter::default().python(),
highlighter: Highlighter::default().python().git(),
comment_syntax: Some(vec!['#', ' ']),
},
(_, "tao") => Self {
highlighter: Highlighter::default().tao(),
highlighter: Highlighter::default().tao().git(),
comment_syntax: Some(vec!['#', ' ']),
},
("makefile" | "Makefile", _) => Self {
highlighter: Highlighter::default().makefile(),
highlighter: Highlighter::default().makefile().git(),
comment_syntax: Some(vec!['#', ' ']),
},
_ => Self {
highlighter: Highlighter::default(),
highlighter: Highlighter::default().git(),
comment_syntax: None,
},
}
@ -170,7 +170,7 @@ impl Highlighter {
pub fn generic_clike(self) -> Self {
self
// Keywords
.with(TokenKind::Keyword, r"\b[(var)(enum)(let)(this)(fn)(struct)(class)(import)(if)(while)(for)(in)(loop)(else)(break)(continue)(const)(static)(type)(extern)(return)(async)(throw)(catch)(union)(auto)(namespace)(public)(private)(function)(func)(goto)]\b")
.with(TokenKind::Keyword, r"\b[(var)(enum)(let)(this)(fn)(struct)(class)(import)(if)(while)(for)(in)(loop)(else)(break)(continue)(const)(static)(type)(extern)(return)(async)(throw)(catch)(union)(auto)(namespace)(public)(private)(function)(func)(goto)(case)(default)(switch)]\b")
// Primitives
.with(TokenKind::Type, r"\b[(([(unsigned)(signed)][[:space:]])*u?int[0-9]*(_t)?)(float)(double)(bool)(char)(size_t)(void)]\b")
.clike_comments()
@ -277,4 +277,11 @@ impl Highlighter {
// Comments
.with(TokenKind::Comment, r"#[^$]*$")
}
pub fn git(self) -> Self {
self.with(
TokenKind::MergeConflict,
r"^[(<<<<<<<)(=======)(>>>>>>>)]( [^$]*)?$",
)
}
}

View file

@ -64,6 +64,8 @@ pub struct Theme {
pub hl_token_special: Color,
pub hl_token_constant: Color,
pub hl_token_function: Color,
pub hl_merge_conflict: Color,
}
impl Default for Theme {
@ -103,13 +105,15 @@ impl Default for Theme {
hl_token_special: Color::AnsiValue(160),
hl_token_constant: Color::AnsiValue(81),
hl_token_function: Color::AnsiValue(122),
hl_merge_conflict: Color::AnsiValue(124),
}
}
}
impl Theme {
pub fn token_color(&self, token: TokenKind) -> Color {
match token {
pub fn token_color(&self, token: TokenKind) -> (Color, Option<Color>) {
let fg = match token {
TokenKind::Whitespace => self.hl_token_whitespace,
TokenKind::Ident => self.hl_token_ident,
TokenKind::Keyword => self.hl_token_keyword,
@ -126,6 +130,12 @@ impl Theme {
TokenKind::Special => self.hl_token_special,
TokenKind::Constant => self.hl_token_constant,
TokenKind::Function => self.hl_token_function,
}
TokenKind::MergeConflict => self.text,
};
let bg = match token {
TokenKind::MergeConflict => Some(self.hl_merge_conflict),
_ => None,
};
(fg, bg)
}
}

View file

@ -286,19 +286,19 @@ impl Input {
.selection()
.zip(pos)
.map_or(false, |(s, pos)| s.contains(&pos));
let (fg, c) = match line.get(coord as usize).copied() {
Some('\n') if selected => (state.theme.whitespace, '⮠'),
let (fg, hl_bg, c) = match line.get(coord as usize).copied() {
Some('\n') if selected => (state.theme.whitespace, None, '⮠'),
Some(c) => {
if let Some(fg) = pos
if let Some((fg, bg)) = pos
.and_then(|pos| buffer.highlights.get_at(pos))
.map(|tok| state.theme.token_color(tok.kind))
{
(fg, c)
(fg, bg, c)
} else {
(state.theme.text, c)
(state.theme.text, None, c)
}
}
None => (Color::Reset, ' '),
None => (Color::Reset, None, ' '),
};
let bg = match finder.map(|s| s.contains(pos?)) {
Some(Some(true)) => state.theme.select_bg,
@ -316,7 +316,7 @@ impl Input {
} else if line_selected && frame.has_focus() {
state.theme.line_select_bg
} else {
Color::Reset
hl_bg.unwrap_or(Color::Reset)
}
}
};