diff --git a/TODO.md b/TODO.md index 5918601..73da96b 100644 --- a/TODO.md +++ b/TODO.md @@ -8,6 +8,8 @@ - [x] diff view: add character-wise change highlight (enabled by default). - [x] add tabs: tab support, editor action to open a buffer in a new tab, default tab navigation is `ctrl+option+h/l`, close tab action. - per-tab pane layouts, views, explorers, and comparisons; shared buffers, tab bar, and guarded close/force-close actions. +- [ ] make diff selector close on escape. +- [ ] `:` currently overrides the diff selector input (and maybe other input fields) and spawns the command input on top. this is of course not intended behavior and should be fixed. - [ ] diff view: lsp actions should act as they normally would. if an lsp action would open another file, then the file should be opened in another tab outside the diff view - if the referenced file/symbol is part of the changes in the diff, it should just be opened in the diff view. - this will require tab support. - [ ] diff view: change diff view modes; choose between split and unified diff view (split by default). diff --git a/docs/editing.md b/docs/editing.md index 58e5bc0..301d257 100644 --- a/docs/editing.md +++ b/docs/editing.md @@ -142,9 +142,9 @@ Submitting an empty search repeats the last query. Esc cancels without moving th ## Commands, saving, and pasted input -`:` opens compact floating command input; `/` opens the same kind of input for buffer text search. Enter submits and Escape cancels using the existing modal rules. Long Unicode input scrolls horizontally without changing buffer text. Input is bounded by the workspace, above configured bars, and temporarily hides operation notifications; there is no permanent prompt/footer row. +`:` opens compact floating command input titled **Command**; `/` opens input titled **Search** for buffer text search. Titles sit at the top-left border, replacing the displayed leading `:` / `/`. Both input fields have one column of padding on each side. Enter submits and Escape cancels using the existing modal rules. Long Unicode input scrolls horizontally without changing buffer text. Input is bounded by the workspace, above configured bars, and temporarily hides operation notifications; there is no permanent prompt/footer row. Tiny windows omit borders/titles or padding when needed to keep input usable. -The latest reported operation result appears in a non-focusable popup at the workspace's bottom-right, just above the bottom bar when visible. It remains until dismissed or replaced, with no timer. In Normal mode, the first Escape dismisses it without collapsing carets; a subsequent Escape retains ordinary Normal behavior. Existing modal windows, focused explorers/diff selectors, and pending prefixes retain Escape priority. New operation messages reopen the popup; routine successful buffer switches do not duplicate the buffer/path information already shown in the bar. +The latest reported operation result appears in a non-focusable popup at the workspace's bottom-right, just above the bottom bar when visible, with one column of inner padding on each side when space permits. It remains until dismissed or replaced, with no timer. In Normal mode, the first Escape dismisses it without collapsing carets; a subsequent Escape retains ordinary Normal behavior. Existing modal windows, focused explorers/diff selectors, and pending prefixes retain Escape priority. New operation messages reopen the popup; routine successful buffer switches do not duplicate the buffer/path information already shown in the bar. Command-capable core actions derive canonical Ex names by removing `core.`: `core.quit` gives `:quit`, `core.save` gives `:save`, and `core.diff.close` gives `:diff.close`. Native editing and Insert-only completion/snippet actions remain action bindings, not additional Ex commands. diff --git a/src/tui.rs b/src/tui.rs index 173e166..07bee53 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -1848,27 +1848,31 @@ fn draw_floating_input(frame: &mut Frame, editor: &Editor, area: Rect) -> Option height, ); let bordered = panel.width >= 4 && panel.height >= 3; - let block = Block::default() + let padding = u16::from(panel.width.saturating_sub(2 * u16::from(bordered)) >= 3); + let mut block = Block::default() .borders(if bordered { Borders::ALL } else { Borders::NONE }) - .border_style(Style::default().fg(Color::Cyan)); + .border_style(Style::default().fg(Color::Cyan)) + .padding(ratatui::widgets::Padding::horizontal(padding)); + if bordered { + block = block.title(if editor.mode() == Mode::Search { + " Search " + } else { + " Command " + }); + } let content = block.inner(panel); frame.render_widget(Clear, panel); frame.render_widget(block, panel); - let prefix = if editor.mode() == Mode::Search { - '/' - } else { - ':' - }; - let command = format!("{prefix}{}", editor.command_line()); - let column = display_column(&command, usize::MAX); + let command = editor.command_line(); + let column = display_column(command, usize::MAX); let width = usize::from(content.width); let offset = column.saturating_sub(width.saturating_sub(1)); frame.render_widget( - Paragraph::new(visible_line(&command, offset, width)), + Paragraph::new(visible_line(command, offset, width)), content, ); frame.set_cursor_position((content.x + (column - offset) as u16, content.y)); @@ -1898,13 +1902,19 @@ fn draw_notification(frame: &mut Frame, editor: &Editor, area: Rect) -> Option= 3 { + 4 + } else { + 2 + })) + .min(60) + .min(usize::from(area.width)) as u16; let bordered = width >= 4 && area.height >= 3; let border = 2 * u16::from(bordered); + let padding = u16::from(width.saturating_sub(border) >= 3); let paragraph = Paragraph::new(message).wrap(Wrap { trim: false }); - let height = (paragraph.line_count(width - border).min(6) as u16 + border).min(area.height); + let height = (paragraph.line_count(width - border - 2 * padding).min(6) as u16 + border) + .min(area.height); let panel = Rect::new(area.right() - width, area.bottom() - height, width, height); let block = Block::default() .borders(if bordered { @@ -1912,7 +1922,8 @@ fn draw_notification(frame: &mut Frame, editor: &Editor, area: Rect) -> Option