feat: added rounded-corners option to draw rounded borders

This commit is contained in:
Fabian Gruber 2024-08-11 19:41:48 +02:00
parent 90f978d5af
commit a14a7d7eb6
8 changed files with 38 additions and 14 deletions

View File

@ -49,6 +49,7 @@ ### `[editor]` Section
| `default-line-ending` | The line ending to use for new documents. Can be `native`, `lf`, `crlf`, `ff`, `cr` or `nel`. `native` uses the platform's native line ending (`crlf` on Windows, otherwise `lf`). | `native` | | `default-line-ending` | The line ending to use for new documents. Can be `native`, `lf`, `crlf`, `ff`, `cr` or `nel`. `native` uses the platform's native line ending (`crlf` on Windows, otherwise `lf`). | `native` |
| `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` | | `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` |
| `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` | | `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` |
| `rounded-corners` | Set to `true` to draw rounded border corners | `false` |
| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid` | `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
| `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"` | `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"`
| `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable" | `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable"

View File

@ -9,7 +9,7 @@
theme::{Modifier, Style}, theme::{Modifier, Style},
ViewId, ViewId,
}; };
use tui::{buffer::Buffer as Surface, text::Span}; use tui::{buffer::Buffer as Surface, text::Span, widgets::BorderType};
use std::{borrow::Cow, sync::Arc}; use std::{borrow::Cow, sync::Arc};
@ -531,7 +531,12 @@ fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
if cx.editor.popup_border() { if cx.editor.popup_border() {
use tui::widgets::{Block, Widget}; use tui::widgets::{Block, Widget};
Widget::render(Block::bordered(), doc_area, surface); let border_type = BorderType::new(cx.editor.config().rounded_corners);
Widget::render(
Block::bordered().border_type(border_type),
doc_area,
surface,
);
} }
markdown_doc.render(doc_area, surface, cx); markdown_doc.render(doc_area, surface, cx);

View File

@ -3,7 +3,7 @@
use helix_view::info::Info; use helix_view::info::Info;
use tui::buffer::Buffer as Surface; use tui::buffer::Buffer as Surface;
use tui::text::Text; use tui::text::Text;
use tui::widgets::{Block, Paragraph, Widget}; use tui::widgets::{Block, BorderType, Paragraph, Widget};
impl Component for Info { impl Component for Info {
fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) { fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
@ -23,9 +23,11 @@ fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
)); ));
surface.clear_with(area, popup_style); surface.clear_with(area, popup_style);
let border_type = BorderType::new(cx.editor.config().rounded_corners);
let block = Block::bordered() let block = Block::bordered()
.title(self.title.as_str()) .title(self.title.as_str())
.border_style(popup_style); .border_style(popup_style)
.border_type(border_type);
let margin = Margin::horizontal(1); let margin = Margin::horizontal(1);
let inner = block.inner(area).inner(margin); let inner = block.inner(area).inner(margin);

View File

