Skip to content

Commit

Permalink
Implement line numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
jackpot51 committed Nov 30, 2023
1 parent 4a3dd10 commit 2494a73
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 53 deletions.
46 changes: 23 additions & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ pub struct Config {
pub auto_indent: bool,
pub font_name: String,
pub font_size: u16,
pub line_numbers: bool,
pub syntax_theme_dark: String,
pub syntax_theme_light: String,
pub tab_width: u16,
Expand All @@ -165,6 +166,7 @@ impl Default for Config {
auto_indent: true,
font_name: "Fira Mono".to_string(),
font_size: 14,
line_numbers: true,
syntax_theme_dark: "gruvbox-dark".to_string(),
syntax_theme_light: "gruvbox-light".to_string(),
tab_width: 4,
Expand Down
49 changes: 49 additions & 0 deletions src/line_number.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use cosmic_text::{
Align, Attrs, AttrsList, BufferLine, Family, FontSystem, LayoutLine, ShapeBuffer, Shaping, Wrap,
};
use std::collections::HashMap;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct LineNumberKey {
pub number: usize,
pub width: usize,
}

#[derive(Debug)]
pub struct LineNumberCache {
cache: HashMap<LineNumberKey, Vec<LayoutLine>>,
scratch: ShapeBuffer,
}

impl LineNumberCache {
pub fn new() -> Self {
Self {
cache: HashMap::new(),
scratch: ShapeBuffer::default(),
}
}

pub fn clear(&mut self) {
self.cache.clear();
}

pub fn get(&mut self, font_system: &mut FontSystem, key: LineNumberKey) -> &Vec<LayoutLine> {
self.cache.entry(key).or_insert_with(|| {
//TODO: do not repeat, used in App::init
let attrs = Attrs::new().family(Family::Monospace);
let text = format!("{:width$}", key.number, width = key.width);
let mut buffer_line = BufferLine::new(text, AttrsList::new(attrs), Shaping::Advanced);
buffer_line.set_wrap(Wrap::None);
buffer_line.set_align(Some(Align::Left));
buffer_line
.layout_in_buffer(
&mut self.scratch,
font_system,
1.0, /* font size adjusted later */
1000.0, /* dummy width */
Wrap::None,
)
.to_vec()
})
}
}
30 changes: 29 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ mod config;
use icon_cache::IconCache;
mod icon_cache;

use line_number::LineNumberCache;
mod line_number;

mod localize;

pub use self::mime_icon::{mime_icon, FALLBACK_MIME_ICON};
Expand All @@ -56,6 +59,7 @@ mod text_box;
lazy_static::lazy_static! {
static ref FONT_SYSTEM: Mutex<FontSystem> = Mutex::new(FontSystem::new());
static ref ICON_CACHE: Mutex<IconCache> = Mutex::new(IconCache::new());
static ref LINE_NUMBER_CACHE: Mutex<LineNumberCache> = Mutex::new(LineNumberCache::new());
static ref SWASH_CACHE: Mutex<SwashCache> = Mutex::new(SwashCache::new());
static ref SYNTAX_SYSTEM: SyntaxSystem = {
let lazy_theme_set = two_face::theme::LazyThemeSet::from(two_face::theme::extra());
Expand Down Expand Up @@ -190,6 +194,7 @@ pub enum Message {
Todo,
ToggleAutoIndent,
ToggleContextPage(ContextPage),
ToggleLineNumbers,
ToggleWordWrap,
Undo,
VimBindings(bool),
Expand Down Expand Up @@ -734,6 +739,12 @@ impl Application for App {
font_system.db_mut().set_monospace_family(font_name);
}

// Reset line number cache
{
let mut line_number_cache = LINE_NUMBER_CACHE.lock().unwrap();
line_number_cache.clear();
}

// This does a complete reset of shaping data!
let entities: Vec<_> = self.tab_model.iter().collect();
for entity in entities {
Expand Down Expand Up @@ -1130,6 +1141,20 @@ impl Application for App {
}
}
}
Message::ToggleLineNumbers => {
self.config.line_numbers = !self.config.line_numbers;

// This forces a redraw of all buffers
let entities: Vec<_> = self.tab_model.iter().collect();
for entity in entities {
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
let mut editor = tab.editor.lock().unwrap();
editor.buffer_mut().set_redraw(true);
}
}

return self.save_config();
}
Message::ToggleWordWrap => {
self.config.word_wrap = !self.config.word_wrap;
return self.save_config();
Expand Down Expand Up @@ -1424,11 +1449,14 @@ impl Application for App {
}
}
};
let text_box = text_box(&tab.editor, self.config.metrics())
let mut text_box = text_box(&tab.editor, self.config.metrics())
.on_changed(Message::TabChanged(tab_id))
.on_context_menu(move |position_opt| {
Message::TabContextMenu(tab_id, position_opt)
});
if self.config.line_numbers {
text_box = text_box.line_numbers();
}
let tab_element: Element<'_, Message> = match tab.context_menu {
Some(position) => widget::popover(
text_box.context_menu(position),
Expand Down
6 changes: 5 additions & 1 deletion src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,11 @@ pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
),
MenuTree::new(horizontal_rule(1)),
menu_checkbox(fl!("word-wrap"), config.word_wrap, Message::ToggleWordWrap),
menu_checkbox(fl!("show-line-numbers"), false, Message::Todo),
menu_checkbox(
fl!("show-line-numbers"),
config.line_numbers,
Message::ToggleLineNumbers,
),
menu_checkbox(fl!("highlight-current-line"), false, Message::Todo),
menu_item(fl!("syntax-highlighting"), Message::Todo),
MenuTree::new(horizontal_rule(1)),
Expand Down
Loading

0 comments on commit 2494a73

Please sign in to comment.