Merge branch 'master' into 2nd-filename-extension

pull/13549/head
Nik Revenco 2025-05-17 02:43:23 +01:00
commit 222b24ae6b
8 changed files with 465 additions and 176 deletions

View File

@ -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 |

View File

@ -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),
}
}

View File

@ -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,
};

View File

@ -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())
}
}

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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