editor: Improve line number width by max lines. (#1291)
This commit is contained in:
parent
6b7a481fc8
commit
13e2b08873
2 changed files with 57 additions and 50 deletions
|
|
@ -1,10 +1,9 @@
|
|||
use gpui::*;
|
||||
use gpui_component::{
|
||||
highlighter::{HighlightTheme, Language},
|
||||
highlighter::Language,
|
||||
input::{InputEvent, InputState, TabSize, TextInput},
|
||||
resizable::{h_resizable, resizable_panel, ResizableState},
|
||||
text::{TextView, TextViewStyle},
|
||||
ActiveTheme as _,
|
||||
text::TextView,
|
||||
};
|
||||
use story::Assets;
|
||||
|
||||
|
|
@ -48,14 +47,6 @@ impl Example {
|
|||
|
||||
impl Render for Example {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let theme = if cx.theme().mode.is_dark() {
|
||||
HighlightTheme::default_dark()
|
||||
} else {
|
||||
HighlightTheme::default_light()
|
||||
};
|
||||
|
||||
let is_dark = cx.theme().mode.is_dark();
|
||||
|
||||
h_resizable("container", self.resizable_state.clone())
|
||||
.child(
|
||||
resizable_panel().child(
|
||||
|
|
@ -68,7 +59,7 @@ impl Render for Example {
|
|||
TextInput::new(&self.input_state)
|
||||
.h_full()
|
||||
.p_0()
|
||||
.appearance(false)
|
||||
.border_0()
|
||||
.focus_bordered(false),
|
||||
),
|
||||
),
|
||||
|
|
@ -87,12 +78,7 @@ impl Render for Example {
|
|||
window,
|
||||
cx,
|
||||
)
|
||||
.selectable()
|
||||
.style(TextViewStyle {
|
||||
highlight_theme: theme.clone(),
|
||||
is_dark,
|
||||
..Default::default()
|
||||
}),
|
||||
.selectable(),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use gpui::{
|
|||
fill, point, px, relative, size, App, Bounds, Corners, Element, ElementId, ElementInputHandler,
|
||||
Entity, GlobalElementId, Half, HighlightStyle, Hitbox, IntoElement, LayoutId, MouseButton,
|
||||
MouseMoveEvent, Path, Pixels, Point, ShapedLine, SharedString, Size, Style, TextAlign, TextRun,
|
||||
UnderlineStyle, Window,
|
||||
TextStyle, UnderlineStyle, Window,
|
||||
};
|
||||
use ropey::Rope;
|
||||
use smallvec::SmallVec;
|
||||
|
|
@ -483,6 +483,45 @@ impl TextElement {
|
|||
(visible_range, visible_top)
|
||||
}
|
||||
|
||||
/// Return (line_number_width, line_number_len)
|
||||
fn layout_line_numbers(
|
||||
state: &InputState,
|
||||
text: &Rope,
|
||||
font_size: Pixels,
|
||||
style: &TextStyle,
|
||||
window: &mut Window,
|
||||
) -> (Pixels, usize) {
|
||||
let total_lines = text.lines_len();
|
||||
let line_number_len = match total_lines {
|
||||
0..=9999 => 5,
|
||||
10000..=99999 => 6,
|
||||
100000..=999999 => 7,
|
||||
_ => 8,
|
||||
};
|
||||
|
||||
let line_number_width = if state.mode.line_number() {
|
||||
let empty_line_number = window.text_system().shape_line(
|
||||
"+".repeat(line_number_len).into(),
|
||||
font_size,
|
||||
&[TextRun {
|
||||
len: line_number_len,
|
||||
font: style.font(),
|
||||
color: gpui::black(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
}],
|
||||
None,
|
||||
);
|
||||
|
||||
empty_line_number.width + px(6.) + LINE_NUMBER_RIGHT_MARGIN
|
||||
} else {
|
||||
px(0.)
|
||||
};
|
||||
|
||||
(line_number_width, line_number_len)
|
||||
}
|
||||
|
||||
/// First usize is the offset of skipped.
|
||||
fn highlight_lines(
|
||||
&mut self,
|
||||
|
|
@ -670,39 +709,23 @@ impl Element for TextElement {
|
|||
|
||||
let (display_text, text_color) = if is_empty {
|
||||
(
|
||||
Rope::from(placeholder.as_str()),
|
||||
&Rope::from(placeholder.as_str()),
|
||||
cx.theme().muted_foreground,
|
||||
)
|
||||
} else if state.masked {
|
||||
(
|
||||
Rope::from("*".repeat(text.chars().count())),
|
||||
&Rope::from("*".repeat(text.chars().count())),
|
||||
cx.theme().foreground,
|
||||
)
|
||||
} else {
|
||||
(text.clone(), cx.theme().foreground)
|
||||
(&text, cx.theme().foreground)
|
||||
};
|
||||
|
||||
let text_style = window.text_style();
|
||||
|
||||
// Calculate the width of the line numbers
|
||||
let empty_line_number = window.text_system().shape_line(
|
||||
"++++++".into(),
|
||||
font_size,
|
||||
&[TextRun {
|
||||
len: 6,
|
||||
font: style.font(),
|
||||
color: gpui::black(),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
}],
|
||||
None,
|
||||
);
|
||||
let line_number_width = if state.mode.line_number() {
|
||||
empty_line_number.width + px(6.) + LINE_NUMBER_RIGHT_MARGIN
|
||||
} else {
|
||||
px(0.)
|
||||
};
|
||||
let (line_number_width, line_number_len) =
|
||||
Self::layout_line_numbers(&state, &text, font_size, &text_style, window);
|
||||
|
||||
let run = TextRun {
|
||||
len: display_text.len(),
|
||||
|
|
@ -881,9 +904,8 @@ impl Element for TextElement {
|
|||
let state = self.state.read(cx);
|
||||
let line_numbers = if state.mode.line_number() {
|
||||
let mut line_numbers = vec![];
|
||||
let run_len = 6;
|
||||
let other_line_runs = vec![TextRun {
|
||||
len: run_len,
|
||||
len: line_number_len,
|
||||
font: style.font(),
|
||||
color: cx.theme().muted_foreground,
|
||||
background_color: None,
|
||||
|
|
@ -891,7 +913,7 @@ impl Element for TextElement {
|
|||
strikethrough: None,
|
||||
}];
|
||||
let current_line_runs = vec![TextRun {
|
||||
len: run_len,
|
||||
len: line_number_len,
|
||||
font: style.font(),
|
||||
color: cx.theme().foreground,
|
||||
background_color: None,
|
||||
|
|
@ -902,7 +924,7 @@ impl Element for TextElement {
|
|||
// build line numbers
|
||||
for (ix, line) in last_layout.lines.iter().enumerate() {
|
||||
let ix = last_layout.visible_range.start + ix;
|
||||
let line_no_text = format!("{:>6}", ix + 1);
|
||||
let line_no = format!("{:>width$}", ix + 1, width = line_number_len).into();
|
||||
|
||||
let runs = if current_row == Some(ix) {
|
||||
¤t_line_runs
|
||||
|
|
@ -911,12 +933,11 @@ impl Element for TextElement {
|
|||
};
|
||||
|
||||
let mut sub_lines: SmallVec<[ShapedLine; 1]> = SmallVec::new();
|
||||
sub_lines.push(window.text_system().shape_line(
|
||||
line_no_text.into(),
|
||||
font_size,
|
||||
&runs,
|
||||
None,
|
||||
));
|
||||
sub_lines.push(
|
||||
window
|
||||
.text_system()
|
||||
.shape_line(line_no, font_size, &runs, None),
|
||||
);
|
||||
for _ in 0..line.wrap_boundaries.len() {
|
||||
sub_lines.push(ShapedLine::default());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue