mirror of https://github.com/lapce/lapce.git
diff view
This commit is contained in:
parent
8369ba29fc
commit
13929bafb6
|
@ -573,7 +573,7 @@ pub fn retrieve_file_head(
|
|||
LapceUICommand::LoadBufferHead {
|
||||
path,
|
||||
content: Rope::from(resp.content),
|
||||
id: resp.id,
|
||||
version: resp.version,
|
||||
},
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
|
@ -2213,7 +2213,7 @@ fn buffer_diff(
|
|||
Some(changes)
|
||||
}
|
||||
|
||||
fn rope_diff(
|
||||
pub fn rope_diff(
|
||||
left_rope: Rope,
|
||||
right_rope: Rope,
|
||||
rev: u64,
|
||||
|
|
|
@ -639,7 +639,7 @@ pub enum LapceUICommand {
|
|||
},
|
||||
LoadBufferHead {
|
||||
path: PathBuf,
|
||||
id: String,
|
||||
version: String,
|
||||
content: Rope,
|
||||
},
|
||||
LoadBufferAndGoToPosition {
|
||||
|
|
|
@ -2431,7 +2431,7 @@ pub fn go_to_location(
|
|||
Vec2::new(info.scroll_offset.0, info.scroll_offset.1);
|
||||
doc.cursor_offset = info.cursor_offset;
|
||||
}
|
||||
doc.retrieve_file(self.proxy.clone(), vec![(editor_view_id, location)]);
|
||||
doc.retrieve_file(vec![(editor_view_id, location)]);
|
||||
self.open_docs.insert(path.clone(), Arc::new(doc));
|
||||
self.open_files.insert(
|
||||
path.clone(),
|
||||
|
@ -2459,14 +2459,9 @@ pub fn go_to_location(
|
|||
None => (doc.cursor_offset, Some(&doc.scroll_offset)),
|
||||
};
|
||||
|
||||
if let Some(compare) = location.history.as_ref() {
|
||||
// if !buffer.histories().contains_key(compare) {
|
||||
// buffer.retrieve_file_head(
|
||||
// *self.tab_id,
|
||||
// self.proxy.clone(),
|
||||
// ctx.get_external_handle(),
|
||||
// );
|
||||
// }
|
||||
if let Some(version) = location.history.as_ref() {
|
||||
let doc = self.open_docs.get_mut(&path).unwrap();
|
||||
Arc::make_mut(doc).retrieve_history(version);
|
||||
}
|
||||
|
||||
let editor = self.get_editor_or_new(
|
||||
|
@ -2475,8 +2470,8 @@ pub fn go_to_location(
|
|||
Some(location.path.clone()),
|
||||
config,
|
||||
);
|
||||
if let Some(compare) = location.history.as_ref() {
|
||||
editor.view = EditorView::Diff(compare.to_string());
|
||||
if let Some(version) = location.history.as_ref() {
|
||||
editor.view = EditorView::Diff(version.to_string());
|
||||
}
|
||||
editor.content = BufferContent::File(path.clone());
|
||||
editor.compare = location.history.clone();
|
||||
|
@ -2606,7 +2601,7 @@ pub fn new(
|
|||
active: Arc::new(None),
|
||||
active_tab: Arc::new(None),
|
||||
register: Arc::new(Register::default()),
|
||||
proxy: proxy.clone(),
|
||||
proxy,
|
||||
palette_preview_editor: Arc::new(palette_preview_editor),
|
||||
show_code_actions: false,
|
||||
current_code_actions: 0,
|
||||
|
@ -2629,11 +2624,8 @@ pub fn new(
|
|||
);
|
||||
main_split_data.split_id = Arc::new(split_data.widget_id);
|
||||
for (path, locations) in positions.into_iter() {
|
||||
main_split_data
|
||||
.open_docs
|
||||
.get(&path)
|
||||
.unwrap()
|
||||
.retrieve_file(proxy.clone(), locations.clone());
|
||||
Arc::make_mut(main_split_data.open_docs.get_mut(&path).unwrap())
|
||||
.retrieve_file(locations.clone());
|
||||
}
|
||||
} else {
|
||||
main_split_data.splits.insert(
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
collections::{HashMap, HashSet},
|
||||
path::PathBuf,
|
||||
rc::Rc,
|
||||
sync::{atomic, Arc},
|
||||
sync::{
|
||||
atomic::{self},
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
|
||||
use druid::{
|
||||
|
@ -26,18 +29,19 @@
|
|||
word::WordCursor,
|
||||
};
|
||||
use lapce_rpc::{
|
||||
buffer::{BufferId, NewBufferResponse},
|
||||
buffer::{BufferHeadResponse, BufferId, NewBufferResponse},
|
||||
style::{LineStyle, LineStyles, Style},
|
||||
};
|
||||
use lsp_types::CodeActionResponse;
|
||||
use xi_rope::{spans::Spans, RopeDelta};
|
||||
use xi_rope::{spans::Spans, Rope, RopeDelta};
|
||||
|
||||
use crate::{
|
||||
buffer::{BufferContent, LocalBufferKind},
|
||||
buffer::{rope_diff, BufferContent, DiffLines, DiffResult, LocalBufferKind},
|
||||
command::{LapceUICommand, LAPCE_UI_COMMAND},
|
||||
config::{Config, LapceTheme},
|
||||
editor::EditorLocationNew,
|
||||
find::{Find, FindProgress},
|
||||
history::DocumentHisotry,
|
||||
proxy::LapceProxy,
|
||||
};
|
||||
|
||||
|
@ -53,15 +57,16 @@ fn put_string(&mut self, s: impl AsRef<str>) {
|
|||
}
|
||||
}
|
||||
|
||||
struct TextLayoutCache {
|
||||
#[derive(Clone, Default)]
|
||||
pub struct TextLayoutCache {
|
||||
font_size: usize,
|
||||
font_family: FontFamily,
|
||||
tab_wdith: usize,
|
||||
layouts: HashMap<usize, Arc<PietTextLayout>>,
|
||||
pub layouts: HashMap<usize, Arc<PietTextLayout>>,
|
||||
}
|
||||
|
||||
impl TextLayoutCache {
|
||||
fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
font_size: 0,
|
||||
font_family: FontFamily::SYSTEM_UI,
|
||||
|
@ -74,7 +79,7 @@ fn clear(&mut self) {
|
|||
self.layouts.clear();
|
||||
}
|
||||
|
||||
fn check_attributes(
|
||||
pub fn check_attributes(
|
||||
&mut self,
|
||||
font_size: usize,
|
||||
font_family: FontFamily,
|
||||
|
@ -95,7 +100,7 @@ fn check_attributes(
|
|||
#[derive(Clone)]
|
||||
pub struct Document {
|
||||
id: BufferId,
|
||||
tab_id: WidgetId,
|
||||
pub tab_id: WidgetId,
|
||||
buffer: Buffer,
|
||||
content: BufferContent,
|
||||
syntax: Option<Syntax>,
|
||||
|
@ -104,13 +109,14 @@ pub struct Document {
|
|||
text_layouts: Rc<RefCell<TextLayoutCache>>,
|
||||
load_started: Rc<RefCell<bool>>,
|
||||
loaded: bool,
|
||||
histories: im::HashMap<String, DocumentHisotry>,
|
||||
pub cursor_offset: usize,
|
||||
pub scroll_offset: Vec2,
|
||||
pub code_actions: im::HashMap<usize, CodeActionResponse>,
|
||||
pub find: Rc<RefCell<Find>>,
|
||||
find_progress: Rc<RefCell<FindProgress>>,
|
||||
event_sink: ExtEventSink,
|
||||
proxy: Arc<LapceProxy>,
|
||||
pub event_sink: ExtEventSink,
|
||||
pub proxy: Arc<LapceProxy>,
|
||||
}
|
||||
|
||||
impl Document {
|
||||
|
@ -130,6 +136,7 @@ pub fn new(
|
|||
text_layouts: Rc::new(RefCell::new(TextLayoutCache::new())),
|
||||
semantic_styles: None,
|
||||
load_started: Rc::new(RefCell::new(false)),
|
||||
histories: im::HashMap::new(),
|
||||
loaded: false,
|
||||
cursor_offset: 0,
|
||||
scroll_offset: Vec2::ZERO,
|
||||
|
@ -165,11 +172,7 @@ pub fn load_content(&mut self, content: &str) {
|
|||
self.on_update(None);
|
||||
}
|
||||
|
||||
pub fn retrieve_file(
|
||||
&self,
|
||||
proxy: Arc<LapceProxy>,
|
||||
locations: Vec<(WidgetId, EditorLocationNew)>,
|
||||
) {
|
||||
pub fn retrieve_file(&mut self, locations: Vec<(WidgetId, EditorLocationNew)>) {
|
||||
if self.loaded || *self.load_started.borrow() {
|
||||
return;
|
||||
}
|
||||
|
@ -180,6 +183,7 @@ pub fn retrieve_file(
|
|||
let tab_id = self.tab_id;
|
||||
let path = path.clone();
|
||||
let event_sink = self.event_sink.clone();
|
||||
let proxy = self.proxy.clone();
|
||||
std::thread::spawn(move || {
|
||||
proxy.new_buffer(
|
||||
id,
|
||||
|
@ -204,6 +208,58 @@ pub fn retrieve_file(
|
|||
)
|
||||
});
|
||||
}
|
||||
|
||||
self.retrieve_history("head");
|
||||
}
|
||||
|
||||
pub fn retrieve_history(&mut self, version: &str) {
|
||||
if self.histories.contains_key(version) {
|
||||
return;
|
||||
}
|
||||
|
||||
let history = DocumentHisotry::new(version.to_string());
|
||||
history.retrieve(self);
|
||||
self.histories.insert(version.to_string(), history);
|
||||
}
|
||||
|
||||
pub fn load_history(&mut self, version: &str, content: Rope) {
|
||||
let mut history = DocumentHisotry::new(version.to_string());
|
||||
history.load_content(content, self);
|
||||
self.histories.insert(version.to_string(), history);
|
||||
}
|
||||
|
||||
pub fn get_history(&self, version: &str) -> Option<&DocumentHisotry> {
|
||||
self.histories.get(version)
|
||||
}
|
||||
|
||||
fn trigger_head_change(&self) {
|
||||
if let Some(head) = self.histories.get("head") {
|
||||
head.trigger_update_change(self);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_history_changes(
|
||||
&mut self,
|
||||
rev: u64,
|
||||
version: &str,
|
||||
changes: Arc<Vec<DiffLines>>,
|
||||
) {
|
||||
if rev != self.rev() {
|
||||
return;
|
||||
}
|
||||
if let Some(history) = self.histories.get_mut(version) {
|
||||
history.update_changes(changes);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_history_styles(
|
||||
&mut self,
|
||||
version: &str,
|
||||
styles: Arc<Spans<Style>>,
|
||||
) {
|
||||
if let Some(history) = self.histories.get_mut(version) {
|
||||
history.update_styles(styles);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_update(&mut self, delta: Option<&RopeDelta>) {
|
||||
|
@ -211,6 +267,7 @@ fn on_update(&mut self, delta: Option<&RopeDelta>) {
|
|||
*self.find_progress.borrow_mut() = FindProgress::Started;
|
||||
self.clear_style_cache();
|
||||
self.trigger_syntax_change(delta);
|
||||
self.trigger_head_change();
|
||||
self.notify_special();
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,238 @@
|
|||
pub struct DocumentHisotry {}
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
rc::Rc,
|
||||
sync::{atomic, Arc},
|
||||
};
|
||||
|
||||
use druid::{
|
||||
piet::{PietText, PietTextLayout, Text, TextAttribute, TextLayoutBuilder},
|
||||
Target,
|
||||
};
|
||||
use lapce_core::{buffer::Buffer, style::line_styles, syntax::Syntax};
|
||||
use lapce_rpc::{
|
||||
buffer::BufferHeadResponse,
|
||||
style::{LineStyle, LineStyles, Style},
|
||||
};
|
||||
use xi_rope::{spans::Spans, Rope};
|
||||
|
||||
use crate::{
|
||||
buffer::{rope_diff, BufferContent, DiffLines},
|
||||
command::{LapceUICommand, LAPCE_UI_COMMAND},
|
||||
config::{Config, LapceTheme},
|
||||
document::{Document, TextLayoutCache},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DocumentHisotry {
|
||||
version: String,
|
||||
buffer: Buffer,
|
||||
styles: Arc<Spans<Style>>,
|
||||
line_styles: Rc<RefCell<LineStyles>>,
|
||||
changes: Arc<Vec<DiffLines>>,
|
||||
text_layouts: Rc<RefCell<TextLayoutCache>>,
|
||||
}
|
||||
|
||||
impl DocumentHisotry {
|
||||
pub fn new(version: String) -> Self {
|
||||
Self {
|
||||
version,
|
||||
buffer: Buffer::new(""),
|
||||
styles: Arc::new(Spans::default()),
|
||||
line_styles: Rc::new(RefCell::new(LineStyles::new())),
|
||||
text_layouts: Rc::new(RefCell::new(TextLayoutCache::new())),
|
||||
changes: Arc::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_content(&mut self, content: Rope, doc: &Document) {
|
||||
self.buffer.load_content(&content.slice_to_cow(..));
|
||||
self.trigger_update_change(doc);
|
||||
self.retrieve_history_styles(doc);
|
||||
}
|
||||
|
||||
pub fn get_text_layout(
|
||||
&self,
|
||||
text: &mut PietText,
|
||||
line: usize,
|
||||
config: &Config,
|
||||
) -> Arc<PietTextLayout> {
|
||||
self.text_layouts.borrow_mut().check_attributes(
|
||||
config.editor.font_size,
|
||||
config.editor.font_family(),
|
||||
config.editor.tab_width,
|
||||
);
|
||||
if self.text_layouts.borrow().layouts.get(&line).is_none() {
|
||||
self.text_layouts
|
||||
.borrow_mut()
|
||||
.layouts
|
||||
.insert(line, Arc::new(self.new_text_layout(text, line, config)));
|
||||
}
|
||||
self.text_layouts
|
||||
.borrow()
|
||||
.layouts
|
||||
.get(&line)
|
||||
.cloned()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn new_text_layout(
|
||||
&self,
|
||||
text: &mut PietText,
|
||||
line: usize,
|
||||
config: &Config,
|
||||
) -> PietTextLayout {
|
||||
let line_content = self.buffer.line_content(line);
|
||||
let font_family = config.editor.font_family();
|
||||
let font_size = config.editor.font_size;
|
||||
let tab_width =
|
||||
config.tab_width(text, config.editor.font_family(), font_size);
|
||||
let mut layout_builder = text
|
||||
.new_text_layout(line_content.to_string())
|
||||
.font(font_family, font_size as f64)
|
||||
.text_color(
|
||||
config
|
||||
.get_color_unchecked(LapceTheme::EDITOR_FOREGROUND)
|
||||
.clone(),
|
||||
)
|
||||
.set_tab_width(tab_width);
|
||||
|
||||
let styles = self.line_style(line);
|
||||
for line_style in styles.iter() {
|
||||
if let Some(fg_color) = line_style.style.fg_color.as_ref() {
|
||||
if let Some(fg_color) = config.get_style_color(fg_color) {
|
||||
layout_builder = layout_builder.range_attribute(
|
||||
line_style.start..line_style.end,
|
||||
TextAttribute::TextColor(fg_color.clone()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layout_builder.build().unwrap()
|
||||
}
|
||||
|
||||
fn line_style(&self, line: usize) -> Arc<Vec<LineStyle>> {
|
||||
if self.line_styles.borrow().get(&line).is_none() {
|
||||
let line_styles = line_styles(self.buffer.text(), line, &self.styles);
|
||||
self.line_styles
|
||||
.borrow_mut()
|
||||
.insert(line, Arc::new(line_styles));
|
||||
}
|
||||
self.line_styles.borrow().get(&line).cloned().unwrap()
|
||||
}
|
||||
|
||||
pub fn retrieve(&self, doc: &Document) {
|
||||
if let BufferContent::File(path) = &doc.content() {
|
||||
let id = doc.id();
|
||||
let tab_id = doc.tab_id;
|
||||
let path = path.clone();
|
||||
let proxy = doc.proxy.clone();
|
||||
let event_sink = doc.event_sink.clone();
|
||||
std::thread::spawn(move || {
|
||||
proxy.get_buffer_head(
|
||||
id,
|
||||
path.clone(),
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
if let Ok(resp) =
|
||||
serde_json::from_value::<BufferHeadResponse>(res)
|
||||
{
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::LoadBufferHead {
|
||||
path,
|
||||
content: Rope::from(resp.content),
|
||||
version: resp.version,
|
||||
},
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trigger_update_change(&self, doc: &Document) {
|
||||
if let BufferContent::File(path) = &doc.content() {
|
||||
let id = doc.id();
|
||||
let rev = doc.rev();
|
||||
let atomic_rev = doc.buffer().atomic_rev();
|
||||
let path = path.clone();
|
||||
let left_rope = self.buffer.text().clone();
|
||||
let right_rope = doc.buffer().text().clone();
|
||||
let event_sink = doc.event_sink.clone();
|
||||
let tab_id = doc.tab_id;
|
||||
rayon::spawn(move || {
|
||||
if atomic_rev.load(atomic::Ordering::Acquire) != rev {
|
||||
return;
|
||||
}
|
||||
let changes =
|
||||
rope_diff(left_rope, right_rope, rev, atomic_rev.clone());
|
||||
if changes.is_none() {
|
||||
return;
|
||||
}
|
||||
let changes = changes.unwrap();
|
||||
if atomic_rev.load(atomic::Ordering::Acquire) != rev {
|
||||
return;
|
||||
}
|
||||
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdateHistoryChanges {
|
||||
id,
|
||||
path,
|
||||
rev,
|
||||
history: "head".to_string(),
|
||||
changes: Arc::new(changes),
|
||||
},
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn changes(&self) -> &[DiffLines] {
|
||||
&self.changes
|
||||
}
|
||||
|
||||
pub fn update_changes(&mut self, changes: Arc<Vec<DiffLines>>) {
|
||||
self.changes = changes;
|
||||
}
|
||||
|
||||
pub fn update_styles(&mut self, styles: Arc<Spans<Style>>) {
|
||||
self.styles = styles;
|
||||
self.line_styles.borrow_mut().clear();
|
||||
}
|
||||
|
||||
fn retrieve_history_styles(&self, doc: &Document) {
|
||||
if let BufferContent::File(path) = &doc.content() {
|
||||
let id = doc.id();
|
||||
let path = path.clone();
|
||||
let tab_id = doc.tab_id;
|
||||
let version = self.version.to_string();
|
||||
let event_sink = doc.event_sink.clone();
|
||||
|
||||
let content = self.buffer.text().clone();
|
||||
rayon::spawn(move || {
|
||||
if let Some(syntax) =
|
||||
Syntax::init(&path).map(|s| s.parse(0, content, None))
|
||||
{
|
||||
if let Some(styles) = syntax.styles {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdateHistoryStyle {
|
||||
id,
|
||||
path,
|
||||
history: version,
|
||||
highlights: styles,
|
||||
},
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -404,7 +404,7 @@ fn handle_request(&self, id: RequestId, rpc: ProxyRequest) {
|
|||
let result = file_get_head(&workspace, &path);
|
||||
if let Ok((_blob_id, content)) = result {
|
||||
let resp = BufferHeadResponse {
|
||||
id: "head".to_string(),
|
||||
version: "head".to_string(),
|
||||
content,
|
||||
};
|
||||
let _ = self.sender.send(json!({
|
||||
|
|
|
@ -19,6 +19,6 @@ pub struct NewBufferResponse {
|
|||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BufferHeadResponse {
|
||||
pub id: String,
|
||||
pub version: String,
|
||||
pub content: String,
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
use lapce_core::command::FocusCommand;
|
||||
use lapce_core::mode::{Mode, VisualMode};
|
||||
use lapce_data::command::CommandKind;
|
||||
use lapce_data::data::EditorView;
|
||||
use lapce_data::keypress::KeyPressFocus;
|
||||
use lapce_data::{
|
||||
buffer::{matching_pair_direction, BufferContent, DiffLines, LocalBufferKind},
|
||||
|
@ -479,12 +480,12 @@ fn paint_content(
|
|||
|
||||
if !data.editor.content.is_input() && data.editor.code_lens {
|
||||
Self::paint_code_lens_content(data, ctx, is_focused);
|
||||
} else if let Some(compare) = data.editor.compare.as_ref() {
|
||||
if let Some(changes) = data.buffer.history_changes.get(compare) {
|
||||
} else if let EditorView::Diff(version) = &data.editor.view {
|
||||
if let Some(history) = data.doc.get_history(version) {
|
||||
let cursor_line =
|
||||
data.buffer.line_of_offset(data.editor.cursor.offset());
|
||||
let mut line = 0;
|
||||
for change in changes.iter() {
|
||||
for change in history.changes().iter() {
|
||||
match change {
|
||||
DiffLines::Left(range) => {
|
||||
let len = range.len();
|
||||
|
@ -509,24 +510,19 @@ fn paint_content(
|
|||
continue;
|
||||
}
|
||||
let actual_line = l - (line - len) + range.start;
|
||||
if let Some(text_layout) =
|
||||
data.buffer.history_text_layout(
|
||||
ctx,
|
||||
compare,
|
||||
actual_line,
|
||||
None,
|
||||
[rect.x0, rect.x1],
|
||||
&data.config,
|
||||
)
|
||||
{
|
||||
ctx.draw_text(
|
||||
&text_layout,
|
||||
Point::new(
|
||||
0.0,
|
||||
line_height * l as f64 + y_shift,
|
||||
),
|
||||
);
|
||||
}
|
||||
let text_layout = history.get_text_layout(
|
||||
ctx.text(),
|
||||
actual_line,
|
||||
&data.config,
|
||||
);
|
||||
ctx.draw_text(
|
||||
&text_layout,
|
||||
Point::new(
|
||||
0.0,
|
||||
line_height * l as f64 + y_shift,
|
||||
),
|
||||
);
|
||||
|
||||
if l > end_line {
|
||||
break;
|
||||
}
|
||||
|
@ -600,13 +596,10 @@ fn paint_content(
|
|||
char_width,
|
||||
line_height,
|
||||
);
|
||||
let text_layout = data.buffer.new_text_layout(
|
||||
ctx,
|
||||
let text_layout = data.doc.get_text_layout(
|
||||
ctx.text(),
|
||||
rope_line,
|
||||
&data.buffer.line_content(rope_line),
|
||||
None,
|
||||
font_size,
|
||||
[rect.x0, rect.x1],
|
||||
&data.config,
|
||||
);
|
||||
ctx.draw_text(
|
||||
|
@ -662,13 +655,10 @@ fn paint_content(
|
|||
char_width,
|
||||
line_height,
|
||||
);
|
||||
let text_layout = data.buffer.new_text_layout(
|
||||
ctx,
|
||||
let text_layout = data.doc.get_text_layout(
|
||||
ctx.text(),
|
||||
rope_line,
|
||||
&data.buffer.line_content(rope_line),
|
||||
None,
|
||||
font_size,
|
||||
[rect.x0, rect.x1],
|
||||
&data.config,
|
||||
);
|
||||
ctx.draw_text(
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use lapce_data::{
|
||||
buffer::DiffLines,
|
||||
config::LapceTheme,
|
||||
data::LapceTabData,
|
||||
data::{EditorView, LapceTabData},
|
||||
editor::{LapceEditorBufferData, Syntax},
|
||||
};
|
||||
|
||||
|
@ -108,25 +108,28 @@ fn paint_gutter_inline_diff(
|
|||
&self,
|
||||
data: &LapceEditorBufferData,
|
||||
ctx: &mut PaintCtx,
|
||||
compare: &str,
|
||||
version: &str,
|
||||
) {
|
||||
if data.buffer.history_changes.get(compare).is_none() {
|
||||
if data.doc.get_history(version).is_none() {
|
||||
return;
|
||||
}
|
||||
let history = data.doc.get_history(version).unwrap();
|
||||
let self_size = ctx.size();
|
||||
let rect = self_size.to_rect();
|
||||
let changes = data.buffer.history_changes.get(compare).unwrap();
|
||||
let line_height = data.config.editor.line_height as f64;
|
||||
let scroll_offset = data.editor.scroll_offset;
|
||||
let start_line = (scroll_offset.y / line_height).floor() as usize;
|
||||
let end_line =
|
||||
(scroll_offset.y + rect.height() / line_height).ceil() as usize;
|
||||
let current_line = data.editor.cursor.current_line(data.buffer.data());
|
||||
let last_line = data.buffer.last_line();
|
||||
let current_line = data
|
||||
.doc
|
||||
.buffer()
|
||||
.line_of_offset(data.editor.new_cursor.offset());
|
||||
let last_line = data.doc.buffer().last_line();
|
||||
let width = data.config.editor_char_width(ctx.text());
|
||||
|
||||
let mut line = 0;
|
||||
for change in changes.iter() {
|
||||
for change in history.changes().iter() {
|
||||
match change {
|
||||
DiffLines::Left(r) => {
|
||||
let len = r.len();
|
||||
|
@ -467,8 +470,8 @@ fn paint_gutter(&self, data: &LapceEditorBufferData, ctx: &mut PaintCtx) {
|
|||
ctx.with_save(|ctx| {
|
||||
let clip_rect = rect;
|
||||
ctx.clip(clip_rect);
|
||||
if let Some(compare) = data.editor.compare.as_ref() {
|
||||
self.paint_gutter_inline_diff(data, ctx, compare);
|
||||
if let EditorView::Diff(version) = &data.editor.view {
|
||||
self.paint_gutter_inline_diff(data, ctx, version);
|
||||
return;
|
||||
}
|
||||
if data.editor.code_lens {
|
||||
|
@ -479,7 +482,7 @@ fn paint_gutter(&self, data: &LapceEditorBufferData, ctx: &mut PaintCtx) {
|
|||
let scroll_offset = data.editor.scroll_offset;
|
||||
let start_line = (scroll_offset.y / line_height).floor() as usize;
|
||||
let num_lines = (ctx.size().height / line_height).floor() as usize;
|
||||
let last_line = data.buffer.last_line();
|
||||
let last_line = data.doc.buffer().last_line();
|
||||
let current_line = data
|
||||
.doc
|
||||
.buffer()
|
||||
|
@ -536,13 +539,13 @@ fn paint_gutter(&self, data: &LapceEditorBufferData, ctx: &mut PaintCtx) {
|
|||
ctx.draw_text(&text_layout, Point::new(x, y));
|
||||
}
|
||||
|
||||
if let Some(changes) = data.buffer.history_changes.get("head") {
|
||||
if let Some(history) = data.doc.get_history("head") {
|
||||
let end_line =
|
||||
(scroll_offset.y + rect.height() / line_height).ceil() as usize;
|
||||
|
||||
let mut line = 0;
|
||||
let mut last_change = None;
|
||||
for change in changes.iter() {
|
||||
for change in history.changes().iter() {
|
||||
let len = match change {
|
||||
DiffLines::Left(_range) => 0,
|
||||
DiffLines::Skip(_left, right) => right.len(),
|
||||
|
|
|
@ -433,11 +433,19 @@ fn event(
|
|||
matches.clone();
|
||||
}
|
||||
}
|
||||
LapceUICommand::LoadBufferHead { path, id, content } => {
|
||||
LapceUICommand::LoadBufferHead {
|
||||
path,
|
||||
version,
|
||||
content,
|
||||
} => {
|
||||
let buffer =
|
||||
data.main_split.open_files.get_mut(path).unwrap();
|
||||
let buffer = Arc::make_mut(buffer);
|
||||
buffer.load_history(id, content.clone());
|
||||
buffer.load_history(version, content.clone());
|
||||
|
||||
let doc = data.main_split.open_docs.get_mut(path).unwrap();
|
||||
let doc = Arc::make_mut(doc);
|
||||
doc.load_history(version, content.clone());
|
||||
ctx.set_handled();
|
||||
}
|
||||
LapceUICommand::UpdateTerminalTitle(term_id, title) => {
|
||||
|
@ -974,6 +982,12 @@ fn event(
|
|||
history,
|
||||
changes.clone(),
|
||||
);
|
||||
let doc = data.main_split.open_docs.get_mut(path).unwrap();
|
||||
Arc::make_mut(doc).update_history_changes(
|
||||
*rev,
|
||||
history,
|
||||
changes.clone(),
|
||||
);
|
||||
}
|
||||
LapceUICommand::UpdateHistoryStyle {
|
||||
path,
|
||||
|
@ -991,6 +1005,10 @@ fn event(
|
|||
.history_line_styles
|
||||
.borrow_mut()
|
||||
.insert(history.to_string(), HashMap::new());
|
||||
|
||||
let doc = data.main_split.open_docs.get_mut(path).unwrap();
|
||||
Arc::make_mut(doc)
|
||||
.update_history_styles(history, highlights.to_owned());
|
||||
}
|
||||
LapceUICommand::UpdatePickerPwd(path) => {
|
||||
Arc::make_mut(&mut data.picker).pwd = path.clone();
|
||||
|
|
Loading…
Reference in New Issue