mirror of https://github.com/lapce/lapce.git
Update floem for editor styling (#3122)
This commit is contained in:
parent
9cd3bcc611
commit
571485f1a6
|
@ -1672,7 +1672,7 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
|||
[[package]]
|
||||
name = "floem"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/lapce/floem?rev=eba11fbdea84bfac0b90da5f26e1045597e897a4#eba11fbdea84bfac0b90da5f26e1045597e897a4"
|
||||
source = "git+https://github.com/lapce/floem?rev=fbd5f4db12db93b3fcbe047df6f6cc054e8ff634#fbd5f4db12db93b3fcbe047df6f6cc054e8ff634"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"copypasta",
|
||||
|
@ -1734,7 +1734,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "floem-editor-core"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/lapce/floem?rev=eba11fbdea84bfac0b90da5f26e1045597e897a4#eba11fbdea84bfac0b90da5f26e1045597e897a4"
|
||||
source = "git+https://github.com/lapce/floem?rev=fbd5f4db12db93b3fcbe047df6f6cc054e8ff634#fbd5f4db12db93b3fcbe047df6f6cc054e8ff634"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"itertools",
|
||||
|
@ -1822,7 +1822,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "floem_reactive"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/lapce/floem?rev=eba11fbdea84bfac0b90da5f26e1045597e897a4#eba11fbdea84bfac0b90da5f26e1045597e897a4"
|
||||
source = "git+https://github.com/lapce/floem?rev=fbd5f4db12db93b3fcbe047df6f6cc054e8ff634#fbd5f4db12db93b3fcbe047df6f6cc054e8ff634"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
@ -1830,7 +1830,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "floem_renderer"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/lapce/floem?rev=eba11fbdea84bfac0b90da5f26e1045597e897a4#eba11fbdea84bfac0b90da5f26e1045597e897a4"
|
||||
source = "git+https://github.com/lapce/floem?rev=fbd5f4db12db93b3fcbe047df6f6cc054e8ff634#fbd5f4db12db93b3fcbe047df6f6cc054e8ff634"
|
||||
dependencies = [
|
||||
"floem-cosmic-text",
|
||||
"floem-peniko",
|
||||
|
@ -1841,7 +1841,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "floem_tiny_skia_renderer"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/lapce/floem?rev=eba11fbdea84bfac0b90da5f26e1045597e897a4#eba11fbdea84bfac0b90da5f26e1045597e897a4"
|
||||
source = "git+https://github.com/lapce/floem?rev=fbd5f4db12db93b3fcbe047df6f6cc054e8ff634#fbd5f4db12db93b3fcbe047df6f6cc054e8ff634"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytemuck",
|
||||
|
@ -1858,7 +1858,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "floem_vger_renderer"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/lapce/floem?rev=eba11fbdea84bfac0b90da5f26e1045597e897a4#eba11fbdea84bfac0b90da5f26e1045597e897a4"
|
||||
source = "git+https://github.com/lapce/floem?rev=fbd5f4db12db93b3fcbe047df6f6cc054e8ff634#fbd5f4db12db93b3fcbe047df6f6cc054e8ff634"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"floem-peniko",
|
||||
|
|
|
@ -71,7 +71,7 @@ lapce-core = { path = "./lapce-core" }
|
|||
lapce-rpc = { path = "./lapce-rpc" }
|
||||
lapce-proxy = { path = "./lapce-proxy" }
|
||||
|
||||
floem-editor-core = { git = "https://github.com/lapce/floem", rev = "eba11fbdea84bfac0b90da5f26e1045597e897a4", features = ["serde"] }
|
||||
floem-editor-core = { git = "https://github.com/lapce/floem", rev = "fbd5f4db12db93b3fcbe047df6f6cc054e8ff634", features = ["serde"] }
|
||||
# floem-editor-core = { path = "../workspaces/floem/editor-core/", features = ["serde"] }
|
||||
|
||||
[patch.crates-io]
|
||||
|
|
|
@ -66,7 +66,7 @@ floem-winit = { version = "0.29.4", features = ["rwh_05"] }
|
|||
[dependencies.floem]
|
||||
# path = "../../workspaces/floem"
|
||||
git = "https://github.com/lapce/floem"
|
||||
rev = "eba11fbdea84bfac0b90da5f26e1045597e897a4"
|
||||
rev = "fbd5f4db12db93b3fcbe047df6f6cc054e8ff634"
|
||||
default-features = true
|
||||
features = ["editor", "serde"]
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
layout::TextLayoutLine,
|
||||
phantom_text::PhantomTextLine,
|
||||
visual_line::{
|
||||
FontSizeCacheId, LineFontSizeProvider, Lines, ResolvedWrap,
|
||||
ConfigId, FontSizeCacheId, LineFontSizeProvider, Lines, ResolvedWrap,
|
||||
TextLayoutProvider, VLine,
|
||||
},
|
||||
},
|
||||
|
@ -167,7 +167,7 @@ fn make_lines_ph(
|
|||
lines.set_wrap(wrap);
|
||||
|
||||
if init {
|
||||
lines.init_all(0, 0, &text, true);
|
||||
lines.init_all(0, ConfigId::new(0, 0), &text, true);
|
||||
}
|
||||
|
||||
(text, lines)
|
||||
|
|
|
@ -33,8 +33,10 @@
|
|||
view::{View, Widget},
|
||||
views::{
|
||||
clip, container, drag_resize_window_area, drag_window_area, dyn_stack,
|
||||
empty, label, rich_text, scroll::scroll, stack, svg, tab, text, tooltip,
|
||||
virtual_stack, Decorators, VirtualDirection, VirtualItemSize, VirtualVector,
|
||||
empty, label, rich_text,
|
||||
scroll::{scroll, HideBar, VerticalScrollAsHorizontal},
|
||||
stack, svg, tab, text, tooltip, virtual_stack, Decorators, VirtualDirection,
|
||||
VirtualItemSize, VirtualVector,
|
||||
},
|
||||
window::{ResizeDirection, WindowConfig, WindowId},
|
||||
EventPropagation,
|
||||
|
@ -941,10 +943,10 @@ fn editor_tab_header(
|
|||
.with_untracked(|editor_tab| editor_tab.children[active].1)
|
||||
.get_untracked()
|
||||
})
|
||||
.hide_bar(|| true)
|
||||
.vertical_scroll_as_horizontal(|| true)
|
||||
.style(|s| {
|
||||
s.position(Position::Absolute)
|
||||
s.set(HideBar, true)
|
||||
.set(VerticalScrollAsHorizontal, true)
|
||||
.position(Position::Absolute)
|
||||
.height_full()
|
||||
.max_width_full()
|
||||
})
|
||||
|
|
|
@ -18,17 +18,13 @@
|
|||
reactive::{batch, ReadSignal, RwSignal, Scope},
|
||||
views::editor::{
|
||||
actions::CommonAction,
|
||||
color::EditorColor,
|
||||
command::{Command, CommandExecuted},
|
||||
id::EditorId,
|
||||
layout::{LineExtraStyle, TextLayoutLine},
|
||||
phantom_text::{PhantomText, PhantomTextKind, PhantomTextLine},
|
||||
text::{
|
||||
Document, DocumentPhantom, PreeditData, RenderWhitespace, Styling,
|
||||
SystemClipboard, WrapMethod,
|
||||
},
|
||||
text::{Document, DocumentPhantom, PreeditData, Styling, SystemClipboard},
|
||||
view::{ScreenLines, ScreenLinesBase},
|
||||
CursorInfo, Editor,
|
||||
CursorInfo, Editor, EditorStyle,
|
||||
},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
@ -71,7 +67,7 @@
|
|||
|
||||
use crate::{
|
||||
command::{CommandKind, LapceCommand},
|
||||
config::{color::LapceColor, editor::WrapStyle, LapceConfig},
|
||||
config::{color::LapceColor, LapceConfig},
|
||||
editor::{compute_screen_lines, EditorData},
|
||||
find::{Find, FindProgress, FindResult},
|
||||
history::DocumentHistory,
|
||||
|
@ -369,49 +365,6 @@ pub fn create_editor(self: &Rc<Doc>, cx: Scope, id: EditorId) -> Editor {
|
|||
editor.cursor_info = cursor_info;
|
||||
editor.ime_allowed = common.window_common.ime_allowed;
|
||||
|
||||
// Updating editor fields based on config
|
||||
let ed = editor.clone();
|
||||
cx.create_effect(move |_| {
|
||||
let config = config.get();
|
||||
|
||||
batch(|| {
|
||||
if ed.scroll_beyond_last_line.get_untracked()
|
||||
!= config.editor.scroll_beyond_last_line
|
||||
{
|
||||
ed.scroll_beyond_last_line
|
||||
.set(config.editor.scroll_beyond_last_line);
|
||||
}
|
||||
|
||||
if ed.cursor_surrounding_lines.get_untracked()
|
||||
!= config.editor.cursor_surrounding_lines
|
||||
{
|
||||
ed.cursor_surrounding_lines
|
||||
.set(config.editor.cursor_surrounding_lines);
|
||||
}
|
||||
|
||||
if ed.show_indent_guide.get_untracked()
|
||||
!= config.editor.show_indent_guide
|
||||
{
|
||||
ed.show_indent_guide.set(config.editor.show_indent_guide);
|
||||
}
|
||||
|
||||
if ed.modal_relative_line_numbers.get_untracked()
|
||||
!= config.editor.modal_mode_relative_line_numbers
|
||||
{
|
||||
ed.modal_relative_line_numbers
|
||||
.set(config.editor.modal_mode_relative_line_numbers);
|
||||
}
|
||||
|
||||
if ed.smart_tab.get_untracked() != config.editor.smart_tab {
|
||||
ed.smart_tab.set(config.editor.smart_tab);
|
||||
}
|
||||
|
||||
if ed.modal.get_untracked() != config.core.modal {
|
||||
ed.modal.set(config.core.modal);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
editor.recreate_view_effects();
|
||||
|
||||
editor
|
||||
|
@ -1458,6 +1411,7 @@ fn compute_screen_lines(
|
|||
&editor_data.doc_signal().get(),
|
||||
editor.lines(),
|
||||
editor.text_prov(),
|
||||
editor.config_id(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1504,7 +1458,7 @@ impl DocumentPhantom for Doc {
|
|||
fn phantom_text(
|
||||
&self,
|
||||
_: EditorId,
|
||||
_: &dyn Styling,
|
||||
_: &EditorStyle,
|
||||
line: usize,
|
||||
) -> PhantomTextLine {
|
||||
let config = &self.common.config.get_untracked();
|
||||
|
@ -1674,7 +1628,7 @@ fn phantom_text(
|
|||
PhantomTextLine { text }
|
||||
}
|
||||
|
||||
fn has_multiline_phantom(&self, _: EditorId, _: &dyn Styling) -> bool {
|
||||
fn has_multiline_phantom(&self, _: EditorId, _: &EditorStyle) -> bool {
|
||||
// TODO: actually check
|
||||
true
|
||||
}
|
||||
|
@ -1719,9 +1673,6 @@ fn do_edit(
|
|||
}
|
||||
}
|
||||
|
||||
/// Minimum width that we'll allow the view to be wrapped at.
|
||||
const MIN_WRAPPED_WIDTH: f32 = 100.0;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DocStyling {
|
||||
config: ReadSignal<Arc<LapceConfig>>,
|
||||
|
@ -1731,12 +1682,13 @@ impl DocStyling {
|
|||
fn apply_colorization(
|
||||
&self,
|
||||
edid: EditorId,
|
||||
style: &EditorStyle,
|
||||
line: usize,
|
||||
attrs: &Attrs,
|
||||
attrs_list: &mut AttrsList,
|
||||
) {
|
||||
let config = self.config.get_untracked();
|
||||
let phantom_text = self.doc.phantom_text(edid, self, line);
|
||||
let phantom_text = self.doc.phantom_text(edid, style, line);
|
||||
if let Some(bracket_styles) = self.doc.parser.borrow().bracket_pos.get(&line)
|
||||
{
|
||||
for bracket_style in bracket_styles.iter() {
|
||||
|
@ -1789,10 +1741,6 @@ fn stretch(&self, _: EditorId, _line: usize) -> floem::cosmic_text::Stretch {
|
|||
floem::cosmic_text::Stretch::Normal
|
||||
}
|
||||
|
||||
fn indent_style(&self) -> IndentStyle {
|
||||
self.doc.buffer.with_untracked(|b| b.indent_style())
|
||||
}
|
||||
|
||||
fn indent_line(&self, _: EditorId, line: usize, line_content: &str) -> usize {
|
||||
if line_content.trim().is_empty() {
|
||||
let text = self.doc.rope_text();
|
||||
|
@ -1819,15 +1767,16 @@ fn atomic_soft_tabs(&self, _: EditorId, _line: usize) -> bool {
|
|||
fn apply_attr_styles(
|
||||
&self,
|
||||
edid: EditorId,
|
||||
style: &EditorStyle,
|
||||
line: usize,
|
||||
default: Attrs,
|
||||
attrs_list: &mut AttrsList,
|
||||
) {
|
||||
let config = self.doc.common.config.get_untracked();
|
||||
|
||||
self.apply_colorization(edid, line, &default, attrs_list);
|
||||
self.apply_colorization(edid, style, line, &default, attrs_list);
|
||||
|
||||
let phantom_text = self.doc.phantom_text(edid, self, line);
|
||||
let phantom_text = self.doc.phantom_text(edid, style, line);
|
||||
for line_style in self.doc.line_style(line).iter() {
|
||||
if let Some(fg_color) = line_style.style.fg_color.as_ref() {
|
||||
if let Some(fg_color) = config.style_color(fg_color) {
|
||||
|
@ -1839,30 +1788,10 @@ fn apply_attr_styles(
|
|||
}
|
||||
}
|
||||
|
||||
fn wrap(&self, _: EditorId) -> WrapMethod {
|
||||
let wrap_style = self
|
||||
.config
|
||||
.with_untracked(|config| config.editor.wrap_style);
|
||||
match wrap_style {
|
||||
WrapStyle::None => WrapMethod::None,
|
||||
WrapStyle::EditorWidth => WrapMethod::EditorWidth,
|
||||
WrapStyle::WrapWidth => WrapMethod::WrapWidth {
|
||||
width: self
|
||||
.config
|
||||
.with_untracked(|config| config.editor.wrap_width as f32)
|
||||
.max(MIN_WRAPPED_WIDTH),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn render_whitespace(&self, _: EditorId) -> RenderWhitespace {
|
||||
self.config
|
||||
.with_untracked(|config| config.editor.render_whitespace)
|
||||
}
|
||||
|
||||
fn apply_layout_styles(
|
||||
&self,
|
||||
edid: EditorId,
|
||||
style: &EditorStyle,
|
||||
line: usize,
|
||||
layout_line: &mut TextLayoutLine,
|
||||
) {
|
||||
|
@ -1872,7 +1801,7 @@ fn apply_layout_styles(
|
|||
layout_line.extra_style.clear();
|
||||
let layout = &layout_line.text;
|
||||
|
||||
let phantom_text = doc.phantom_text(edid, self, line);
|
||||
let phantom_text = doc.phantom_text(edid, style, line);
|
||||
|
||||
let phantom_styles = phantom_text
|
||||
.offset_size_iter()
|
||||
|
@ -1978,17 +1907,6 @@ fn apply_layout_styles(
|
|||
});
|
||||
}
|
||||
|
||||
fn color(&self, _: EditorId, color: EditorColor) -> Color {
|
||||
let name = match color {
|
||||
EditorColor::Scrollbar => LapceColor::LAPCE_SCROLL_BAR,
|
||||
EditorColor::DropdownShadow => LapceColor::LAPCE_DROPDOWN_SHADOW,
|
||||
EditorColor::PreeditUnderline => LapceColor::EDITOR_FOREGROUND,
|
||||
_ => color.into(),
|
||||
};
|
||||
|
||||
self.config.with_untracked(|config| config.color(name))
|
||||
}
|
||||
|
||||
fn paint_caret(&self, edid: EditorId, _line: usize) -> bool {
|
||||
let Some(e_data) = self.doc.editor_data(edid) else {
|
||||
return true;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
view::{
|
||||
DiffSection, DiffSectionKind, LineInfo, ScreenLines, ScreenLinesBase,
|
||||
},
|
||||
visual_line::{Lines, TextLayoutProvider, VLine, VLineInfo},
|
||||
visual_line::{ConfigId, Lines, TextLayoutProvider, VLine, VLineInfo},
|
||||
Editor,
|
||||
},
|
||||
};
|
||||
|
@ -378,11 +378,8 @@ pub fn rope_text(&self) -> RopeTextVal {
|
|||
fn run_edit_command(&self, cmd: &EditCommand) -> CommandExecuted {
|
||||
let doc = self.doc();
|
||||
let text = self.editor.rope_text();
|
||||
let modal = self
|
||||
.common
|
||||
.config
|
||||
.with_untracked(|config| config.core.modal)
|
||||
&& !doc.content.with_untracked(|content| content.is_local());
|
||||
let is_local = doc.content.with_untracked(|content| content.is_local());
|
||||
let modal = self.editor.es.with_untracked(|s| s.modal()) && !is_local;
|
||||
let smart_tab = self
|
||||
.common
|
||||
.config
|
||||
|
@ -2833,6 +2830,7 @@ pub(crate) fn compute_screen_lines(
|
|||
doc: &Doc,
|
||||
lines: &Lines,
|
||||
text_prov: impl TextLayoutProvider + Clone,
|
||||
config_id: ConfigId,
|
||||
) -> ScreenLines {
|
||||
// TODO: this should probably be a get since we need to depend on line-height
|
||||
let config = config.get();
|
||||
|
@ -2885,7 +2883,7 @@ pub(crate) fn compute_screen_lines(
|
|||
.iter_rvlines_init(
|
||||
text_prov,
|
||||
cache_rev,
|
||||
config.id,
|
||||
config_id,
|
||||
min_info.rvline,
|
||||
false,
|
||||
)
|
||||
|
@ -3083,7 +3081,7 @@ pub(crate) fn compute_screen_lines(
|
|||
.iter_rvlines_init(
|
||||
&text_prov,
|
||||
cache_rev,
|
||||
config.id,
|
||||
config_id,
|
||||
start_rvline,
|
||||
false,
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use floem::{
|
||||
action::{set_ime_allowed, set_ime_cursor_area},
|
||||
context::PaintCx,
|
||||
context::{PaintCx, StyleCx},
|
||||
event::{Event, EventListener},
|
||||
id::Id,
|
||||
keyboard::ModifiersState,
|
||||
|
@ -13,36 +13,43 @@
|
|||
reactive::{
|
||||
create_effect, create_memo, create_rw_signal, Memo, ReadSignal, RwSignal,
|
||||
},
|
||||
style::{CursorStyle, Style},
|
||||
style::{CursorStyle, Style, TextColor},
|
||||
taffy::prelude::NodeId,
|
||||
view::{AnyWidget, View, ViewData, Widget},
|
||||
views::{
|
||||
clip, container, dyn_stack,
|
||||
editor::{
|
||||
text::WrapMethod,
|
||||
view::{
|
||||
cursor_caret, DiffSectionKind, EditorView as FloemEditorView,
|
||||
LineRegion, ScreenLines,
|
||||
cursor_caret, CaretColor, CurrentLineColor, DiffSectionKind,
|
||||
EditorView as FloemEditorView, EditorViewClass, EditorViewStyle,
|
||||
IndentGuideColor, IndentStyleProp, LineRegion, ScreenLines,
|
||||
SelectionColor, VisibleWhitespaceColor,
|
||||
},
|
||||
visual_line::{RVLine, VLine},
|
||||
Editor,
|
||||
CursorSurroundingLines, Editor, Modal, ModalRelativeLine, PhantomColor,
|
||||
PlaceholderColor, PreeditUnderlineColor, RenderWhitespaceProp,
|
||||
ScrollBeyondLastLine, ShowIndentGuide, SmartTab, WrapProp,
|
||||
},
|
||||
empty, label, scroll, stack, svg, Decorators,
|
||||
empty, label,
|
||||
scroll::{scroll, HideBar},
|
||||
stack, svg, Decorators,
|
||||
},
|
||||
EventPropagation, Renderer,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use lapce_core::{
|
||||
buffer::{diff::DiffLines, rope_text::RopeText},
|
||||
buffer::{diff::DiffLines, rope_text::RopeText, Buffer},
|
||||
cursor::{CursorAffinity, CursorMode},
|
||||
};
|
||||
use lapce_rpc::dap_types::{DapId, SourceBreakpoint};
|
||||
use lapce_xi_rope::find::CaseMatching;
|
||||
|
||||
use super::{gutter::editor_gutter_view, EditorData};
|
||||
use super::{gutter::editor_gutter_view, DocSignal, EditorData};
|
||||
use crate::{
|
||||
app::clickable_icon,
|
||||
command::InternalCommand,
|
||||
config::{color::LapceColor, icon::LapceIcons, LapceConfig},
|
||||
config::{color::LapceColor, editor::WrapStyle, icon::LapceIcons, LapceConfig},
|
||||
debug::LapceBreakpoint,
|
||||
doc::DocContent,
|
||||
text_input::TextInputBuilder,
|
||||
|
@ -56,6 +63,71 @@ struct StickyHeaderInfo {
|
|||
y_diff: f64,
|
||||
}
|
||||
|
||||
fn editor_wrap(config: &LapceConfig) -> WrapMethod {
|
||||
/// Minimum width that we'll allow the view to be wrapped at.
|
||||
const MIN_WRAPPED_WIDTH: f32 = 100.0;
|
||||
|
||||
match config.editor.wrap_style {
|
||||
WrapStyle::None => WrapMethod::None,
|
||||
WrapStyle::EditorWidth => WrapMethod::EditorWidth,
|
||||
WrapStyle::WrapWidth => WrapMethod::WrapWidth {
|
||||
width: (config.editor.wrap_width as f32).max(MIN_WRAPPED_WIDTH),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn editor_style(
|
||||
config: ReadSignal<Arc<LapceConfig>>,
|
||||
doc: DocSignal,
|
||||
s: Style,
|
||||
) -> Style {
|
||||
let config = config.get();
|
||||
let doc = doc.get();
|
||||
// s.class(EditorViewClass, |s| {
|
||||
|
||||
s.set(
|
||||
IndentStyleProp,
|
||||
doc.buffer.with_untracked(Buffer::indent_style),
|
||||
)
|
||||
.set(CaretColor, config.color(LapceColor::EDITOR_CARET))
|
||||
.set(SelectionColor, config.color(LapceColor::EDITOR_SELECTION))
|
||||
.set(
|
||||
CurrentLineColor,
|
||||
config.color(LapceColor::EDITOR_CURRENT_LINE),
|
||||
)
|
||||
.set(
|
||||
VisibleWhitespaceColor,
|
||||
config.color(LapceColor::EDITOR_VISIBLE_WHITESPACE),
|
||||
)
|
||||
.set(
|
||||
IndentGuideColor,
|
||||
config.color(LapceColor::EDITOR_INDENT_GUIDE),
|
||||
)
|
||||
.set(ScrollBeyondLastLine, config.editor.scroll_beyond_last_line)
|
||||
// })
|
||||
.color(config.color(LapceColor::EDITOR_FOREGROUND))
|
||||
.set(TextColor, config.color(LapceColor::EDITOR_FOREGROUND))
|
||||
.set(PhantomColor, config.color(LapceColor::EDITOR_DIM))
|
||||
.set(PlaceholderColor, config.color(LapceColor::EDITOR_DIM))
|
||||
.set(
|
||||
PreeditUnderlineColor,
|
||||
config.color(LapceColor::EDITOR_FOREGROUND),
|
||||
)
|
||||
.set(ShowIndentGuide, config.editor.show_indent_guide)
|
||||
.set(Modal, config.core.modal)
|
||||
.set(
|
||||
ModalRelativeLine,
|
||||
config.editor.modal_mode_relative_line_numbers,
|
||||
)
|
||||
.set(SmartTab, config.editor.smart_tab)
|
||||
.set(WrapProp, editor_wrap(&config))
|
||||
.set(
|
||||
CursorSurroundingLines,
|
||||
config.editor.cursor_surrounding_lines,
|
||||
)
|
||||
.set(RenderWhitespaceProp, config.editor.render_whitespace)
|
||||
}
|
||||
|
||||
pub struct EditorView {
|
||||
data: ViewData,
|
||||
editor: EditorData,
|
||||
|
@ -64,6 +136,7 @@ pub struct EditorView {
|
|||
viewport: RwSignal<Rect>,
|
||||
debug_breakline: Memo<Option<(usize, PathBuf)>>,
|
||||
sticky_header_info: StickyHeaderInfo,
|
||||
editor_view_style: EditorViewStyle,
|
||||
}
|
||||
|
||||
pub fn editor_view(
|
||||
|
@ -174,6 +247,7 @@ pub fn editor_view(
|
|||
}
|
||||
});
|
||||
|
||||
let doc = e_data.doc_signal();
|
||||
EditorView {
|
||||
data: ViewData::new(id),
|
||||
editor: e_data,
|
||||
|
@ -186,6 +260,7 @@ pub fn editor_view(
|
|||
last_sticky_should_scroll: false,
|
||||
y_diff: 0.0,
|
||||
},
|
||||
editor_view_style: Default::default(),
|
||||
}
|
||||
.on_event(EventListener::ImePreedit, move |event| {
|
||||
if !is_active.get_untracked() {
|
||||
|
@ -213,6 +288,8 @@ pub fn editor_view(
|
|||
}
|
||||
EventPropagation::Stop
|
||||
})
|
||||
.class(EditorViewClass)
|
||||
.style(move |s| editor_style(config, doc, s))
|
||||
}
|
||||
|
||||
impl EditorView {
|
||||
|
@ -329,6 +406,7 @@ fn paint_cursor(
|
|||
cx: &mut PaintCx,
|
||||
is_local: bool,
|
||||
screen_lines: &ScreenLines,
|
||||
editor_style: &EditorViewStyle,
|
||||
) {
|
||||
let e_data = self.editor.clone();
|
||||
let ed = e_data.editor.clone();
|
||||
|
@ -342,7 +420,7 @@ fn paint_cursor(
|
|||
let is_active =
|
||||
self.is_active.get_untracked() && !find_focus.get_untracked();
|
||||
|
||||
let current_line_color = config.color(LapceColor::EDITOR_CURRENT_LINE);
|
||||
let current_line_color = editor_style.current_line();
|
||||
|
||||
let breakline = self.debug_breakline.get_untracked().and_then(
|
||||
|(breakline, breakline_path)| {
|
||||
|
@ -380,29 +458,37 @@ fn paint_cursor(
|
|||
CursorMode::Visual { .. } => false,
|
||||
};
|
||||
|
||||
// Highlight the current line
|
||||
if !is_local && highlight_current_line {
|
||||
for (_, end) in cursor.regions_iter() {
|
||||
// TODO: unsure if this is correct for wrapping lines
|
||||
let rvline = ed.rvline_of_offset(end, cursor.affinity);
|
||||
if let Some(current_line_color) = current_line_color {
|
||||
// Highlight the current line
|
||||
if !is_local && highlight_current_line {
|
||||
for (_, end) in cursor.regions_iter() {
|
||||
// TODO: unsure if this is correct for wrapping lines
|
||||
let rvline = ed.rvline_of_offset(end, cursor.affinity);
|
||||
|
||||
if let Some(info) = screen_lines
|
||||
.info(rvline)
|
||||
.filter(|_| Some(rvline.line) != breakline)
|
||||
{
|
||||
let rect = Rect::from_origin_size(
|
||||
(viewport.x0, info.vline_y),
|
||||
(viewport.width(), line_height),
|
||||
);
|
||||
if let Some(info) = screen_lines
|
||||
.info(rvline)
|
||||
.filter(|_| Some(rvline.line) != breakline)
|
||||
{
|
||||
let rect = Rect::from_origin_size(
|
||||
(viewport.x0, info.vline_y),
|
||||
(viewport.width(), line_height),
|
||||
);
|
||||
|
||||
cx.fill(&rect, current_line_color, 0.0);
|
||||
cx.fill(&rect, current_line_color, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FloemEditorView::paint_selection(cx, &ed, screen_lines);
|
||||
FloemEditorView::paint_selection(cx, &ed, screen_lines, editor_style);
|
||||
|
||||
FloemEditorView::paint_cursor_caret(cx, &ed, is_active, screen_lines);
|
||||
FloemEditorView::paint_cursor_caret(
|
||||
cx,
|
||||
&ed,
|
||||
is_active,
|
||||
screen_lines,
|
||||
editor_style,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -629,7 +715,17 @@ fn paint_scroll_bar(
|
|||
return;
|
||||
}
|
||||
|
||||
FloemEditorView::paint_scroll_bar(cx, &self.editor.editor, viewport);
|
||||
cx.fill(
|
||||
&Rect::ZERO
|
||||
.with_size(Size::new(1.0, viewport.height()))
|
||||
.with_origin(Point::new(
|
||||
viewport.x0 + viewport.width() - BAR_WIDTH,
|
||||
viewport.y0,
|
||||
))
|
||||
.inflate(0.0, 10.0),
|
||||
config.color(LapceColor::LAPCE_SCROLL_BAR),
|
||||
0.0,
|
||||
);
|
||||
|
||||
if !self.editor.kind.get_untracked().is_normal() {
|
||||
return;
|
||||
|
@ -929,6 +1025,27 @@ fn view_data_mut(&mut self) -> &mut ViewData {
|
|||
&mut self.data
|
||||
}
|
||||
|
||||
fn style(&mut self, cx: &mut StyleCx<'_>) {
|
||||
if self.editor_view_style.read(cx) {
|
||||
cx.app_state_mut().request_paint(self.id());
|
||||
}
|
||||
|
||||
let editor = &self.editor.editor;
|
||||
if editor.es.try_update(|s| s.read(cx)).unwrap() {
|
||||
editor.floem_style_id.update(|val| *val += 1);
|
||||
cx.app_state_mut().request_paint(self.id());
|
||||
}
|
||||
|
||||
self.for_each_child_mut(&mut |child| {
|
||||
cx.style_view(child);
|
||||
false
|
||||
});
|
||||
}
|
||||
|
||||
fn debug_name(&self) -> std::borrow::Cow<'static, str> {
|
||||
"Editor View".into()
|
||||
}
|
||||
|
||||
fn update(
|
||||
&mut self,
|
||||
cx: &mut floem::context::UpdateCx,
|
||||
|
@ -950,10 +1067,14 @@ fn layout(
|
|||
}
|
||||
|
||||
let e_data = &self.editor;
|
||||
let editor = &e_data.editor;
|
||||
|
||||
let parent_size = editor.parent_size.get_untracked();
|
||||
|
||||
let screen_lines = e_data.screen_lines().get_untracked();
|
||||
for (line, _) in screen_lines.iter_lines_y() {
|
||||
// fill in text layout cache so that max width is correct.
|
||||
e_data.editor.text_layout(line);
|
||||
editor.text_layout(line);
|
||||
}
|
||||
|
||||
let inner_node = self.inner_node.unwrap();
|
||||
|
@ -961,10 +1082,22 @@ fn layout(
|
|||
let config = self.editor.common.config.get_untracked();
|
||||
let line_height = config.editor.line_height() as f64;
|
||||
|
||||
let width = e_data.editor.max_line_width() + 20.0;
|
||||
let height = line_height * e_data.editor.last_vline().get() as f64;
|
||||
let width = editor.max_line_width().max(parent_size.width());
|
||||
let last_line_height =
|
||||
line_height * (editor.last_vline().get() + 1) as f64;
|
||||
let height = last_line_height.max(parent_size.height());
|
||||
|
||||
let style = Style::new().width(width).height(height).to_taffy_style();
|
||||
let margin_bottom = if self.editor_view_style.scroll_beyond_last_line() {
|
||||
parent_size.height().min(last_line_height) - line_height
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
let style = Style::new()
|
||||
.width(width)
|
||||
.height(height)
|
||||
.margin_bottom(margin_bottom)
|
||||
.to_taffy_style();
|
||||
cx.set_style(inner_node, style);
|
||||
|
||||
vec![inner_node]
|
||||
|
@ -975,10 +1108,17 @@ fn compute_layout(
|
|||
&mut self,
|
||||
cx: &mut floem::context::ComputeLayoutCx,
|
||||
) -> Option<Rect> {
|
||||
let editor = &self.editor.editor;
|
||||
let viewport = cx.current_viewport();
|
||||
if self.viewport.with_untracked(|v| v != &viewport) {
|
||||
self.viewport.set(viewport);
|
||||
}
|
||||
let parent_size = cx
|
||||
.app_state_mut()
|
||||
.get_layout_rect(self.id().parent().unwrap());
|
||||
if editor.parent_size.with_untracked(|ps| ps != &parent_size) {
|
||||
editor.parent_size.set(parent_size);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -999,7 +1139,7 @@ fn paint(&mut self, cx: &mut PaintCx) {
|
|||
// I expect that most/all of the paint functions could restrict themselves to only what is
|
||||
// within the active screen lines without issue.
|
||||
let screen_lines = ed.screen_lines.get_untracked();
|
||||
self.paint_cursor(cx, is_local, &screen_lines);
|
||||
self.paint_cursor(cx, is_local, &screen_lines, &self.editor_view_style);
|
||||
let screen_lines = ed.screen_lines.get_untracked();
|
||||
self.paint_diff_sections(cx, viewport, &screen_lines, &config);
|
||||
let screen_lines = ed.screen_lines.get_untracked();
|
||||
|
@ -1007,7 +1147,13 @@ fn paint(&mut self, cx: &mut PaintCx) {
|
|||
let screen_lines = ed.screen_lines.get_untracked();
|
||||
self.paint_bracket_highlights_scope_lines(cx, viewport, &screen_lines);
|
||||
let screen_lines = ed.screen_lines.get_untracked();
|
||||
FloemEditorView::paint_text(cx, ed, viewport, &screen_lines);
|
||||
FloemEditorView::paint_text(
|
||||
cx,
|
||||
ed,
|
||||
viewport,
|
||||
&screen_lines,
|
||||
&self.editor_view_style,
|
||||
);
|
||||
let screen_lines = ed.screen_lines.get_untracked();
|
||||
self.paint_sticky_headers(cx, viewport, &screen_lines);
|
||||
self.paint_scroll_bar(cx, viewport, is_local, config);
|
||||
|
@ -1153,11 +1299,9 @@ pub fn editor_container_view(
|
|||
let replace_focus = main_split.common.find.replace_focus;
|
||||
let debug_breakline = window_tab_data.terminal.breakline;
|
||||
|
||||
let editor_rect = create_rw_signal(Rect::ZERO);
|
||||
|
||||
stack((
|
||||
editor_breadcrumbs(workspace, editor.get_untracked(), config),
|
||||
container(
|
||||
clip(
|
||||
stack((
|
||||
editor_gutter(window_tab_data.clone(), editor, is_active),
|
||||
container(editor_content(editor, debug_breakline, is_active))
|
||||
|
@ -1189,9 +1333,6 @@ pub fn editor_container_view(
|
|||
is_active,
|
||||
),
|
||||
))
|
||||
.on_resize(move |rect| {
|
||||
editor_rect.set(rect);
|
||||
})
|
||||
.style(|s| s.absolute().size_pct(100.0, 100.0)),
|
||||
)
|
||||
.style(|s| s.size_pct(100.0, 100.0)),
|
||||
|
@ -1618,9 +1759,9 @@ fn editor_breadcrumbs(
|
|||
doc.track();
|
||||
Some(Point::new(3000.0, 0.0))
|
||||
})
|
||||
.hide_bar(|| true)
|
||||
.style(move |s| {
|
||||
s.absolute()
|
||||
s.set(HideBar, true)
|
||||
.absolute()
|
||||
.size_pct(100.0, 100.0)
|
||||
.border_bottom(1.0)
|
||||
.border_color(config.get().color(LapceColor::LAPCE_BORDER))
|
||||
|
@ -1666,17 +1807,18 @@ fn editor_content(
|
|||
let editor_content_view =
|
||||
editor_view(e_data.get_untracked(), debug_breakline, is_active).style(
|
||||
move |s| {
|
||||
let config = config.get();
|
||||
let padding_bottom = if config.editor.scroll_beyond_last_line {
|
||||
viewport.get().height() as f32
|
||||
- config.editor.line_height() as f32
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
s.absolute()
|
||||
.padding_bottom(padding_bottom)
|
||||
.cursor(CursorStyle::Text)
|
||||
.min_size_pct(100.0, 100.0)
|
||||
// let config = config.get();
|
||||
s.absolute().cursor(CursorStyle::Text)
|
||||
// let padding_bottom = if config.editor.scroll_beyond_last_line {
|
||||
// viewport.get().height() as f32
|
||||
// - config.editor.line_height() as f32
|
||||
// } else {
|
||||
// 0.0
|
||||
// };
|
||||
// s.absolute()
|
||||
// .padding_bottom(padding_bottom)
|
||||
// .cursor(CursorStyle::Text)
|
||||
// .min_size_pct(100.0, 100.0)
|
||||
},
|
||||
);
|
||||
let id = editor_content_view.id();
|
||||
|
@ -1748,10 +1890,12 @@ fn editor_content(
|
|||
if jump_to_middle {
|
||||
rect.inflate(0.0, viewport.height() / 2.0)
|
||||
} else {
|
||||
let cursor_surrounding_lines =
|
||||
e_data.editor.es.with(|s| s.cursor_surrounding_lines());
|
||||
let mut rect = rect;
|
||||
rect.y0 -= (config.editor.cursor_surrounding_lines * line_height) as f64
|
||||
rect.y0 -= (cursor_surrounding_lines * line_height) as f64
|
||||
+ sticky_header_height.get_untracked();
|
||||
rect.y1 += (config.editor.cursor_surrounding_lines * line_height) as f64;
|
||||
rect.y1 += (cursor_surrounding_lines * line_height) as f64;
|
||||
rect
|
||||
}
|
||||
})
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
style::CursorStyle,
|
||||
view::View,
|
||||
views::{
|
||||
container, dyn_container, img, label, scroll::scroll, stack, svg,
|
||||
virtual_stack, Decorators, VirtualDirection, VirtualItemSize, VirtualVector,
|
||||
container, dyn_container, img, label,
|
||||
scroll::{scroll, HideBar},
|
||||
stack, svg, virtual_stack, Decorators, VirtualDirection, VirtualItemSize,
|
||||
VirtualVector,
|
||||
},
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
|
@ -334,13 +336,13 @@ fn available_view(plugin: PluginData) -> impl View {
|
|||
.to_rect()
|
||||
.with_origin(Point::new(cursor_x.get(), 0.0))
|
||||
})
|
||||
.hide_bar(|| true)
|
||||
.on_event_cont(EventListener::PointerDown, move |_| {
|
||||
focus.set(Focus::Panel(PanelKind::Plugin));
|
||||
})
|
||||
.style(move |s| {
|
||||
let config = config.get();
|
||||
s.width_pct(100.0)
|
||||
s.set(HideBar, true)
|
||||
.width_pct(100.0)
|
||||
.cursor(CursorStyle::Text)
|
||||
.items_center()
|
||||
.background(config.color(LapceColor::EDITOR_BACKGROUND))
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
view::View,
|
||||
views::{
|
||||
container, dyn_stack, empty, label,
|
||||
scroll::{scroll, Thickness},
|
||||
scroll::{scroll, Thickness, VerticalScrollAsHorizontal},
|
||||
stack, svg, tab, Decorators,
|
||||
},
|
||||
EventPropagation,
|
||||
|
@ -196,7 +196,6 @@ fn terminal_tab_header(window_tab_data: Rc<WindowTabData>) -> impl View {
|
|||
)
|
||||
},
|
||||
))
|
||||
.vertical_scroll_as_horizontal(|| true)
|
||||
.on_resize(move |rect| {
|
||||
if rect.size() != scroll_size.get_untracked() {
|
||||
scroll_size.set(rect.size());
|
||||
|
@ -205,7 +204,8 @@ fn terminal_tab_header(window_tab_data: Rc<WindowTabData>) -> impl View {
|
|||
.style(move |s| {
|
||||
let header_width = header_width.get();
|
||||
let icon_width = icon_width.get();
|
||||
s.absolute()
|
||||
s.set(VerticalScrollAsHorizontal, true)
|
||||
.absolute()
|
||||
.max_width(header_width - icon_width)
|
||||
.set(Thickness, 3)
|
||||
}),
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
use crate::{
|
||||
config::{color::LapceColor, LapceConfig},
|
||||
doc::Doc,
|
||||
editor::{DocSignal, EditorData},
|
||||
editor::{view::editor_style, DocSignal, EditorData},
|
||||
keypress::KeyPressFocus,
|
||||
main_split::Editors,
|
||||
window_tab::CommonData,
|
||||
|
@ -235,8 +235,9 @@ fn text_input_full<T: KeyPressFocus + 'static>(
|
|||
hide_cursor: editor.cursor_info.hidden,
|
||||
style: Default::default(),
|
||||
}
|
||||
.style(|s| {
|
||||
s.cursor(CursorStyle::Text)
|
||||
.style(move |s| {
|
||||
editor_style(config, doc, s)
|
||||
.cursor(CursorStyle::Text)
|
||||
.padding_horiz(10.0)
|
||||
.padding_vert(6.0)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue