Added zoom mode & max width

pull/9838/head
Elizabeth 8 months ago
parent 00e9e5eade
commit ca55729159
No known key found for this signature in database
GPG Key ID: CA216582906ECF8E

@ -76,7 +76,7 @@ The `[editor.statusline]` key takes the following sub-keys:
| Key | Description | Default | | Key | Description | Default |
| --- | --- | --- | | --- | --- | --- |
| `left` | A list of elements aligned to the left of the statusline | `["mode", "spinner", "file-name", "read-only-indicator", "file-modification-indicator"]` | | `left` | A list of elements aligned to the left of the statusline | `["mode", "spinner", "file-name", "read-only-indicator", "zoom", "file-modification-indicator"]` |
| `center` | A list of elements aligned to the middle of the statusline | `[]` | | `center` | A list of elements aligned to the middle of the statusline | `[]` |
| `right` | A list of elements aligned to the right of the statusline | `["diagnostics", "selections", "register", "position", "file-encoding"]` | | `right` | A list of elements aligned to the right of the statusline | `["diagnostics", "selections", "register", "position", "file-encoding"]` |
| `separator` | The character used to separate elements in the statusline | `"│"` | | `separator` | The character used to separate elements in the statusline | `"│"` |
@ -109,6 +109,7 @@ The following statusline elements can be configured:
| `spacer` | Inserts a space between elements (multiple/contiguous spacers may be specified) | | `spacer` | Inserts a space between elements (multiple/contiguous spacers may be specified) |
| `version-control` | The current branch name or detached commit hash of the opened workspace | | `version-control` | The current branch name or detached commit hash of the opened workspace |
| `register` | The current selected register | | `register` | The current selected register |
| `zoom` | The current window zoom/zen state |
### `[editor.lsp]` Section ### `[editor.lsp]` Section

@ -88,3 +88,4 @@
| `:move` | Move the current buffer and its corresponding file to a different path | | `:move` | Move the current buffer and its corresponding file to a different path |
| `:yank-diagnostic` | Yank diagnostic(s) under primary cursor to register, or clipboard by default | | `:yank-diagnostic` | Yank diagnostic(s) under primary cursor to register, or clipboard by default |
| `:read`, `:r` | Load a file into buffer | | `:read`, `:r` | Load a file into buffer |
| `:set-max-width` | Set the maximum width of the editor. If set to 0 it will take up the entire width. |

@ -270,6 +270,7 @@ This layer is similar to Vim keybindings as Kakoune does not support windows.
| `J` | Swap window downwards | `swap_view_down` | | `J` | Swap window downwards | `swap_view_down` |
| `K` | Swap window upwards | `swap_view_up` | | `K` | Swap window upwards | `swap_view_up` |
| `L` | Swap window to the right | `swap_view_right` | | `L` | Swap window to the right | `swap_view_right` |
| `z` | Toggle zoom for the focused view | `toggle_zoom` |
#### Space mode #### Space mode

@ -46,6 +46,10 @@ k = "scroll_down"
m = ":run-shell-command make" m = ":run-shell-command make"
c = ":run-shell-command cargo build" c = ":run-shell-command cargo build"
t = ":run-shell-command cargo test" t = ":run-shell-command cargo test"
# Creates a basic 'zen-mode' similar to VSCode's
z = ["toggle_zoom", ":set-max-width 120", ":set gutters.layout []"]
Z = ["toggle_zoom", ":set-max-width 0", ':set gutters.layout ["diagnostics","spacer","line-numbers","spacer","diff"]']
``` ```
## Special keys and modifiers ## Special keys and modifiers

@ -462,6 +462,7 @@ impl MappableCommand {
vsplit_new, "Vertical right split scratch buffer", vsplit_new, "Vertical right split scratch buffer",
wclose, "Close window", wclose, "Close window",
wonly, "Close windows except current", wonly, "Close windows except current",
toggle_zoom, "Toggle zoom for current window",
select_register, "Select register", select_register, "Select register",
insert_register, "Insert register", insert_register, "Insert register",
align_view_middle, "Align view middle", align_view_middle, "Align view middle",
@ -5187,6 +5188,11 @@ fn wonly(cx: &mut Context) {
} }
} }
fn toggle_zoom(cx: &mut Context) {
cx.editor.tree.zoom = !cx.editor.tree.zoom;
cx.editor.tree.recalculate();
}
fn select_register(cx: &mut Context) { fn select_register(cx: &mut Context) {
cx.editor.autoinfo = Some(Info::from_registers(&cx.editor.registers)); cx.editor.autoinfo = Some(Info::from_registers(&cx.editor.registers));
cx.on_next_key(move |cx, event| { cx.on_next_key(move |cx, event| {

@ -2488,6 +2488,30 @@ fn read(cx: &mut compositor::Context, args: &[Cow<str>], event: PromptEvent) ->
Ok(()) Ok(())
} }
fn set_max_width(
cx: &mut compositor::Context,
args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
let Some(width) = args.first() else { bail!(":set-max-width takes one argument") };
let width = width.parse()?;
cx.editor.tree.max_width = width;
cx.editor.tree.recalculate();
if width == 0 {
cx.editor.set_status("Unset maximum width");
} else {
cx.editor
.set_status(format!("Set maximum width to {}", width));
}
Ok(())
}
pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
TypableCommand { TypableCommand {
name: "quit", name: "quit",
@ -3109,6 +3133,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
fun: read, fun: read,
signature: CommandSignature::positional(&[completers::filename]), signature: CommandSignature::positional(&[completers::filename]),
}, },
TypableCommand {
name: "set-max-width",
aliases: &[],
doc: "Set the maximum width of the editor. If set to 0 it will take up the entire width.",
fun: set_max_width,
signature: CommandSignature::positional(&[completers::none]),
},
]; ];
pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> = pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =

@ -207,6 +207,7 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"C-s" | "s" => hsplit_new, "C-s" | "s" => hsplit_new,
"C-v" | "v" => vsplit_new, "C-v" | "v" => vsplit_new,
}, },
"z" => toggle_zoom,
}, },
// move under <space>c // move under <space>c
@ -272,6 +273,7 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"C-s" | "s" => hsplit_new, "C-s" | "s" => hsplit_new,
"C-v" | "v" => vsplit_new, "C-v" | "v" => vsplit_new,
}, },
"z" => toggle_zoom,
}, },
"y" => yank_to_clipboard, "y" => yank_to_clipboard,
"Y" => yank_main_selection_to_clipboard, "Y" => yank_main_selection_to_clipboard,

