Detailed changes
@@ -50,6 +50,13 @@
// Whether to pop the completions menu while typing in an editor without
// explicitly requesting it.
"show_completions_on_input": true,
+ // Whether to show wrap guides in the editor. Setting this to true will
+ // show a guide at the 'preferred_line_length' value if softwrap is set to
+ // 'preferred_line_length', and will show any additional guides as specified
+ // by the 'wrap_guides' setting.
+ "show_wrap_guides": true,
+ // Character counts at which to show wrap guides in the editor.
+ "wrap_guides": [],
// Whether to use additional LSP queries to format (and amend) the code after
// every "trigger" symbol input, defined by LSP server capabilities.
"use_on_type_format": true,
@@ -356,12 +363,6 @@
// LSP Specific settings.
"lsp": {
// Specify the LSP name as a key here.
- // As of 8/10/22, supported LSPs are:
- // pyright
- // gopls
- // rust-analyzer
- // typescript-language-server
- // vscode-json-languageserver
// "rust-analyzer": {
// //These initialization options are merged into Zed's defaults
// "initialization_options": {
@@ -7086,6 +7086,20 @@ impl Editor {
.text()
}
+ pub fn wrap_guides(&self, cx: &AppContext) -> SmallVec<[(usize, bool); 2]> {
+ let mut wrap_guides = smallvec::smallvec![];
+
+ let settings = self.buffer.read(cx).settings_at(0, cx);
+ if settings.show_wrap_guides {
+ if let SoftWrap::Column(soft_wrap) = self.soft_wrap_mode(cx) {
+ wrap_guides.push((soft_wrap as usize, true));
+ }
+ wrap_guides.extend(settings.wrap_guides.iter().map(|guide| (*guide, false)))
+ }
+
+ wrap_guides
+ }
+
pub fn soft_wrap_mode(&self, cx: &AppContext) -> SoftWrap {
let settings = self.buffer.read(cx).settings_at(0, cx);
let mode = self
@@ -541,6 +541,24 @@ impl EditorElement {
corner_radius: 0.,
});
}
+
+ for (wrap_position, active) in layout.wrap_guides.iter() {
+ let x = text_bounds.origin_x() + wrap_position + layout.position_map.em_width / 2.;
+ let color = if *active {
+ self.style.active_wrap_guide
+ } else {
+ self.style.wrap_guide
+ };
+ scene.push_quad(Quad {
+ bounds: RectF::new(
+ vec2f(x, text_bounds.origin_y()),
+ vec2f(1., text_bounds.height()),
+ ),
+ background: Some(color),
+ border: Border::new(0., Color::transparent_black()),
+ corner_radius: 0.,
+ });
+ }
}
}
@@ -1320,16 +1338,15 @@ impl EditorElement {
}
}
- fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &ViewContext<Editor>) -> f32 {
- let digit_count = (snapshot.max_buffer_row() as f32 + 1.).log10().floor() as usize + 1;
+ fn column_pixels(&self, column: usize, cx: &ViewContext<Editor>) -> f32 {
let style = &self.style;
cx.text_layout_cache()
.layout_str(
- "1".repeat(digit_count).as_str(),
+ " ".repeat(column).as_str(),
style.text.font_size,
&[(
- digit_count,
+ column,
RunStyle {
font_id: style.text.font_id,
color: Color::black(),
@@ -1340,6 +1357,11 @@ impl EditorElement {
.width()
}
+ fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &ViewContext<Editor>) -> f32 {
+ let digit_count = (snapshot.max_buffer_row() as f32 + 1.).log10().floor() as usize + 1;
+ self.column_pixels(digit_count, cx)
+ }
+
//Folds contained in a hunk are ignored apart from shrinking visual size
//If a fold contains any hunks then that fold line is marked as modified
fn layout_git_gutters(
@@ -2025,6 +2047,12 @@ impl Element<Editor> for EditorElement {
}
};
+ let wrap_guides = editor
+ .wrap_guides(cx)
+ .iter()
+ .map(|(guide, active)| (self.column_pixels(*guide, cx), *active))
+ .collect();
+
let scroll_height = (snapshot.max_point().row() + 1) as f32 * line_height;
if let EditorMode::AutoHeight { max_lines } = snapshot.mode {
size.set_y(
@@ -2385,6 +2413,7 @@ impl Element<Editor> for EditorElement {
snapshot,
}),
visible_display_row_range: start_row..end_row,
+ wrap_guides,
gutter_size,
gutter_padding,
text_size,
@@ -2535,6 +2564,7 @@ pub struct LayoutState {
gutter_margin: f32,
text_size: Vector2F,
mode: EditorMode,
+ wrap_guides: SmallVec<[(f32, bool); 2]>,
visible_display_row_range: Range<u32>,
active_rows: BTreeMap<u32, bool>,
highlighted_rows: Option<Range<u32>>,
@@ -44,6 +44,8 @@ pub struct LanguageSettings {
pub hard_tabs: bool,
pub soft_wrap: SoftWrap,
pub preferred_line_length: u32,
+ pub show_wrap_guides: bool,
+ pub wrap_guides: Vec<usize>,
pub format_on_save: FormatOnSave,
pub remove_trailing_whitespace_on_save: bool,
pub ensure_final_newline_on_save: bool,
@@ -84,6 +86,10 @@ pub struct LanguageSettingsContent {
#[serde(default)]
pub preferred_line_length: Option<u32>,
#[serde(default)]
+ pub show_wrap_guides: Option<bool>,
+ #[serde(default)]
+ pub wrap_guides: Option<Vec<usize>>,
+ #[serde(default)]
pub format_on_save: Option<FormatOnSave>,
#[serde(default)]
pub remove_trailing_whitespace_on_save: Option<bool>,
@@ -378,6 +384,9 @@ fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent
merge(&mut settings.tab_size, src.tab_size);
merge(&mut settings.hard_tabs, src.hard_tabs);
merge(&mut settings.soft_wrap, src.soft_wrap);
+ merge(&mut settings.show_wrap_guides, src.show_wrap_guides);
+ merge(&mut settings.wrap_guides, src.wrap_guides.clone());
+
merge(
&mut settings.preferred_line_length,
src.preferred_line_length,
@@ -691,6 +691,8 @@ pub struct Editor {
pub document_highlight_read_background: Color,
pub document_highlight_write_background: Color,
pub diff: DiffStyle,
+ pub wrap_guide: Color,
+ pub active_wrap_guide: Color,
pub line_number: Color,
pub line_number_active: Color,
pub guest_selections: Vec<SelectionStyle>,
@@ -170,6 +170,8 @@ export default function editor(): any {
line_number: with_opacity(foreground(layer), 0.35),
line_number_active: foreground(layer),
rename_fade: 0.6,
+ wrap_guide: with_opacity(foreground(layer), 0.1),
+ active_wrap_guide: with_opacity(foreground(layer), 0.2),
unnecessary_code_fade: 0.5,
selection: theme.players[0],
whitespace: theme.ramps.neutral(0.5).hex(),