@ -655,12 +655,13 @@ fn render_picker(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context)
let background = cx.editor.theme.get("ui.background"); let background = cx.editor.theme.get("ui.background");
surface.clear_with(area, background); surface.clear_with(area, background);
const BLOCK: Block<'_> = Block::bordered(); let border_type = BorderType::new(cx.editor.config().rounded_corners);
let block: Block<'_> = Block::bordered().border_type(border_type);
// calculate the inner area inside the box // calculate the inner area inside the box
let inner = BLOCK.inner(area); let inner = block.inner(area);
BLOCK.render(area, surface); block.render(area, surface);
// -- Render the input bar: // -- Render the input bar:
@ -840,14 +841,15 @@ fn render_preview(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context
let text = cx.editor.theme.get("ui.text"); let text = cx.editor.theme.get("ui.text");
surface.clear_with(area, background); surface.clear_with(area, background);
const BLOCK: Block<'_> = Block::bordered(); let border_type = BorderType::new(cx.editor.config().rounded_corners);
let block: Block<'_> = Block::bordered().border_type(border_type);
// calculate the inner area inside the box // calculate the inner area inside the box
let inner = BLOCK.inner(area); let inner = block.inner(area);
// 1 column gap on either side // 1 column gap on either side
let margin = Margin::horizontal(1); let margin = Margin::horizontal(1);
let inner = inner.inner(margin); let inner = inner.inner(margin);
BLOCK.render(area, surface); block.render(area, surface);
if let Some((preview, range)) = self.get_preview(cx.editor) { if let Some((preview, range)) = self.get_preview(cx.editor) {
let doc = match preview.document() { let doc = match preview.document() {

View File

@ -5,7 +5,7 @@
}; };
use tui::{ use tui::{
buffer::Buffer as Surface, buffer::Buffer as Surface,
widgets::{Block, Widget}, widgets::{Block, BorderType, Widget},
}; };
use helix_core::Position; use helix_core::Position;
@ -323,8 +323,9 @@ fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
let mut inner = area; let mut inner = area;
if render_borders { if render_borders {
let border_type = BorderType::new(cx.editor.config().rounded_corners);
inner = area.inner(Margin::all(1)); inner = area.inner(Margin::all(1));
Widget::render(Block::bordered(), area, surface); Widget::render(Block::bordered().border_type(border_type), area, surface);
} }
let border = usize::from(render_borders); let border = usize::from(render_borders);

View File

@ -8,7 +8,7 @@
use std::sync::Arc; use std::sync::Arc;
use std::{borrow::Cow, ops::RangeFrom}; use std::{borrow::Cow, ops::RangeFrom};
use tui::buffer::Buffer as Surface; use tui::buffer::Buffer as Surface;
use tui::widgets::{Block, Widget}; use tui::widgets::{Block, BorderType, Widget};
use helix_core::{ use helix_core::{
unicode::segmentation::GraphemeCursor, unicode::width::UnicodeWidthStr, Position, unicode::segmentation::GraphemeCursor, unicode::width::UnicodeWidthStr, Position,
@ -485,9 +485,11 @@ pub fn render_prompt(&self, area: Rect, surface: &mut Surface, cx: &mut Context)
let background = theme.get("ui.help"); let background = theme.get("ui.help");
surface.clear_with(area, background); surface.clear_with(area, background);
let border_type = BorderType::new(cx.editor.config().rounded_corners);
let block = Block::bordered() let block = Block::bordered()
// .title(self.title.as_str()) // .title(self.title.as_str())
.border_style(background); .border_style(background)
.border_type(border_type);
let inner = block.inner(area).inner(Margin::horizontal(1)); let inner = block.inner(area).inner(Margin::horizontal(1));

View File

@ -17,6 +17,14 @@ pub enum BorderType {
} }
impl BorderType { impl BorderType {
pub fn new(rounded: bool) -> Self {
if rounded {
Self::Rounded
} else {
Self::default()
}
}
pub fn line_symbols(border_type: Self) -> line::Set { pub fn line_symbols(border_type: Self) -> line::Set {
match border_type { match border_type {
Self::Plain => line::NORMAL, Self::Plain => line::NORMAL,

View File

@ -333,6 +333,8 @@ pub struct Config {
pub smart_tab: Option<SmartTabConfig>, pub smart_tab: Option<SmartTabConfig>,
/// Draw border around popups. /// Draw border around popups.
pub popup_border: PopupBorderConfig, pub popup_border: PopupBorderConfig,
/// Draw rounded border corners
pub rounded_corners: bool,
/// Which indent heuristic to use when a new line is inserted /// Which indent heuristic to use when a new line is inserted
#[serde(default)] #[serde(default)]
pub indent_heuristic: IndentationHeuristic, pub indent_heuristic: IndentationHeuristic,
@ -975,6 +977,7 @@ fn default() -> Self {
insert_final_newline: true, insert_final_newline: true,
smart_tab: Some(SmartTabConfig::default()), smart_tab: Some(SmartTabConfig::default()),
popup_border: PopupBorderConfig::None, popup_border: PopupBorderConfig::None,
rounded_corners: false,
indent_heuristic: IndentationHeuristic::default(), indent_heuristic: IndentationHeuristic::default(),
jump_label_alphabet: ('a'..='z').collect(), jump_label_alphabet: ('a'..='z').collect(),
inline_diagnostics: InlineDiagnosticsConfig::default(), inline_diagnostics: InlineDiagnosticsConfig::default(),