on master help sign in
Pass editor into render_view & gutter, reducing the number of params
3633f85Blaž Hrastnik
helix-term/src/commands/dap.rs+1−1
@@ -429,7 +429,7 @@ pub fn dap_toggle_breakpoint_impl(cx: &mut Context, path: std::path::PathBuf, li
429 Some(debugger) => debugger,
429 Some(debugger) => debugger,
430 None => return,
430 None => return,
431 };
431 };
432− let request = debugger.set_breakpoints(path.clone(), breakpoints);
432+ let request = debugger.set_breakpoints(path, breakpoints);
433 match block_on(request) {
433 match block_on(request) {
434 Ok(Some(breakpoints)) => {
434 Ok(Some(breakpoints)) => {
435 // TODO: handle breakpoint.message
435 // TODO: handle breakpoint.message
helix-term/src/ui/editor.rs+76−101
@@ -63,20 +63,18 @@ impl EditorView {
63 #[allow(clippy::too_many_arguments)]
63 #[allow(clippy::too_many_arguments)]
64 pub fn render_view(
64 pub fn render_view(
65 &self,
65 &self,
66+ editor: &Editor,
66 doc: &Document,
67 doc: &Document,
67 view: &View,
68 view: &View,
68 viewport: Rect,
69 viewport: Rect,
69 surface: &mut Surface,
70 surface: &mut Surface,
70− theme: &Theme,
71 is_focused: bool,
71 is_focused: bool,
72 loader: &syntax::Loader,
72 loader: &syntax::Loader,
73− config: &helix_view::editor::Config,
74− debugger: &Option<helix_dap::Client>,
75− all_breakpoints: &HashMap<PathBuf, Vec<SourceBreakpoint>>,
76− dbg_breakpoints: &Option<Vec<Breakpoint>>,
77 ) {
73 ) {
78 let inner = view.inner_area();
74 let inner = view.inner_area();
79 let area = view.area;
75 let area = view.area;
76+ let theme = &editor.theme;
77+ let all_breakpoints = HashMap::new();
80
78
81 let highlights = Self::doc_syntax_highlights(doc, view.offset, inner.height, theme, loader);
79 let highlights = Self::doc_syntax_highlights(doc, view.offset, inner.height, theme, loader);
82 let highlights = syntax::merge(highlights, Self::doc_diagnostics_highlights(doc, theme));
80 let highlights = syntax::merge(highlights, Self::doc_diagnostics_highlights(doc, theme));
@@ -90,18 +88,7 @@ impl EditorView {
90 };
88 };
91
89
92 Self::render_text_highlights(doc, view.offset, inner, surface, theme, highlights);
90 Self::render_text_highlights(doc, view.offset, inner, surface, theme, highlights);
93− Self::render_gutter(
91+ Self::render_gutter(editor, doc, view, view.area, surface, theme, is_focused);
94− doc,
95− view,
96− view.area,
97− surface,
98− theme,
99− is_focused,
100− config,
101− debugger,
102− all_breakpoints,
103− dbg_breakpoints,
104− );
105
92
106 if is_focused {
93 if is_focused {
107 Self::render_focused_view_elements(view, doc, inner, theme, surface);
94 Self::render_focused_view_elements(view, doc, inner, theme, surface);
@@ -120,7 +107,7 @@ impl EditorView {
120 }
107 }
121 }
108 }
122
109
123− self.render_diagnostics(doc, view, inner, surface, theme, all_breakpoints);
110+ self.render_diagnostics(doc, view, inner, surface, theme, &all_breakpoints);
124
111
125 let statusline_area = view
112 let statusline_area = view
126 .area
113 .area
@@ -413,18 +400,14 @@ impl EditorView {
413 }
400 }
414 }
401 }
415
402
416− #[allow(clippy::too_many_arguments)]
417 pub fn render_gutter(
403 pub fn render_gutter(
404+ editor: &Editor,
418 doc: &Document,
405 doc: &Document,
419 view: &View,
406 view: &View,
420 viewport: Rect,
407 viewport: Rect,
421 surface: &mut Surface,
408 surface: &mut Surface,
422 theme: &Theme,
409 theme: &Theme,
423 is_focused: bool,
410 is_focused: bool,
424− config: &helix_view::editor::Config,
425− debugger: &Option<helix_dap::Client>,
426− all_breakpoints: &HashMap<PathBuf, Vec<SourceBreakpoint>>,
427− dbg_breakpoints: &Option<Vec<Breakpoint>>,
428 ) {
411 ) {
429 let text = doc.text().slice(..);
412 let text = doc.text().slice(..);
430 let last_line = view.last_line(doc);
413 let last_line = view.last_line(doc);
@@ -438,8 +421,10 @@ impl EditorView {
438 .map(|range| range.cursor_line(text))
421 .map(|range| range.cursor_line(text))
439 .collect();
422 .collect();
440
423
424+ use helix_view::editor::Config;
441 use helix_view::gutter::GutterFn;
425 use helix_view::gutter::GutterFn;
442 fn breakpoints<'doc>(
426 fn breakpoints<'doc>(
427+ editor: &'doc Editor,
443 doc: &'doc Document,
428 doc: &'doc Document,
444 _view: &View,
429 _view: &View,
445 theme: &Theme,
430 theme: &Theme,
@@ -447,14 +432,77 @@ impl EditorView {
447 _is_focused: bool,
432 _is_focused: bool,
448 _width: usize,
433 _width: usize,
449 ) -> GutterFn<'doc> {
434 ) -> GutterFn<'doc> {
435+ let warning = theme.get("warning");
436+ let error = theme.get("error");
437+ let info = theme.get("info");
438+
439+ let all_breakpoints = &editor.breakpoints;
440+
441+ // TODO: debugger breakpoints should keep editor level breakpoints in sync
442+
443+ let breakpoints = doc
444+ .path()
445+ .and_then(|path| all_breakpoints.get(path))
446+ .unwrap();
447+
450 Box::new(move |line: usize, _selected: bool, out: &mut String| {
448 Box::new(move |line: usize, _selected: bool, out: &mut String| {
451− //
449+ // TODO: debugger should translate received breakpoints to 0-indexing
450+ let breakpoint = breakpoints.iter().find(|breakpoint| {
451+ false
452+ // if breakpoint.source == doc.path() {
453+ // match (breakpoint.line, breakpoint.end_line) {
454+ // #[allow(clippy::int_plus_one)]
455+ // (Some(l), Some(el)) => l - 1 <= line && line <= el - 1,
456+ // (Some(l), None) => l - 1 == line,
457+ // _ => false,
458+ // }
459+ // } else {
460+ // false
461+ // }
462+ });
463+
464+ let breakpoint = match breakpoint {
465+ Some(b) => b,
466+ None => return None,
467+ };
468+
469+ // let verified = breakpoint.verified;
470+ let verified = false;
471+
472+ let mut style =
473+ if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {
474+ error.add_modifier(Modifier::UNDERLINED)
475+ } else if breakpoint.condition.is_some() {
476+ error
477+ } else if breakpoint.log_message.is_some() {
478+ info
479+ } else {
480+ warning
481+ };
482+
483+ if !verified {
484+ // Faded colors
485+ style = if let Some(Color::Rgb(r, g, b)) = style.fg {
486+ style.fg(Color::Rgb(
487+ ((r as f32) * 0.4).floor() as u8,
488+ ((g as f32) * 0.4).floor() as u8,
489+ ((b as f32) * 0.4).floor() as u8,
490+ ))
491+ } else {
492+ style.fg(Color::Gray)
493+ }
494+ };
495+
496+ // TODO: also handle breakpoints only present in the user struct
497+ use std::fmt::Write;
498+ let sym = if verified { "▲" } else { "⊚" };
499+ write!(out, "{}", sym).unwrap();
500+ Some(style)
452 })
501 })
453 }
502 }
454− // let mut breakpoints: Option<&Vec<SourceBreakpoint>> = None;
503+
455 // let mut stack_frame: Option<&StackFrame> = None;
504 // let mut stack_frame: Option<&StackFrame> = None;
456 // if let Some(path) = doc.path() {
505 // if let Some(path) = doc.path() {
457− // breakpoints = all_breakpoints.get(path);
458 // if let Some(debugger) = debugger {
506 // if let Some(debugger) = debugger {
459 // // if we have a frame, and the frame path matches document
507 // // if we have a frame, and the frame path matches document
460 // if let (Some(frame), Some(thread_id)) = (debugger.active_frame, debugger.thread_id)
508 // if let (Some(frame), Some(thread_id)) = (debugger.active_frame, debugger.thread_id)
@@ -475,66 +523,6 @@ impl EditorView {
475 // };
523 // };
476 // }
524 // }
477 // }
525 // }
478−
479− // TODO: debugger should translate received breakpoints to 0-indexing
480−
481− // if let Some(user) = breakpoints.as_ref() {
482− // let debugger_breakpoint = if let Some(debugger) = dbg_breakpoints.as_ref() {
483− // debugger.iter().find(|breakpoint| {
484− // if breakpoint.source.is_some()
485− // && doc.path().is_some()
486− // && breakpoint.source.as_ref().unwrap().path == doc.path().cloned()
487− // {
488− // match (breakpoint.line, breakpoint.end_line) {
489− // #[allow(clippy::int_plus_one)]
490− // (Some(l), Some(el)) => l - 1 <= line && line <= el - 1,
491− // (Some(l), None) => l - 1 == line,
492− // _ => false,
493− // }
494− // } else {
495− // false
496− // }
497− // })
498− // } else {
499− // None
500− // };
501−
502− // if let Some(breakpoint) = user.iter().find(|breakpoint| breakpoint.line - 1 == line)
503− // {
504− // let verified = debugger_breakpoint.map(|b| b.verified).unwrap_or(false);
505− // let mut style =
506− // if breakpoint.condition.is_some() && breakpoint.log_message.is_some() {
507− // error.add_modifier(Modifier::UNDERLINED)
508− // } else if breakpoint.condition.is_some() {
509− // error
510− // } else if breakpoint.log_message.is_some() {
511− // info
512− // } else {
513− // warning
514− // };
515− // if !verified {
516− // // Faded colors
517− // style = if let Some(Color::Rgb(r, g, b)) = style.fg {
518− // style.fg(Color::Rgb(
519− // ((r as f32) * 0.4).floor() as u8,
520− // ((g as f32) * 0.4).floor() as u8,
521− // ((b as f32) * 0.4).floor() as u8,
522− // ))
523− // } else {
524− // style.fg(Color::Gray)
525− // }
526− // };
527− // surface.set_stringn(viewport.x, viewport.y + i as u16, "▲", 1, style);
528− // } else if let Some(breakpoint) = debugger_breakpoint {
529− // let style = if breakpoint.verified {
530− // info
531− // } else {
532− // info.fg(Color::Gray)
533− // };
534− // surface.set_stringn(viewport.x, viewport.y + i as u16, "⊚", 1, style);
535− // }
536− // }
537−
538 // if let Some(frame) = stack_frame {
526 // if let Some(frame) = stack_frame {
539 // if frame.line - 1 == line {
527 // if frame.line - 1 == line {
540 // surface.set_style(
528 // surface.set_style(
@@ -551,7 +539,7 @@ impl EditorView {
551 let mut text = String::with_capacity(8);
539 let mut text = String::with_capacity(8);
552
540
553 for (constructor, width) in view.gutters() {
541 for (constructor, width) in view.gutters() {
554− let gutter = constructor(doc, view, theme, config, is_focused, *width);
542+ let gutter = constructor(editor, doc, view, theme, is_focused, *width);
555 text.reserve(*width); // ensure there's enough space for the gutter
543 text.reserve(*width); // ensure there's enough space for the gutter
556 for (i, line) in (view.offset.row..(last_line + 1)).enumerate() {
544 for (i, line) in (view.offset.row..(last_line + 1)).enumerate() {
557 let selected = cursors.contains(&line);
545 let selected = cursors.contains(&line);
@@ -1250,20 +1238,7 @@ impl Component for EditorView {
1250 for (view, is_focused) in cx.editor.tree.views() {
1238 for (view, is_focused) in cx.editor.tree.views() {
1251 let doc = cx.editor.document(view.doc).unwrap();
1239 let doc = cx.editor.document(view.doc).unwrap();
1252 let loader = &cx.editor.syn_loader;
1240 let loader = &cx.editor.syn_loader;
1253− let dbg_breakpoints = cx.editor.debugger.as_ref().map(|d| d.breakpoints.clone());
1254− self.render_view(
1241+ self.render_view(cx.editor, doc, view, area, surface, is_focused, loader);
1255− doc,
1256− view,
1257− area,
1258− surface,
1259− &cx.editor.theme,
1260− is_focused,
1261− loader,
1262− &cx.editor.config,
1263− &cx.editor.debugger,
1264− &cx.editor.breakpoints,
1265− &dbg_breakpoints,
1266− );
1267 }
1242 }
1268
1243
1269 if cx.editor.config.auto_info {
1244 if cx.editor.config.auto_info {
helix-view/src/gutter.rs+5−5
@@ -1,16 +1,16 @@
1use std::fmt::Write;
1use std::fmt::Write;
2
2
3−use crate::{editor::Config, graphics::Style, Document, Theme, View};
3+use crate::{graphics::Style, Document, Editor, Theme, View};
4
4
5pub type GutterFn<'doc> = Box<dyn Fn(usize, bool, &mut String) -> Option<Style> + 'doc>;
5pub type GutterFn<'doc> = Box<dyn Fn(usize, bool, &mut String) -> Option<Style> + 'doc>;
6pub type Gutter =
6pub type Gutter =
7− for<'doc> fn(&'doc Document, &View, &Theme, &Config, bool, usize) -> GutterFn<'doc>;
7+ for<'doc> fn(&'doc Editor, &'doc Document, &View, &Theme, bool, usize) -> GutterFn<'doc>;
8
8
9pub fn diagnostic<'doc>(
9pub fn diagnostic<'doc>(
10+ _editor: &'doc Editor,
10 doc: &'doc Document,
11 doc: &'doc Document,
11 _view: &View,
12 _view: &View,
12 theme: &Theme,
13 theme: &Theme,
13− _config: &Config,
14 _is_focused: bool,
14 _is_focused: bool,
15 _width: usize,
15 _width: usize,
16) -> GutterFn<'doc> {
16) -> GutterFn<'doc> {
@@ -36,10 +36,10 @@ pub fn diagnostic<'doc>(
36}
36}
37
37
38pub fn line_number<'doc>(
38pub fn line_number<'doc>(
39+ editor: &'doc Editor,
39 doc: &'doc Document,
40 doc: &'doc Document,
40 view: &View,
41 view: &View,
41 theme: &Theme,
42 theme: &Theme,
42− config: &Config,
43 is_focused: bool,
43 is_focused: bool,
44 width: usize,
44 width: usize,
45) -> GutterFn<'doc> {
45) -> GutterFn<'doc> {
@@ -56,7 +56,7 @@ pub fn line_number<'doc>(
56 .text()
56 .text()
57 .char_to_line(doc.selection(view.id).primary().cursor(text));
57 .char_to_line(doc.selection(view.id).primary().cursor(text));
58
58
59− let config = config.line_number;
59+ let config = editor.config.line_number;
60
60
61 Box::new(move |line: usize, selected: bool, out: &mut String| {
61 Box::new(move |line: usize, selected: bool, out: &mut String| {
62 if line == last_line && !draw_last {
62 if line == last_line && !draw_last {