@ -206,8 +206,8 @@ impl EditorView {
); );
Self::render_rulers(editor, doc, view, inner, surface, theme); Self::render_rulers(editor, doc, view, inner, surface, theme);
// if we're not at the edge of the screen, draw a right border // if we're not at the edge of the screen or zoomed, draw a right border
if viewport.right() != view.area.right() { if viewport.right() != view.area.right() && !editor.tree.zoom {
let x = area.right(); let x = area.right();
let border_style = theme.get("ui.window"); let border_style = theme.get("ui.window");
for y in area.top()..area.bottom() { for y in area.top()..area.bottom() {
@ -1489,9 +1489,11 @@ impl Component for EditorView {
} }
for (view, is_focused) in cx.editor.tree.views() { for (view, is_focused) in cx.editor.tree.views() {
if !cx.editor.tree.zoom || is_focused {
let doc = cx.editor.document(view.doc).unwrap(); let doc = cx.editor.document(view.doc).unwrap();
self.render_view(cx.editor, doc, view, area, surface, is_focused); self.render_view(cx.editor, doc, view, area, surface, is_focused);
} }
}
if config.auto_info { if config.auto_info {
if let Some(mut info) = cx.editor.autoinfo.take() { if let Some(mut info) = cx.editor.autoinfo.take() {

@ -163,6 +163,7 @@ where
helix_view::editor::StatusLineElement::Spacer => render_spacer, helix_view::editor::StatusLineElement::Spacer => render_spacer,
helix_view::editor::StatusLineElement::VersionControl => render_version_control, helix_view::editor::StatusLineElement::VersionControl => render_version_control,
helix_view::editor::StatusLineElement::Register => render_register, helix_view::editor::StatusLineElement::Register => render_register,
helix_view::editor::StatusLineElement::Zoom => render_zoom,
} }
} }
@ -531,3 +532,11 @@ where
write(context, format!(" reg={} ", reg), None) write(context, format!(" reg={} ", reg), None)
} }
} }
fn render_zoom<'a>(context: &RenderContext) -> Spans<'a> {
if context.editor.tree.zoom {
"[zoom]".into()
} else {
Spans::default()
}
}

@ -469,6 +469,7 @@ impl Default for StatusLineConfig {
E::Spinner, E::Spinner,
E::FileName, E::FileName,
E::ReadOnlyIndicator, E::ReadOnlyIndicator,
E::Zoom,
E::FileModificationIndicator, E::FileModificationIndicator,
], ],
center: vec![], center: vec![],
@ -568,6 +569,9 @@ pub enum StatusLineElement {
/// Indicator for selected register /// Indicator for selected register
Register, Register,
/// Current zoom/zen state
Zoom,
} }
// Cursor shape is read and used on every rendered frame and so needs // Cursor shape is read and used on every rendered frame and so needs

@ -8,8 +8,13 @@ pub struct Tree {
root: ViewId, root: ViewId,
// (container, index inside the container) // (container, index inside the container)
pub focus: ViewId, pub focus: ViewId,
// fullscreen: bool,
area: Rect, area: Rect,
// Maximum width the views will take up. If 0 then they will take up the
// entire width regardless of state.
pub max_width: u16,
// If true, the focused view gets all the available space and the rest are
// not rendered.
pub zoom: bool,
nodes: HopSlotMap<ViewId, Node>, nodes: HopSlotMap<ViewId, Node>,
@ -96,8 +101,9 @@ impl Tree {
Self { Self {
root, root,
focus: root, focus: root,
// fullscreen: false,
area, area,
max_width: 0,
zoom: false,
nodes, nodes,
stack: Vec::new(), stack: Vec::new(),
} }
@ -360,7 +366,27 @@ impl Tree {
return; return;
} }
self.stack.push((self.root, self.area)); let area = if self.max_width > 0 {
let width = std::cmp::min(self.max_width, self.area.width);
Rect::new(
self.area.width / 2 - width / 2,
self.area.y,
width,
self.area.height,
)
} else {
self.area
};
if self.zoom {
for (view, _focused) in self.views_mut() {
view.area = area;
}
return;
}
self.stack.push((self.root, area));
// take the area // take the area
// fetch the node // fetch the node

Loading…
Cancel
Save