mirror of https://github.com/helix-editor/helix
Merge branch 'master' into 2nd-filename-extension
commit
222b24ae6b
|
@ -138,7 +138,7 @@ The following statusline elements can be configured:
|
|||
| `file-type` | The type of the opened file |
|
||||
| `diagnostics` | The number of warnings and/or errors |
|
||||
| `workspace-diagnostics` | The number of warnings and/or errors on workspace |
|
||||
| `selections` | The number of active selections |
|
||||
| `selections` | The primary selection index out of the number of active selections |
|
||||
| `primary-selection-length` | The number of characters currently in primary selection |
|
||||
| `position` | The cursor position |
|
||||
| `position-percentage` | The cursor position as a percentage of the total number of lines |
|
||||
|
|
|
@ -312,7 +312,22 @@ impl Loader {
|
|||
}
|
||||
|
||||
pub fn language_for_shebang(&self, text: RopeSlice) -> Option<Language> {
|
||||
let shebang: Cow<str> = text.into();
|
||||
// NOTE: this is slightly different than the one for injection markers in tree-house. It
|
||||
// is anchored at the beginning.
|
||||
use helix_stdx::rope::Regex;
|
||||
use once_cell::sync::Lazy;
|
||||
const SHEBANG: &str = r"^#!\s*(?:\S*[/\\](?:env\s+(?:\-\S+\s+)*)?)?([^\s\.\d]+)";
|
||||
static SHEBANG_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(SHEBANG).unwrap());
|
||||
|
||||
let marker = SHEBANG_REGEX
|
||||
.captures_iter(regex_cursor::Input::new(text))
|
||||
.map(|cap| text.byte_slice(cap.get_group(1).unwrap().range()))
|
||||
.next()?;
|
||||
self.language_for_shebang_marker(marker)
|
||||
}
|
||||
|
||||
fn language_for_shebang_marker(&self, marker: RopeSlice) -> Option<Language> {
|
||||
let shebang: Cow<str> = marker.into();
|
||||
self.languages_by_shebang.get(shebang.as_ref()).copied()
|
||||
}
|
||||
|
||||
|
@ -351,7 +366,7 @@ impl LanguageLoader for Loader {
|
|||
let path: Cow<str> = text.into();
|
||||
self.language_for_filename(Path::new(path.as_ref()))
|
||||
}
|
||||
InjectionLanguageMarker::Shebang(text) => self.language_for_shebang(text),
|
||||
InjectionLanguageMarker::Shebang(text) => self.language_for_shebang_marker(text),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,8 @@ pub fn render_text(
|
|||
|
||||
let mut formatter =
|
||||
DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, text_annotations, anchor);
|
||||
let mut syntax_highlighter = SyntaxHighlighter::new(syntax_highlighter, text, theme);
|
||||
let mut syntax_highlighter =
|
||||
SyntaxHighlighter::new(syntax_highlighter, text, theme, renderer.text_style);
|
||||
let mut overlay_highlighter = OverlayHighlighter::new(overlay_highlights, theme);
|
||||
|
||||
let mut last_line_pos = LinePos {
|
||||
|
@ -477,17 +478,24 @@ struct SyntaxHighlighter<'h, 'r, 't> {
|
|||
/// finished.
|
||||
pos: usize,
|
||||
theme: &'t Theme,
|
||||
text_style: Style,
|
||||
style: Style,
|
||||
}
|
||||
|
||||
impl<'h, 'r, 't> SyntaxHighlighter<'h, 'r, 't> {
|
||||
fn new(inner: Option<Highlighter<'h>>, text: RopeSlice<'r>, theme: &'t Theme) -> Self {
|
||||
fn new(
|
||||
inner: Option<Highlighter<'h>>,
|
||||
text: RopeSlice<'r>,
|
||||
theme: &'t Theme,
|
||||
text_style: Style,
|
||||
) -> Self {
|
||||
let mut highlighter = Self {
|
||||
inner,
|
||||
text,
|
||||
pos: 0,
|
||||
theme,
|
||||
style: Style::default(),
|
||||
style: text_style,
|
||||
text_style,
|
||||
};
|
||||
highlighter.update_pos();
|
||||
highlighter
|
||||
|
@ -516,7 +524,7 @@ impl<'h, 'r, 't> SyntaxHighlighter<'h, 'r, 't> {
|
|||
|
||||
let (event, highlights) = highlighter.advance();
|
||||
let base = match event {
|
||||
HighlightEvent::Refresh => Style::default(),
|
||||
HighlightEvent::Refresh => self.text_style,
|
||||
HighlightEvent::Push => self.style,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use helix_core::{coords_at_pos, encoding, Position};
|
||||
use helix_lsp::lsp::DiagnosticSeverity;
|
||||
use helix_view::document::DEFAULT_LANGUAGE_NAME;
|
||||
|
@ -58,25 +60,16 @@ pub fn render(context: &mut RenderContext, viewport: Rect, surface: &mut Surface
|
|||
|
||||
surface.set_style(viewport.with_height(1), base_style);
|
||||
|
||||
let write_left = |context: &mut RenderContext, text, style| {
|
||||
append(&mut context.parts.left, text, &base_style, style)
|
||||
};
|
||||
let write_center = |context: &mut RenderContext, text, style| {
|
||||
append(&mut context.parts.center, text, &base_style, style)
|
||||
};
|
||||
let write_right = |context: &mut RenderContext, text, style| {
|
||||
append(&mut context.parts.right, text, &base_style, style)
|
||||
};
|
||||
|
||||
// Left side of the status line.
|
||||
|
||||
let config = context.editor.config();
|
||||
|
||||
let element_ids = &config.statusline.left;
|
||||
element_ids
|
||||
.iter()
|
||||
.map(|element_id| get_render_function(*element_id))
|
||||
.for_each(|render| render(context, write_left));
|
||||
for element_id in &config.statusline.left {
|
||||
let render = get_render_function(*element_id);
|
||||
(render)(context, |context, span| {
|
||||
append(&mut context.parts.left, span, base_style)
|
||||
});
|
||||
}
|
||||
|
||||
surface.set_spans(
|
||||
viewport.x,
|
||||
|
@ -87,11 +80,12 @@ pub fn render(context: &mut RenderContext, viewport: Rect, surface: &mut Surface
|
|||
|
||||
// Right side of the status line.
|
||||
|
||||
let element_ids = &config.statusline.right;
|
||||
element_ids
|
||||
.iter()
|
||||
.map(|element_id| get_render_function(*element_id))
|
||||
.for_each(|render| render(context, write_right));
|
||||
for element_id in &config.statusline.right {
|
||||
let render = get_render_function(*element_id);
|
||||
(render)(context, |context, span| {
|
||||
append(&mut context.parts.right, span, base_style)
|
||||
})
|
||||
}
|
||||
|
||||
surface.set_spans(
|
||||
viewport.x
|
||||
|
@ -105,11 +99,12 @@ pub fn render(context: &mut RenderContext, viewport: Rect, surface: &mut Surface
|
|||
|
||||
// Center of the status line.
|
||||
|
||||
let element_ids = &config.statusline.center;
|
||||
element_ids
|
||||
.iter()
|
||||
.map(|element_id| get_render_function(*element_id))
|
||||
.for_each(|render| render(context, write_center));
|
||||
for element_id in &config.statusline.center {
|
||||
let render = get_render_function(*element_id);
|
||||
(render)(context, |context, span| {
|
||||
append(&mut context.parts.center, span, base_style)
|
||||
})
|
||||
}
|
||||
|
||||
// Width of the empty space between the left and center area and between the center and right area.
|
||||
let spacing = 1u16;
|
||||
|
@ -126,16 +121,14 @@ pub fn render(context: &mut RenderContext, viewport: Rect, surface: &mut Surface
|
|||
);
|
||||
}
|
||||
|
||||
fn append(buffer: &mut Spans, text: String, base_style: &Style, style: Option<Style>) {
|
||||
buffer.0.push(Span::styled(
|
||||
text,
|
||||
style.map_or(*base_style, |s| (*base_style).patch(s)),
|
||||
));
|
||||
fn append<'a>(buffer: &mut Spans<'a>, mut span: Span<'a>, base_style: Style) {
|
||||
span.style = base_style.patch(span.style);
|
||||
buffer.0.push(span);
|
||||
}
|
||||
|
||||
fn get_render_function<F>(element_id: StatusLineElementID) -> impl Fn(&mut RenderContext, F)
|
||||
fn get_render_function<'a, F>(element_id: StatusLineElementID) -> impl Fn(&mut RenderContext<'a>, F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
match element_id {
|
||||
helix_view::editor::StatusLineElement::Mode => render_mode,
|
||||
|
@ -166,44 +159,42 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn render_mode<F>(context: &mut RenderContext, write: F)
|
||||
fn render_mode<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let visible = context.focused;
|
||||
let config = context.editor.config();
|
||||
let modenames = &config.statusline.mode;
|
||||
write(
|
||||
context,
|
||||
format!(
|
||||
let content = if visible {
|
||||
Cow::Owned(format!(
|
||||
" {} ",
|
||||
if visible {
|
||||
match context.editor.mode() {
|
||||
Mode::Insert => &modenames.insert,
|
||||
Mode::Select => &modenames.select,
|
||||
Mode::Normal => &modenames.normal,
|
||||
}
|
||||
} else {
|
||||
// If not focused, explicitly leave an empty space instead of returning None.
|
||||
" "
|
||||
}
|
||||
),
|
||||
if visible && config.color_modes {
|
||||
match context.editor.mode() {
|
||||
Mode::Insert => Some(context.editor.theme.get("ui.statusline.insert")),
|
||||
Mode::Select => Some(context.editor.theme.get("ui.statusline.select")),
|
||||
Mode::Normal => Some(context.editor.theme.get("ui.statusline.normal")),
|
||||
Mode::Insert => &modenames.insert,
|
||||
Mode::Select => &modenames.select,
|
||||
Mode::Normal => &modenames.normal,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
},
|
||||
);
|
||||
))
|
||||
} else {
|
||||
// If not focused, explicitly leave an empty space instead of returning None.
|
||||
Cow::Borrowed(" ")
|
||||
};
|
||||
let style = if visible && config.color_modes {
|
||||
match context.editor.mode() {
|
||||
Mode::Insert => context.editor.theme.get("ui.statusline.insert"),
|
||||
Mode::Select => context.editor.theme.get("ui.statusline.select"),
|
||||
Mode::Normal => context.editor.theme.get("ui.statusline.normal"),
|
||||
}
|
||||
} else {
|
||||
Style::default()
|
||||
};
|
||||
write(context, Span::styled(content, style));
|
||||
}
|
||||
|
||||
// TODO think about handling multiple language servers
|
||||
fn render_lsp_spinner<F>(context: &mut RenderContext, write: F)
|
||||
fn render_lsp_spinner<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let language_server = context.doc.language_servers().next();
|
||||
write(
|
||||
|
@ -217,14 +208,13 @@ where
|
|||
})
|
||||
// Even if there's no spinner; reserve its space to avoid elements frequently shifting.
|
||||
.unwrap_or(" ")
|
||||
.to_string(),
|
||||
None,
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
fn render_diagnostics<F>(context: &mut RenderContext, write: F)
|
||||
fn render_diagnostics<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
use helix_core::diagnostic::Severity;
|
||||
let (hints, info, warnings, errors) =
|
||||
|
@ -245,45 +235,35 @@ where
|
|||
for sev in &context.editor.config().statusline.diagnostics {
|
||||
match sev {
|
||||
Severity::Hint if hints > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("hint")),
|
||||
);
|
||||
write(context, format!(" {} ", hints), None);
|
||||
write(context, Span::styled("●", context.editor.theme.get("hint")));
|
||||
write(context, format!(" {} ", hints).into());
|
||||
}
|
||||
Severity::Info if info > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("info")),
|
||||
);
|
||||
write(context, format!(" {} ", info), None);
|
||||
write(context, Span::styled("●", context.editor.theme.get("info")));
|
||||
write(context, format!(" {} ", info).into());
|
||||
}
|
||||
Severity::Warning if warnings > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("warning")),
|
||||
Span::styled("●", context.editor.theme.get("warning")),
|
||||
);
|
||||
write(context, format!(" {} ", warnings), None);
|
||||
write(context, format!(" {} ", warnings).into());
|
||||
}
|
||||
Severity::Error if errors > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("error")),
|
||||
Span::styled("●", context.editor.theme.get("error")),
|
||||
);
|
||||
write(context, format!(" {} ", errors), None);
|
||||
write(context, format!(" {} ", errors).into());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_workspace_diagnostics<F>(context: &mut RenderContext, write: F)
|
||||
fn render_workspace_diagnostics<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
use helix_core::diagnostic::Severity;
|
||||
let (hints, info, warnings, errors) = context.editor.diagnostics.values().flatten().fold(
|
||||
|
@ -305,70 +285,73 @@ where
|
|||
},
|
||||
);
|
||||
|
||||
if hints > 0 || info > 0 || warnings > 0 || errors > 0 {
|
||||
write(context, " W ".into(), None);
|
||||
let sevs_to_show = &context.editor.config().statusline.workspace_diagnostics;
|
||||
|
||||
// Avoid showing the " W " if no diagnostic counts will be shown.
|
||||
if !sevs_to_show.iter().any(|sev| match sev {
|
||||
Severity::Hint => hints != 0,
|
||||
Severity::Info => info != 0,
|
||||
Severity::Warning => warnings != 0,
|
||||
Severity::Error => errors != 0,
|
||||
}) {
|
||||
return;
|
||||
}
|
||||
|
||||
for sev in &context.editor.config().statusline.workspace_diagnostics {
|
||||
write(context, " W ".into());
|
||||
|
||||
for sev in sevs_to_show {
|
||||
match sev {
|
||||
Severity::Hint if hints > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("hint")),
|
||||
);
|
||||
write(context, format!(" {} ", hints), None);
|
||||
write(context, Span::styled("●", context.editor.theme.get("hint")));
|
||||
write(context, format!(" {} ", hints).into());
|
||||
}
|
||||
Severity::Info if info > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("info")),
|
||||
);
|
||||
write(context, format!(" {} ", info), None);
|
||||
write(context, Span::styled("●", context.editor.theme.get("info")));
|
||||
write(context, format!(" {} ", info).into());
|
||||
}
|
||||
Severity::Warning if warnings > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("warning")),
|
||||
Span::styled("●", context.editor.theme.get("warning")),
|
||||
);
|
||||
write(context, format!(" {} ", warnings), None);
|
||||
write(context, format!(" {} ", warnings).into());
|
||||
}
|
||||
Severity::Error if errors > 0 => {
|
||||
write(
|
||||
context,
|
||||
"●".to_string(),
|
||||
Some(context.editor.theme.get("error")),
|
||||
Span::styled("●", context.editor.theme.get("error")),
|
||||
);
|
||||
write(context, format!(" {} ", errors), None);
|
||||
write(context, format!(" {} ", errors).into());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_selections<F>(context: &mut RenderContext, write: F)
|
||||
fn render_selections<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let count = context.doc.selection(context.view.id).len();
|
||||
let selection = context.doc.selection(context.view.id);
|
||||
let count = selection.len();
|
||||
write(
|
||||
context,
|
||||
format!(" {} sel{} ", count, if count == 1 { "" } else { "s" }),
|
||||
None,
|
||||
if count == 1 {
|
||||
" 1 sel ".into()
|
||||
} else {
|
||||
format!(" {}/{count} sels ", selection.primary_index() + 1).into()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn render_primary_selection_length<F>(context: &mut RenderContext, write: F)
|
||||
fn render_primary_selection_length<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let tot_sel = context.doc.selection(context.view.id).primary().len();
|
||||
write(
|
||||
context,
|
||||
format!(" {} char{} ", tot_sel, if tot_sel == 1 { "" } else { "s" }),
|
||||
None,
|
||||
format!(" {} char{} ", tot_sel, if tot_sel == 1 { "" } else { "s" }).into(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -383,54 +366,52 @@ fn get_position(context: &RenderContext) -> Position {
|
|||
)
|
||||
}
|
||||
|
||||
fn render_position<F>(context: &mut RenderContext, write: F)
|
||||
fn render_position<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let position = get_position(context);
|
||||
write(
|
||||
context,
|
||||
format!(" {}:{} ", position.row + 1, position.col + 1),
|
||||
None,
|
||||
format!(" {}:{} ", position.row + 1, position.col + 1).into(),
|
||||
);
|
||||
}
|
||||
|
||||
fn render_total_line_numbers<F>(context: &mut RenderContext, write: F)
|
||||
fn render_total_line_numbers<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let total_line_numbers = context.doc.text().len_lines();
|
||||
|
||||
write(context, format!(" {} ", total_line_numbers), None);
|
||||
write(context, format!(" {} ", total_line_numbers).into());
|
||||
}
|
||||
|
||||
fn render_position_percentage<F>(context: &mut RenderContext, write: F)
|
||||
fn render_position_percentage<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let position = get_position(context);
|
||||
let maxrows = context.doc.text().len_lines();
|
||||
write(
|
||||
context,
|
||||
format!("{}%", (position.row + 1) * 100 / maxrows),
|
||||
None,
|
||||
format!("{}%", (position.row + 1) * 100 / maxrows).into(),
|
||||
);
|
||||
}
|
||||
|
||||
fn render_file_encoding<F>(context: &mut RenderContext, write: F)
|
||||
fn render_file_encoding<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let enc = context.doc.encoding();
|
||||
|
||||
if enc != encoding::UTF_8 {
|
||||
write(context, format!(" {} ", enc.name()), None);
|
||||
write(context, format!(" {} ", enc.name()).into());
|
||||
}
|
||||
}
|
||||
|
||||
fn render_file_line_ending<F>(context: &mut RenderContext, write: F)
|
||||
fn render_file_line_ending<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
use helix_core::LineEnding::*;
|
||||
let line_ending = match context.doc.line_ending {
|
||||
|
@ -450,21 +431,21 @@ where
|
|||
PS => "PS", // U+2029 -- ParagraphSeparator
|
||||
};
|
||||
|
||||
write(context, format!(" {} ", line_ending), None);
|
||||
write(context, format!(" {} ", line_ending).into());
|
||||
}
|
||||
|
||||
fn render_file_type<F>(context: &mut RenderContext, write: F)
|
||||
fn render_file_type<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let file_type = context.doc.language_name().unwrap_or(DEFAULT_LANGUAGE_NAME);
|
||||
|
||||
write(context, format!(" {} ", file_type), None);
|
||||
write(context, format!(" {} ", file_type).into());
|
||||
}
|
||||
|
||||
fn render_file_name<F>(context: &mut RenderContext, write: F)
|
||||
fn render_file_name<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let title = {
|
||||
let rel_path = context.doc.relative_path();
|
||||
|
@ -475,12 +456,12 @@ where
|
|||
format!(" {} ", path)
|
||||
};
|
||||
|
||||
write(context, title, None);
|
||||
write(context, title.into());
|
||||
}
|
||||
|
||||
fn render_file_absolute_path<F>(context: &mut RenderContext, write: F)
|
||||
fn render_file_absolute_path<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let title = {
|
||||
let path = context.doc.path();
|
||||
|
@ -491,39 +472,37 @@ where
|
|||
format!(" {} ", path)
|
||||
};
|
||||
|
||||
write(context, title, None);
|
||||
write(context, title.into());
|
||||
}
|
||||
|
||||
fn render_file_modification_indicator<F>(context: &mut RenderContext, write: F)
|
||||
fn render_file_modification_indicator<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let title = (if context.doc.is_modified() {
|
||||
let title = if context.doc.is_modified() {
|
||||
"[+]"
|
||||
} else {
|
||||
" "
|
||||
})
|
||||
.to_string();
|
||||
};
|
||||
|
||||
write(context, title, None);
|
||||
write(context, title.into());
|
||||
}
|
||||
|
||||
fn render_read_only_indicator<F>(context: &mut RenderContext, write: F)
|
||||
fn render_read_only_indicator<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let title = if context.doc.readonly {
|
||||
" [readonly] "
|
||||
} else {
|
||||
""
|
||||
}
|
||||
.to_string();
|
||||
write(context, title, None);
|
||||
};
|
||||
write(context, title.into());
|
||||
}
|
||||
|
||||
fn render_file_base_name<F>(context: &mut RenderContext, write: F)
|
||||
fn render_file_base_name<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let title = {
|
||||
let rel_path = context.doc.relative_path();
|
||||
|
@ -534,32 +513,29 @@ where
|
|||
format!(" {} ", path)
|
||||
};
|
||||
|
||||
write(context, title, None);
|
||||
write(context, title.into());
|
||||
}
|
||||
|
||||
fn render_separator<F>(context: &mut RenderContext, write: F)
|
||||
fn render_separator<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let sep = &context.editor.config().statusline.separator;
|
||||
let style = context.editor.theme.get("ui.statusline.separator");
|
||||
|
||||
write(
|
||||
context,
|
||||
sep.to_string(),
|
||||
Some(context.editor.theme.get("ui.statusline.separator")),
|
||||
);
|
||||
write(context, Span::styled(sep.to_string(), style));
|
||||
}
|
||||
|
||||
fn render_spacer<F>(context: &mut RenderContext, write: F)
|
||||
fn render_spacer<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
write(context, String::from(" "), None);
|
||||
write(context, " ".into());
|
||||
}
|
||||
|
||||
fn render_version_control<F>(context: &mut RenderContext, write: F)
|
||||
fn render_version_control<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
let head = context
|
||||
.doc
|
||||
|
@ -567,14 +543,14 @@ where
|
|||
.unwrap_or_default()
|
||||
.to_string();
|
||||
|
||||
write(context, head, None);
|
||||
write(context, head.into());
|
||||
}
|
||||
|
||||
fn render_register<F>(context: &mut RenderContext, write: F)
|
||||
fn render_register<'a, F>(context: &mut RenderContext<'a>, write: F)
|
||||
where
|
||||
F: Fn(&mut RenderContext, String, Option<Style>) + Copy,
|
||||
F: Fn(&mut RenderContext<'a>, Span<'a>) + Copy,
|
||||
{
|
||||
if let Some(reg) = context.editor.selected_register {
|
||||
write(context, format!(" reg={} ", reg), None)
|
||||
write(context, format!(" reg={} ", reg).into())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1899,7 +1899,7 @@ source = { git = "https://github.com/the-mikedavis/tree-sitter-git-config", rev
|
|||
[[language]]
|
||||
name = "git-attributes"
|
||||
scope = "source.gitattributes"
|
||||
file-types = [{ glob = ".gitattributes" }]
|
||||
file-types = [{ glob = ".gitattributes" }, { glob = ".config/git/attributes" }]
|
||||
injection-regex = "git-attributes"
|
||||
comment-token = "#"
|
||||
grammar = "gitattributes"
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# nyxvamp - obsidian variant
|
||||
# author: zoedsoupe <zoey.spessanha@zeetech.io>
|
||||
|
||||
inherits = "nyxvamp-radiance"
|
||||
|
||||
# Override specific styles for obsidian variant
|
||||
"function" = { fg = "function_fg", modifiers = ["bold"] }
|
||||
"function.builtin" = { fg = "function_builtin_fg", modifiers = ["bold"] }
|
||||
"ui.match_paren" = { fg = "match_paren_fg", bg = "match_paren_bg", modifiers = ["bold"] }
|
||||
|
||||
# Palette overrides
|
||||
[palette]
|
||||
# Very dark theme colors
|
||||
background = "#000A0F" # Very dark background
|
||||
foreground = "#C0C0CE" # Slightly muted foreground
|
||||
cursor_fg = "#0E0E10"
|
||||
cursor_bg = "#F28FAD" # Pink cursor
|
||||
cursorline = "#1E1E20" # Slightly lighter background
|
||||
selection = "#2E2E30" # Dark gray selection
|
||||
line_nr = "#5E5A76" # Dark gray line numbers
|
||||
line_nr_selected = "#C0C0CE" # Foreground color for selected line number
|
||||
|
||||
# Status line colors
|
||||
status_fg = "#C0C0CE"
|
||||
status_bg = "#1E1E20"
|
||||
status_inactive_fg = "#5E5A76"
|
||||
status_inactive_bg = "#0E0E10"
|
||||
|
||||
# Menu colors
|
||||
menu_fg = "#C0C0CE"
|
||||
menu_bg = "#0E0E10"
|
||||
menu_sel_fg = "#0E0E10"
|
||||
menu_sel_bg = "#F28FAD"
|
||||
menu_scroll_fg = "#5E5A76"
|
||||
menu_scroll_bg = "#0E0E10"
|
||||
popup_fg = "#C0C0CE"
|
||||
popup_bg = "#0E0E10"
|
||||
|
||||
# UI virtual
|
||||
virtual_ruler_bg = "#191921" # Slightly lighter than background, close to comment color
|
||||
|
||||
# Syntax highlighting
|
||||
match_paren_fg = "#F28FAD"
|
||||
match_paren_bg = "#0E0E10"
|
||||
comment_fg = "#5E5A76" # Dark gray comments
|
||||
string_fg = "#8FBF8F" # Muted green strings
|
||||
string_special_fg = "#F28FAD" # Pink special strings
|
||||
constant_fg = "#F28FAD" # Pink constants
|
||||
constant_builtin_fg = "#F28FAD"
|
||||
number_fg = "#D8A080" # Muted peach numbers
|
||||
boolean_fg = "#F28FAD"
|
||||
function_fg = "#7FAFD7" # Muted blue functions
|
||||
function_builtin_fg = "#7FAFD7"
|
||||
keyword_fg = "#F5C2E7" # Pink keywords
|
||||
keyword_control_fg = "#F5C2E7"
|
||||
operator_fg = "#C0C0CE" # Foreground color for operators
|
||||
variable_fg = "#C0C0CE"
|
||||
variable_builtin_fg = "#F28FAD"
|
||||
type_fg = "#A0A0D0" # Muted lavender types
|
||||
type_builtin_fg = "#A0A0D0"
|
||||
attribute_fg = "#F5C2E7"
|
||||
namespace_fg = "#A090C0" # Muted purple namespaces
|
||||
punctuation_fg = "#C0C0CE"
|
||||
symbol_fg = "#F28FAD"
|
||||
|
||||
# Diagnostics
|
||||
error_fg = "#D78284" # Muted red errors
|
||||
warning_fg = "#D5B880" # Muted yellow warnings
|
||||
info_fg = "#7A9CCC" # Muted blue info
|
||||
hint_fg = "#7BB5A8" # Muted cyan hints
|
||||
|
||||
# Diff colors
|
||||
diff_add_fg = "#86BA75" # Muted green additions
|
||||
diff_delete_fg = "#D78284" # Muted red deletions
|
||||
diff_change_fg = "#D5B880" # Muted yellow changes
|
||||
|
||||
# Markup colors
|
||||
markup_heading_fg = "#F5C2E7"
|
||||
markup_bold_fg = "#F5C2E7"
|
||||
markup_italic_fg = "#F5C2E7"
|
||||
markup_link_url_fg = "#7FAFD7"
|
||||
markup_link_text_fg = "#F5C2E7"
|
||||
markup_quote_fg = "#5E5A76"
|
|
@ -0,0 +1,124 @@
|
|||
# nyxvamp - radiance variant
|
||||
# author: <zoey.spessanha@zeetech.io>
|
||||
|
||||
# UI Elements
|
||||
"ui.background" = { bg = "background", fg = "foreground" }
|
||||
"ui.text" = { fg = "foreground" }
|
||||
"ui.cursor" = { fg = "cursor_fg", bg = "cursor_bg" }
|
||||
"ui.cursorline.primary" = { bg = "cursorline" }
|
||||
"ui.selection" = { bg = "selection" }
|
||||
"ui.linenr" = { fg = "line_nr" }
|
||||
"ui.linenr.selected" = { fg = "line_nr_selected", modifiers = ["bold"] }
|
||||
"ui.statusline" = { fg = "status_fg", bg = "status_bg" }
|
||||
"ui.statusline.inactive" = { fg = "status_inactive_fg", bg = "status_inactive_bg" }
|
||||
"ui.menu" = { fg = "menu_fg", bg = "menu_bg" }
|
||||
"ui.menu.selected" = { fg = "menu_sel_fg", bg = "menu_sel_bg" }
|
||||
"ui.menu.scroll" = { fg = "menu_scroll_fg", bg = "menu_scroll_bg" }
|
||||
"ui.popup" = { fg = "popup_fg", bg = "popup_bg" }
|
||||
"ui.match_paren" = { fg = "match_paren_fg", bg = "match_paren_bg", modifiers = ["bold"] }
|
||||
"ui.virtual" = { fg = "comment_fg" }
|
||||
"ui.virtual.ruler" = { bg = "virtual_ruler_bg" }
|
||||
|
||||
# Syntax Highlighting
|
||||
"comment" = { fg = "comment_fg", modifiers = ["italic"] }
|
||||
"string" = { fg = "string_fg" }
|
||||
"string.special" = { fg = "string_special_fg" }
|
||||
"constant" = { fg = "constant_fg" }
|
||||
"constant.builtin" = { fg = "constant_builtin_fg", modifiers = ["bold"] }
|
||||
"number" = { fg = "number_fg" }
|
||||
"boolean" = { fg = "boolean_fg" }
|
||||
"function" = { fg = "function_fg", modifiers = ["bold"] } # Added bold for better distinction
|
||||
"function.builtin" = { fg = "function_builtin_fg", modifiers = ["bold"] }
|
||||
"keyword" = { fg = "keyword_fg", modifiers = ["bold"] }
|
||||
"keyword.control" = { fg = "keyword_control_fg", modifiers = ["bold"] }
|
||||
"operator" = { fg = "operator_fg" }
|
||||
"variable" = { fg = "variable_fg" }
|
||||
"variable.builtin" = { fg = "variable_builtin_fg", modifiers = ["italic"] }
|
||||
"type" = { fg = "type_fg", modifiers = ["italic"] }
|
||||
"type.builtin" = { fg = "type_builtin_fg", modifiers = ["italic"] }
|
||||
"attribute" = { fg = "attribute_fg" }
|
||||
"namespace" = { fg = "namespace_fg" }
|
||||
"punctuation" = { fg = "punctuation_fg" }
|
||||
"symbol" = { fg = "symbol_fg", modifiers = ["italic"] }
|
||||
|
||||
# Diagnostics
|
||||
"diagnostic.error" = { fg = "error_fg", modifiers = ["bold"] }
|
||||
"diagnostic.warning" = { fg = "warning_fg", modifiers = ["bold"] }
|
||||
"diagnostic.info" = { fg = "info_fg", modifiers = ["bold"] }
|
||||
"diagnostic.hint" = { fg = "hint_fg", modifiers = ["bold"] }
|
||||
|
||||
# Diff
|
||||
"diff.plus" = { fg = "diff_add_fg" }
|
||||
"diff.minus" = { fg = "diff_delete_fg" }
|
||||
"diff.delta" = { fg = "diff_change_fg" }
|
||||
|
||||
# Markup
|
||||
"markup.heading" = { fg = "markup_heading_fg", modifiers = ["bold"] }
|
||||
"markup.bold" = { fg = "markup_bold_fg", modifiers = ["bold"] }
|
||||
"markup.italic" = { fg = "markup_italic_fg", modifiers = ["italic"] }
|
||||
"markup.link.url" = { fg = "markup_link_url_fg", modifiers = ["underlined"] }
|
||||
"markup.link.text" = { fg = "markup_link_text_fg" }
|
||||
"markup.quote" = { fg = "markup_quote_fg", modifiers = ["italic"] }
|
||||
|
||||
# Palette
|
||||
[palette]
|
||||
background = "#F7F7FF" # Off-white background (from your visual identity)
|
||||
foreground = "#1E1E2E" # Deep navy foreground (from your visual identity)
|
||||
cursor_fg = "#F7F7FF" # Off-white cursor text
|
||||
cursor_bg = "#9655FF" # Deep purple cursor (from your visual identity)
|
||||
cursorline = "#E8E8F0" # Slightly darker than background
|
||||
selection = "#FEF5BC" # Soft yellow selection (from your visual identity)
|
||||
line_nr = "#6E6A86" # Medium gray for line numbers
|
||||
line_nr_selected = "#1E1E2E" # Deep navy for selected line number
|
||||
status_fg = "#1E1E2E" # Deep navy
|
||||
status_bg = "#E8E8F0" # Light gray
|
||||
status_inactive_fg = "#6E6A86" # Medium gray
|
||||
status_inactive_bg = "#F7F7FF" # Off-white
|
||||
menu_fg = "#1E1E2E" # Deep navy
|
||||
menu_bg = "#E8E8F0" # Light gray
|
||||
menu_sel_fg = "#F7F7FF" # Off-white
|
||||
menu_sel_bg = "#FEF5BC" # Soft yellow selection
|
||||
menu_scroll_fg = "#6E6A86" # Medium gray
|
||||
menu_scroll_bg = "#E8E8F0" # Light gray
|
||||
popup_fg = "#1E1E2E" # Deep navy
|
||||
popup_bg = "#E8E8F0" # Light gray
|
||||
match_paren_fg = "#1E1E2E" # Deep navy
|
||||
match_paren_bg = "#FEF5BC" # Soft yellow
|
||||
virtual_ruler_bg = "#EAEAF0" # Slightly lighter than comment color background
|
||||
|
||||
comment_fg = "#6E6A86" # Medium gray comments
|
||||
string_fg = "#FEF5BC" # Soft yellow strings (from your visual identity)
|
||||
string_special_fg = "#F28FAD" # Pink special strings
|
||||
constant_fg = "#F28FAD" # Pink constants
|
||||
constant_builtin_fg = "#F28FAD" # Pink built-in constants
|
||||
number_fg = "#F8BD96" # Peach numbers
|
||||
boolean_fg = "#F28FAD" # Pink booleans
|
||||
function_fg = "#005F87" # Dark blue functions (more distinguishable)
|
||||
function_builtin_fg = "#005F87" # Dark blue built-in functions
|
||||
keyword_fg = "#9655FF" # Deep purple keywords
|
||||
keyword_control_fg = "#9655FF" # Deep purple control keywords
|
||||
operator_fg = "#6E6A86" # Medium gray operators (adjusted for better contrast)
|
||||
variable_fg = "#1E1E2E" # Deep navy variables
|
||||
variable_builtin_fg = "#F28FAD" # Pink built-in variables
|
||||
type_fg = "#C9CBFF" # Lavender types
|
||||
type_builtin_fg = "#C9CBFF" # Lavender built-in types
|
||||
attribute_fg = "#9655FF" # Deep purple attributes
|
||||
namespace_fg = "#9655FF" # Deep purple namespaces
|
||||
punctuation_fg = "#1E1E2E" # Deep navy punctuation
|
||||
symbol_fg = "#F28FAD" # Pink symbols (e.g., Elixir atoms)
|
||||
|
||||
error_fg = "#E78284" # Soft red errors
|
||||
warning_fg = "#E5C890" # Soft yellow warnings
|
||||
info_fg = "#8CAAEE" # Soft blue info
|
||||
hint_fg = "#8BD5CA" # Soft cyan hints
|
||||
|
||||
diff_add_fg = "#A6DA95" # Soft green additions
|
||||
diff_delete_fg = "#E78284" # Soft red deletions
|
||||
diff_change_fg = "#E5C890" # Soft yellow changes
|
||||
|
||||
markup_heading_fg = "#9655FF" # Deep purple headings
|
||||
markup_bold_fg = "#1E1E2E" # Deep navy bold text
|
||||
markup_italic_fg = "#1E1E2E" # Deep navy italic text
|
||||
markup_link_url_fg = "#005F87" # Dark blue links
|
||||
markup_link_text_fg = "#9655FF" # Deep purple link text
|
||||
markup_quote_fg = "#6E6A86" # Gray quotes
|
|
@ -0,0 +1,83 @@
|
|||
# nyxvamp: veil variant
|
||||
# author: zoedsoupe <zoey.spessanha@zeetech.io>
|
||||
|
||||
inherits = "nyxvamp-radiance"
|
||||
|
||||
# Override specific styles for veil variant
|
||||
"function" = { fg = "function_fg", modifiers = ["bold"] }
|
||||
"function.builtin" = { fg = "function_builtin_fg", modifiers = ["bold"] }
|
||||
"ui.match_paren" = { fg = "match_paren_fg", bg = "match_paren_bg", modifiers = ["bold"] }
|
||||
|
||||
# Palette overrides
|
||||
[palette]
|
||||
# Dark theme colors - only override what's different from the base theme
|
||||
background = "#1E1E2E" # Dark purple background
|
||||
foreground = "#D9E0EE" # Light lavender foreground
|
||||
cursor_fg = "#1E1E2E"
|
||||
cursor_bg = "#F5C2E7" # Soft pink cursor
|
||||
cursorline = "#2E2E3E" # Slightly lighter background
|
||||
selection = "#494D64" # Grayish selection
|
||||
line_nr = "#6E6A86" # Medium gray for line numbers
|
||||
line_nr_selected = "#D9E0EE" # Foreground color for selected line number
|
||||
|
||||
# Status line colors
|
||||
status_fg = "#D9E0EE"
|
||||
status_bg = "#302D41"
|
||||
status_inactive_fg = "#6E6A86"
|
||||
status_inactive_bg = "#1E1E2E"
|
||||
|
||||
# Menu colors
|
||||
menu_fg = "#D9E0EE"
|
||||
menu_bg = "#1E1E2E"
|
||||
menu_sel_fg = "#1E1E2E"
|
||||
menu_sel_bg = "#F5C2E7"
|
||||
menu_scroll_fg = "#6E6A86"
|
||||
menu_scroll_bg = "#1E1E2E"
|
||||
popup_fg = "#D9E0EE"
|
||||
popup_bg = "#1E1E2E"
|
||||
|
||||
# UI virtual
|
||||
virtual_ruler_bg = "#2A2A3C" # Slightly lighter than background, close to comment color
|
||||
|
||||
# Syntax highlighting
|
||||
match_paren_fg = "#F28FAD"
|
||||
match_paren_bg = "#1E1E2E"
|
||||
comment_fg = "#6E6A86" # Gray comments
|
||||
string_fg = "#ABE9B3" # Green strings
|
||||
string_special_fg = "#F28FAD" # Pink special strings
|
||||
constant_fg = "#F28FAD" # Pink constants
|
||||
constant_builtin_fg = "#F28FAD" # Pink built-in constants
|
||||
number_fg = "#F8BD96" # Peach numbers
|
||||
boolean_fg = "#F28FAD" # Pink booleans
|
||||
function_fg = "#96CDFB" # Blue functions
|
||||
function_builtin_fg = "#96CDFB" # Blue built-in functions
|
||||
keyword_fg = "#F5C2E7" # Pink keywords
|
||||
keyword_control_fg = "#F5C2E7" # Pink control keywords
|
||||
operator_fg = "#D9E0EE" # Foreground color for operators
|
||||
variable_fg = "#D9E0EE" # Foreground color for variables
|
||||
variable_builtin_fg = "#F28FAD" # Pink built-in variables
|
||||
type_fg = "#C9CBFF" # Lavender types
|
||||
type_builtin_fg = "#C9CBFF" # Lavender built-in types
|
||||
attribute_fg = "#F5C2E7" # Pink attributes
|
||||
namespace_fg = "#DDB6F2" # Purple namespaces
|
||||
punctuation_fg = "#D9E0EE" # Foreground color for punctuation
|
||||
symbol_fg = "#F28FAD" # Pink symbols (e.g., Elixir atoms)
|
||||
|
||||
# Diagnostics
|
||||
error_fg = "#E78284" # Red errors
|
||||
warning_fg = "#E5C890" # Yellow warnings
|
||||
info_fg = "#8CAAEE" # Blue info
|
||||
hint_fg = "#8BD5CA" # Cyan hints
|
||||
|
||||
# Diff colors
|
||||
diff_add_fg = "#A6DA95" # Green additions
|
||||
diff_delete_fg = "#E78284" # Red deletions
|
||||
diff_change_fg = "#E5C890" # Yellow changes
|
||||
|
||||
# Markup colors
|
||||
markup_heading_fg = "#F5C2E7" # Pink headings
|
||||
markup_bold_fg = "#F5C2E7" # Pink bold text
|
||||
markup_italic_fg = "#F5C2E7" # Pink italic text
|
||||
markup_link_url_fg = "#96CDFB" # Blue links
|
||||
markup_link_text_fg = "#F5C2E7" # Pink link text
|
||||
markup_quote_fg = "#6E6A86" # Gray quotes
|
Loading…
Reference in New Issue