-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
repl: Add inlay repl output display, skip empty lines on execution, and gutter execution display #44523
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
repl: Add inlay repl output display, skip empty lines on execution, and gutter execution display #44523
Changes from all commits
0bd508d
47b8411
1e6d083
770030b
547c1dd
36197f1
7bd53e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -433,6 +433,36 @@ fn runnable_ranges( | |
| } | ||
|
|
||
| let snippet_range = cell_range(buffer, range.start.row, range.end.row); | ||
|
|
||
| // Check if the snippet range is entirely blank, if so, skip forward to find code | ||
| let is_blank = | ||
| (snippet_range.start.row..=snippet_range.end.row).all(|row| buffer.is_line_blank(row)); | ||
|
|
||
| if is_blank { | ||
| // Search forward for the next non-blank line | ||
| let max_row = buffer.max_point().row; | ||
| let mut next_row = snippet_range.end.row + 1; | ||
| while next_row <= max_row && buffer.is_line_blank(next_row) { | ||
| next_row += 1; | ||
| } | ||
|
|
||
| if next_row <= max_row { | ||
| // Found a non-blank line, find the extent of this cell | ||
| let next_snippet_range = cell_range(buffer, next_row, next_row); | ||
| let start_language = buffer.language_at(next_snippet_range.start); | ||
| let end_language = buffer.language_at(next_snippet_range.end); | ||
|
|
||
| if start_language | ||
| .zip(end_language) | ||
| .is_some_and(|(start, end)| start == end) | ||
| { | ||
| return (vec![next_snippet_range], None); | ||
| } | ||
| } | ||
|
|
||
| return (Vec::new(), None); | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's one edge case to deal with, though it's not too big a deal. If you run the last line in a script where there's no newline the checkmark ends up after the line you actually ran.
As an alternative, this could be emitted as a bit of an output "marker" so that if there were display updates that come in after (likely via a callback) then we can toss the output.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! |
||
|
|
||
| let start_language = buffer.language_at(snippet_range.start); | ||
| let end_language = buffer.language_at(snippet_range.end); | ||
|
|
||
|
|
@@ -821,4 +851,76 @@ mod tests { | |
| },] | ||
| ); | ||
| } | ||
|
|
||
| #[gpui::test] | ||
| fn test_skip_blank_lines_to_next_cell(cx: &mut App) { | ||
| let test_language = Arc::new(Language::new( | ||
| LanguageConfig { | ||
| name: "TestLang".into(), | ||
| line_comments: vec!["# ".into()], | ||
| ..Default::default() | ||
| }, | ||
| None, | ||
| )); | ||
|
|
||
| let buffer = cx.new(|cx| { | ||
| Buffer::local( | ||
| indoc! { r#" | ||
| print(1 + 1) | ||
|
|
||
| print(2 + 2) | ||
| "# }, | ||
| cx, | ||
| ) | ||
| .with_language(test_language.clone(), cx) | ||
| }); | ||
| let snapshot = buffer.read(cx).snapshot(); | ||
|
|
||
| // Selection on blank line should skip to next non-blank cell | ||
| let (snippets, _) = runnable_ranges(&snapshot, Point::new(1, 0)..Point::new(1, 0), cx); | ||
| let snippets = snippets | ||
| .into_iter() | ||
| .map(|range| snapshot.text_for_range(range).collect::<String>()) | ||
| .collect::<Vec<_>>(); | ||
| assert_eq!(snippets, vec!["print(2 + 2)"]); | ||
|
|
||
| // Multiple blank lines should also skip forward | ||
| let buffer = cx.new(|cx| { | ||
| Buffer::local( | ||
| indoc! { r#" | ||
| print(1 + 1) | ||
|
|
||
|
|
||
|
|
||
| print(2 + 2) | ||
| "# }, | ||
| cx, | ||
| ) | ||
| .with_language(test_language.clone(), cx) | ||
| }); | ||
| let snapshot = buffer.read(cx).snapshot(); | ||
|
|
||
| let (snippets, _) = runnable_ranges(&snapshot, Point::new(2, 0)..Point::new(2, 0), cx); | ||
| let snippets = snippets | ||
| .into_iter() | ||
| .map(|range| snapshot.text_for_range(range).collect::<String>()) | ||
| .collect::<Vec<_>>(); | ||
| assert_eq!(snippets, vec!["print(2 + 2)"]); | ||
|
|
||
| // Blank lines at end of file should return nothing | ||
| let buffer = cx.new(|cx| { | ||
| Buffer::local( | ||
| indoc! { r#" | ||
| print(1 + 1) | ||
|
|
||
| "# }, | ||
| cx, | ||
| ) | ||
| .with_language(test_language, cx) | ||
| }); | ||
| let snapshot = buffer.read(cx).snapshot(); | ||
|
|
||
| let (snippets, _) = runnable_ranges(&snapshot, Point::new(1, 0)..Point::new(1, 0), cx); | ||
| assert!(snippets.is_empty()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,15 @@ pub struct ReplSettings { | |
| /// | ||
| /// Default: 128 | ||
| pub max_columns: usize, | ||
| /// Whether to show small single-line outputs inline instead of in a block. | ||
| /// | ||
| /// Default: true | ||
| pub inline_output: bool, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using this now and loving it. |
||
| /// Maximum number of characters for an output to be shown inline. | ||
| /// Only applies when `inline_output` is true. | ||
| /// | ||
| /// Default: 50 | ||
| pub inline_output_max_length: usize, | ||
| } | ||
|
|
||
| impl Settings for ReplSettings { | ||
|
|
@@ -22,6 +31,8 @@ impl Settings for ReplSettings { | |
| Self { | ||
| max_lines: repl.max_lines.unwrap(), | ||
| max_columns: repl.max_columns.unwrap(), | ||
| inline_output: repl.inline_output.unwrap_or(true), | ||
| inline_output_max_length: repl.inline_output_max_length.unwrap_or(50), | ||
| } | ||
| } | ||
| } | ||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While not likely with any of the kernels, if an output comes after an idle then we may be keeping a loose checkmark when it should be cleared out.