pull/2308/head
chunghha 3 years ago committed by GitHub
parent 2e46961886
commit 3a398eec56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -445,7 +445,7 @@ Fixes:
- A bunch of bugs regarding `o`/`O` behavior ([#281](https://github.com/helix-editor/helix/pull/281)) - A bunch of bugs regarding `o`/`O` behavior ([#281](https://github.com/helix-editor/helix/pull/281))
- `~` expansion now works in file completion ([#284](https://github.com/helix-editor/helix/pull/284)) - `~` expansion now works in file completion ([#284](https://github.com/helix-editor/helix/pull/284))
- Several UI related overflow crashes ([#318](https://github.com/helix-editor/helix/pull/318)) - Several UI related overflow crashes ([#318](https://github.com/helix-editor/helix/pull/318))
- Fix a test failure occuring only on `test --release` ([`4f108ab1`](https://github.com/helix-editor/helix/commit/4f108ab1b2197809506bd7305ad903a3525eabfa)) - Fix a test failure occurring only on `test --release` ([`4f108ab1`](https://github.com/helix-editor/helix/commit/4f108ab1b2197809506bd7305ad903a3525eabfa))
- Prompts now support unicode input ([#295](https://github.com/helix-editor/helix/pull/295)) - Prompts now support unicode input ([#295](https://github.com/helix-editor/helix/pull/295))
- Completion documentation no longer overlaps the popup ([#322](https://github.com/helix-editor/helix/pull/322)) - Completion documentation no longer overlaps the popup ([#322](https://github.com/helix-editor/helix/pull/322))
- Fix a crash when trying to select `^` ([`9c534614`](https://github.com/helix-editor/helix/commit/9c53461429a3e72e3b1fb87d7ca490e168d7dee2)) - Fix a crash when trying to select `^` ([`9c534614`](https://github.com/helix-editor/helix/commit/9c53461429a3e72e3b1fb87d7ca490e168d7dee2))

@ -43,7 +43,7 @@ hidden = false
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` | | `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
| `auto-info` | Whether to display infoboxes | `true` | | `auto-info` | Whether to display infoboxes | `true` |
| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` | | `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` |
| `rulers` | List of column positions at which to display the rulers. Can be overidden by language specific `rulers` in `languages.toml` file. | `[]` | | `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file. | `[]` |
### `[editor.lsp]` Section ### `[editor.lsp]` Section

@ -7,8 +7,8 @@
| `:buffer-close!`, `:bc!`, `:bclose!` | Close the current buffer forcefully (ignoring unsaved changes). | | `:buffer-close!`, `:bc!`, `:bclose!` | Close the current buffer forcefully (ignoring unsaved changes). |
| `:buffer-close-others`, `:bco`, `:bcloseother` | Close all buffers but the currently focused one. | | `:buffer-close-others`, `:bco`, `:bcloseother` | Close all buffers but the currently focused one. |
| `:buffer-close-others!`, `:bco!`, `:bcloseother!` | Close all buffers but the currently focused one. | | `:buffer-close-others!`, `:bco!`, `:bcloseother!` | Close all buffers but the currently focused one. |
| `:buffer-close-all`, `:bca`, `:bcloseall` | Close all buffers, without quiting. | | `:buffer-close-all`, `:bca`, `:bcloseall` | Close all buffers, without quitting. |
| `:buffer-close-all!`, `:bca!`, `:bcloseall!` | Close all buffers forcefully (ignoring unsaved changes), without quiting. | | `:buffer-close-all!`, `:bca!`, `:bcloseall!` | Close all buffers forcefully (ignoring unsaved changes), without quitting. |
| `:buffer-next`, `:bn`, `:bnext` | Go to next buffer. | | `:buffer-next`, `:bn`, `:bnext` | Go to next buffer. |
| `:buffer-previous`, `:bp`, `:bprev` | Go to previous buffer. | | `:buffer-previous`, `:bp`, `:bprev` | Go to previous buffer. |
| `:write`, `:w` | Write changes to disk. Accepts an optional path (:write some/path.txt) | | `:write`, `:w` | Write changes to disk. Accepts an optional path (:write some/path.txt) |

@ -1,4 +1,4 @@
# Guides # Guides
This section contains guides for adding new language server configurations, This section contains guides for adding new language server configurations,
tree-sitter grammers, textobject queries, etc. tree-sitter grammars, textobject queries, etc.

@ -39,7 +39,7 @@ changed by using a `#set!` declaration anywhere in the pattern:
## Capture Types ## Capture Types
- `@indent` (default scope `tail`): - `@indent` (default scope `tail`):
Increase the indent level by 1. Multiple occurences in the same line Increase the indent level by 1. Multiple occurrences in the same line
don't stack. If there is at least one `@indent` and one `@outdent` don't stack. If there is at least one `@indent` and one `@outdent`
capture on the same line, the indent level isn't changed at all. capture on the same line, the indent level isn't changed at all.

@ -58,7 +58,7 @@ cargo install --path helix-term
This will install the `hx` binary to `$HOME/.cargo/bin`. This will install the `hx` binary to `$HOME/.cargo/bin`.
Helix also needs it's runtime files so make sure to copy/symlink the `runtime/` directory into the Helix also needs it's runtime files so make sure to copy/symlink the `runtime/` directory into the
config directory (for example `~/.config/helix/runtime` on Linux/macOS). This location can be overriden config directory (for example `~/.config/helix/runtime` on Linux/macOS). This location can be overridden
via the `HELIX_RUNTIME` environment variable. via the `HELIX_RUNTIME` environment variable.
| OS | command | | OS | command |

@ -191,7 +191,7 @@ Jumps to various locations.
#### Match mode #### Match mode
Enter this mode using `m` from normal mode. See the relavant section Enter this mode using `m` from normal mode. See the relevant section
in [Usage](./usage.md) for an explanation about [surround](./usage.md#surround) in [Usage](./usage.md) for an explanation about [surround](./usage.md#surround)
and [textobject](./usage.md#textobject) usage. and [textobject](./usage.md#textobject) usage.

@ -158,7 +158,7 @@ We use a similar set of scopes as
- `builtin` - `builtin`
- `method` - `method`
- `macro` - `macro`
- `special` (preprocesor in C) - `special` (preprocessor in C)
- `tag` - Tags (e.g. `<body>` in HTML) - `tag` - Tags (e.g. `<body>` in HTML)

@ -601,10 +601,10 @@ function playground_text(playground) {
}); });
})(); })();
(function controllMenu() { (function controlMenu() {
var menu = document.getElementById('menu-bar'); var menu = document.getElementById('menu-bar');
(function controllPosition() { (function controlPosition() {
var scrollTop = document.scrollingElement.scrollTop; var scrollTop = document.scrollingElement.scrollTop;
var prevScrollTop = scrollTop; var prevScrollTop = scrollTop;
var minMenuY = -menu.clientHeight - 50; var minMenuY = -menu.clientHeight - 50;
@ -647,7 +647,7 @@ function playground_text(playground) {
prevScrollTop = scrollTop; prevScrollTop = scrollTop;
}, { passive: true }); }, { passive: true });
})(); })();
(function controllBorder() { (function controlBorder() {
menu.classList.remove('bordered'); menu.classList.remove('bordered');
document.addEventListener('scroll', function () { document.addEventListener('scroll', function () {
if (menu.offsetTop === 0) { if (menu.offsetTop === 0) {

@ -390,7 +390,7 @@ ul#searchresults span.teaser em {
.chapter li { .chapter li {
display: flex; display: flex;
color: var(--sidebar-non-existant); color: var(--sidebar-non-existent);
} }
.chapter li a { .chapter li a {
display: block; display: block;

@ -16,7 +16,7 @@
--sidebar-bg: #14191f; --sidebar-bg: #14191f;
--sidebar-fg: #c8c9db; --sidebar-fg: #c8c9db;
--sidebar-non-existant: #5c6773; --sidebar-non-existent: #5c6773;
--sidebar-active: #ffb454; --sidebar-active: #ffb454;
--sidebar-spacer: #2d334f; --sidebar-spacer: #2d334f;
@ -56,7 +56,7 @@
--sidebar-bg: #292c2f; --sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8; --sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254; --sidebar-non-existent: #505254;
--sidebar-active: #3473ad; --sidebar-active: #3473ad;
--sidebar-spacer: #393939; --sidebar-spacer: #393939;
@ -96,7 +96,7 @@
--sidebar-bg: #fafafa; --sidebar-bg: #fafafa;
--sidebar-fg: hsl(0, 0%, 0%); --sidebar-fg: hsl(0, 0%, 0%);
--sidebar-non-existant: #aaaaaa; --sidebar-non-existent: #aaaaaa;
--sidebar-active: #1f1fff; --sidebar-active: #1f1fff;
--sidebar-spacer: #f4f4f4; --sidebar-spacer: #f4f4f4;
@ -136,7 +136,7 @@
--sidebar-bg: #282d3f; --sidebar-bg: #282d3f;
--sidebar-fg: #c8c9db; --sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274; --sidebar-non-existent: #505274;
--sidebar-active: #2b79a2; --sidebar-active: #2b79a2;
--sidebar-spacer: #2d334f; --sidebar-spacer: #2d334f;
@ -176,7 +176,7 @@
--sidebar-bg: #3b2e2a; --sidebar-bg: #3b2e2a;
--sidebar-fg: #c8c9db; --sidebar-fg: #c8c9db;
--sidebar-non-existant: #505254; --sidebar-non-existent: #505254;
--sidebar-active: #e69f67; --sidebar-active: #e69f67;
--sidebar-spacer: #45373a; --sidebar-spacer: #45373a;
@ -217,7 +217,7 @@
--sidebar-bg: #292c2f; --sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8; --sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254; --sidebar-non-existent: #505254;
--sidebar-active: #3473ad; --sidebar-active: #3473ad;
--sidebar-spacer: #393939; --sidebar-spacer: #393939;
@ -259,7 +259,7 @@
--sidebar-bg: #281733; --sidebar-bg: #281733;
--sidebar-fg: #c8c9db; --sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274; --sidebar-non-existent: #505274;
--sidebar-active: #a4a0e8; --sidebar-active: #a4a0e8;
--sidebar-spacer: #2d334f; --sidebar-spacer: #2d334f;
@ -304,7 +304,7 @@
--sidebar-bg: #281733; --sidebar-bg: #281733;
--sidebar-fg: #c8c9db; --sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274; --sidebar-non-existent: #505274;
--sidebar-active: #a4a0e8; --sidebar-active: #a4a0e8;
--sidebar-spacer: #2d334f; --sidebar-spacer: #2d334f;

@ -22,10 +22,10 @@ use std::time::{Duration, Instant};
/// ///
/// The current revision is the one currently displayed in the buffer. /// The current revision is the one currently displayed in the buffer.
/// ///
/// Commiting a new revision to the history will update the last child of the /// Committing a new revision to the history will update the last child of the
/// current revision, and push a new revision to the end of the vector. /// current revision, and push a new revision to the end of the vector.
/// ///
/// Revisions are commited with a timestamp. :earlier and :later can be used /// Revisions are committed with a timestamp. :earlier and :later can be used
/// to jump to the closest revision to a moment in time relative to the timestamp /// to jump to the closest revision to a moment in time relative to the timestamp
/// of the current revision plus (:later) or minus (:earlier) the duration /// of the current revision plus (:later) or minus (:earlier) the duration
/// given to the command. If a single integer is given, the editor will instead /// given to the command. If a single integer is given, the editor will instead
@ -33,7 +33,7 @@ use std::time::{Duration, Instant};
/// ///
/// Limitations: /// Limitations:
/// * Changes in selections currently don't commit history changes. The selection /// * Changes in selections currently don't commit history changes. The selection
/// will only be updated to the state after a commited buffer change. /// will only be updated to the state after a committed buffer change.
/// * The vector of history revisions is currently unbounded. This might /// * The vector of history revisions is currently unbounded. This might
/// cause the memory consumption to grow significantly large during long /// cause the memory consumption to grow significantly large during long
/// editing sessions. /// editing sessions.
@ -288,7 +288,7 @@ pub enum UndoKind {
TimePeriod(std::time::Duration), TimePeriod(std::time::Duration),
} }
/// A subset of sytemd.time time span syntax units. /// A subset of systemd.time time span syntax units.
const TIME_UNITS: &[(&[&str], &str, u64)] = &[ const TIME_UNITS: &[(&[&str], &str, u64)] = &[
(&["seconds", "second", "sec", "s"], "seconds", 1), (&["seconds", "second", "sec", "s"], "seconds", 1),
(&["minutes", "minute", "min", "m"], "minutes", 60), (&["minutes", "minute", "min", "m"], "minutes", 60),

@ -14,7 +14,7 @@ pub fn fold_home_dir(path: &Path) -> PathBuf {
path.to_path_buf() path.to_path_buf()
} }
/// Expands tilde `~` into users home directory if avilable, otherwise returns the path /// Expands tilde `~` into users home directory if available, otherwise returns the path
/// unchanged. The tilde will only be expanded when present as the first component of the path /// unchanged. The tilde will only be expanded when present as the first component of the path
/// and only slash follows it. /// and only slash follows it.
pub fn expand_tilde(path: &Path) -> PathBuf { pub fn expand_tilde(path: &Path) -> PathBuf {

@ -229,7 +229,7 @@ pub struct TextObjectQuery {
pub enum CapturedNode<'a> { pub enum CapturedNode<'a> {
Single(Node<'a>), Single(Node<'a>),
/// Guarenteed to be not empty /// Guaranteed to be not empty
Grouped(Vec<Node<'a>>), Grouped(Vec<Node<'a>>),
} }
@ -1141,7 +1141,7 @@ pub enum HighlightEvent {
HighlightEnd, HighlightEnd,
} }
/// Contains the data neeeded to higlight code written in a particular language. /// Contains the data needed to highlight code written in a particular language.
/// ///
/// This struct is immutable and can be shared between threads. /// This struct is immutable and can be shared between threads.
#[derive(Debug)] #[derive(Debug)]
@ -1976,7 +1976,7 @@ mod test {
let source = Rope::from_str( let source = Rope::from_str(
r#" r#"
/// a comment on /// a comment on
/// mutiple lines /// multiple lines
"#, "#,
); );
@ -2006,10 +2006,10 @@ mod test {
) )
}; };
test("quantified_nodes", 1..35); test("quantified_nodes", 1..36);
// NOTE: Enable after implementing proper node group capturing // NOTE: Enable after implementing proper node group capturing
// test("quantified_nodes_grouped", 1..35); // test("quantified_nodes_grouped", 1..36);
// test("multiple_nodes_grouped", 1..35); // test("multiple_nodes_grouped", 1..36);
} }
#[test] #[test]

@ -428,7 +428,7 @@ impl LspProgressMap {
Self::default() Self::default()
} }
/// Returns a map of all tokens coresponding to the lanaguage server with `id`. /// Returns a map of all tokens corresponding to the language server with `id`.
pub fn progress_map(&self, id: usize) -> Option<&HashMap<lsp::ProgressToken, ProgressStatus>> { pub fn progress_map(&self, id: usize) -> Option<&HashMap<lsp::ProgressToken, ProgressStatus>> {
self.0.get(&id) self.0.get(&id)
} }
@ -466,7 +466,7 @@ impl LspProgressMap {
self.0.get_mut(&id).and_then(|vals| vals.remove(token)) self.0.get_mut(&id).and_then(|vals| vals.remove(token))
} }
/// Updates the progess of `token` for server with `id` to `status`, returns the value replaced or `None`. /// Updates the progress of `token` for server with `id` to `status`, returns the value replaced or `None`.
pub fn update( pub fn update(
&mut self, &mut self,
id: usize, id: usize,

@ -3715,7 +3715,7 @@ fn shrink_selection(cx: &mut Context) {
doc.set_selection(view.id, prev_selection); doc.set_selection(view.id, prev_selection);
return; return;
} else { } else {
// clear existing selection as they can't be shrinked to anyway // clear existing selection as they can't be shrunk to anyway
view.object_selections.clear(); view.object_selections.clear();
} }
} }

@ -1169,14 +1169,14 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
TypableCommand { TypableCommand {
name: "buffer-close-all", name: "buffer-close-all",
aliases: &["bca", "bcloseall"], aliases: &["bca", "bcloseall"],
doc: "Close all buffers, without quiting.", doc: "Close all buffers, without quitting.",
fun: buffer_close_all, fun: buffer_close_all,
completer: None, completer: None,
}, },
TypableCommand { TypableCommand {
name: "buffer-close-all!", name: "buffer-close-all!",
aliases: &["bca!", "bcloseall!"], aliases: &["bca!", "bcloseall!"],
doc: "Close all buffers forcefully (ignoring unsaved changes), without quiting.", doc: "Close all buffers forcefully (ignoring unsaved changes), without quitting.",
fun: force_buffer_close_all, fun: force_buffer_close_all,
completer: None, completer: None,
}, },

@ -1239,7 +1239,7 @@ impl Component for EditorView {
view.ensure_cursor_in_view(doc, config.scrolloff); view.ensure_cursor_in_view(doc, config.scrolloff);
// Store a history state if not in insert mode. This also takes care of // Store a history state if not in insert mode. This also takes care of
// commiting changes when leaving insert mode. // committing changes when leaving insert mode.
if doc.mode() != Mode::Insert { if doc.mode() != Mode::Insert {
doc.append_changes_to_history(view.id); doc.append_changes_to_history(view.id);
} }

@ -322,7 +322,7 @@ impl Buffer {
continue; continue;
} }
// `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we // `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we
// change dimenstions to usize or u32 and someone resizes the terminal to 1x2^32. // change dimensions to usize or u32 and someone resizes the terminal to 1x2^32.
if width > max_offset.saturating_sub(x_offset) { if width > max_offset.saturating_sub(x_offset) {
break; break;
} }
@ -563,9 +563,9 @@ impl Buffer {
let width = self.area.width; let width = self.area.width;
let mut updates: Vec<(u16, u16, &Cell)> = vec![]; let mut updates: Vec<(u16, u16, &Cell)> = vec![];
// Cells invalidated by drawing/replacing preceeding multi-width characters: // Cells invalidated by drawing/replacing preceding multi-width characters:
let mut invalidated: usize = 0; let mut invalidated: usize = 0;
// Cells from the current buffer to skip due to preceeding multi-width characters taking their // Cells from the current buffer to skip due to preceding multi-width characters taking their
// place (the skipped cells should be blank anyway): // place (the skipped cells should be blank anyway):
let mut to_skip: usize = 0; let mut to_skip: usize = 0;
for (i, (current, previous)) in next_buffer.iter().zip(previous_buffer.iter()).enumerate() { for (i, (current, previous)) in next_buffer.iter().zip(previous_buffer.iter()).enumerate() {

@ -128,7 +128,7 @@ pub struct LineTruncator<'a, 'b> {
symbols: &'b mut dyn Iterator<Item = StyledGrapheme<'a>>, symbols: &'b mut dyn Iterator<Item = StyledGrapheme<'a>>,
max_line_width: u16, max_line_width: u16,
current_line: Vec<StyledGrapheme<'a>>, current_line: Vec<StyledGrapheme<'a>>,
/// Record the offet to skip render /// Record the offset to skip render
horizontal_offset: u16, horizontal_offset: u16,
} }
@ -439,7 +439,7 @@ mod test {
assert_eq!(line_truncator, vec![" "]); assert_eq!(line_truncator, vec![" "]);
} }
/// Tests an input starting with a letter, folowed by spaces - some of the behaviour is /// Tests an input starting with a letter, followed by spaces - some of the behaviour is
/// incidental. /// incidental.
#[test] #[test]
fn line_composer_char_plus_lots_of_spaces() { fn line_composer_char_plus_lots_of_spaces() {

@ -68,7 +68,7 @@ where
/// Row::new(vec!["Cell1", "Cell2", "Cell3"]); /// Row::new(vec!["Cell1", "Cell2", "Cell3"]);
/// ``` /// ```
/// ///
/// But if you need a bit more control over individual cells, you can explicity create [`Cell`]s: /// But if you need a bit more control over individual cells, you can explicitly create [`Cell`]s:
/// ```rust /// ```rust
/// # use helix_tui::widgets::{Row, Cell}; /// # use helix_tui::widgets::{Row, Cell};
/// # use helix_view::graphics::{Style, Color}; /// # use helix_view::graphics::{Style, Color};
@ -109,7 +109,7 @@ impl<'a> Row<'a> {
self self
} }
/// Set the [`Style`] of the entire row. This [`Style`] can be overriden by the [`Style`] of a /// Set the [`Style`] of the entire row. This [`Style`] can be overridden by the [`Style`] of a
/// any individual [`Cell`] or event by their [`Text`] content. /// any individual [`Cell`] or event by their [`Text`] content.
pub fn style(mut self, style: Style) -> Self { pub fn style(mut self, style: Style) -> Self {
self.style = style; self.style = style;

@ -17,15 +17,15 @@ fn terminal_buffer_size_should_be_limited() {
// let backend = TestBackend::new(10, 10); // let backend = TestBackend::new(10, 10);
// let mut terminal = Terminal::new(backend)?; // let mut terminal = Terminal::new(backend)?;
// let frame = terminal.draw(|f| { // let frame = terminal.draw(|f| {
// let paragrah = Paragraph::new("Test"); // let paragraph = Paragraph::new("Test");
// f.render_widget(paragrah, f.size()); // f.render_widget(paragraph, f.size());
// })?; // })?;
// assert_eq!(frame.buffer.get(0, 0).symbol, "T"); // assert_eq!(frame.buffer.get(0, 0).symbol, "T");
// assert_eq!(frame.area, Rect::new(0, 0, 10, 10)); // assert_eq!(frame.area, Rect::new(0, 0, 10, 10));
// terminal.backend_mut().resize(8, 8); // terminal.backend_mut().resize(8, 8);
// let frame = terminal.draw(|f| { // let frame = terminal.draw(|f| {
// let paragrah = Paragraph::new("test"); // let paragraph = Paragraph::new("test");
// f.render_widget(paragrah, f.size()); // f.render_widget(paragraph, f.size());
// })?; // })?;
// assert_eq!(frame.buffer.get(0, 0).symbol, "t"); // assert_eq!(frame.buffer.get(0, 0).symbol, "t");
// assert_eq!(frame.area, Rect::new(0, 0, 8, 8)); // assert_eq!(frame.area, Rect::new(0, 0, 8, 8));

@ -648,7 +648,7 @@ impl Document {
.clone() .clone()
// Map through changes // Map through changes
.map(transaction.changes()) .map(transaction.changes())
// Ensure all selections accross all views still adhere to invariants. // Ensure all selections across all views still adhere to invariants.
.ensure_invariants(self.text.slice(..)); .ensure_invariants(self.text.slice(..));
} }
@ -752,7 +752,7 @@ impl Document {
self.undo_redo_impl(view_id, true) self.undo_redo_impl(view_id, true)
} }
/// Redo the last modification to the [`Document`]. Returns whether the redo was sucessful. /// Redo the last modification to the [`Document`]. Returns whether the redo was successful.
pub fn redo(&mut self, view_id: ViewId) -> bool { pub fn redo(&mut self, view_id: ViewId) -> bool {
self.undo_redo_impl(view_id, false) self.undo_redo_impl(view_id, false)
} }

@ -79,7 +79,7 @@ pub struct View {
// uses two docs because we want to be able to swap between the // uses two docs because we want to be able to swap between the
// two last modified docs which we need to manually keep track of // two last modified docs which we need to manually keep track of
pub last_modified_docs: [Option<DocumentId>; 2], pub last_modified_docs: [Option<DocumentId>; 2],
/// used to store previous selections of tree-sitter objecs /// used to store previous selections of tree-sitter objects
pub object_selections: Vec<Selection>, pub object_selections: Vec<Selection>,
pub gutters: Vec<(Gutter, usize)>, pub gutters: Vec<(Gutter, usize)>,
} }

Loading…
Cancel
Save