Fix cursor positioning.
This commit is contained in:
parent
8695415fbf
commit
ef0d062b1f
@ -9,7 +9,6 @@
|
||||
use log::{debug, info};
|
||||
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
io::{self, stdout, Stdout, Write},
|
||||
path::PathBuf,
|
||||
time::Duration,
|
||||
@ -47,31 +46,9 @@ pub struct Application {
|
||||
// TODO: temp
|
||||
#[inline(always)]
|
||||
pub fn text_color() -> Style {
|
||||
return Style::default().fg(Color::Rgb(219, 191, 239)); // lilac
|
||||
Style::default().fg(Color::Rgb(219, 191, 239)) // lilac
|
||||
}
|
||||
|
||||
// pub fn render_cursor(&mut self, view: &View, prompt: Option<&Prompt>, viewport: Rect) {
|
||||
// let mut stdout = stdout();
|
||||
// match view.doc.mode() {
|
||||
// Mode::Insert => write!(stdout, "\x1B[6 q"),
|
||||
// mode => write!(stdout, "\x1B[2 q"),
|
||||
// };
|
||||
// let pos = if let Some(prompt) = prompt {
|
||||
// Position::new(self.size.0 as usize, 2 + prompt.cursor)
|
||||
// } else {
|
||||
// let cursor = view.doc.state.selection().cursor();
|
||||
|
||||
// let mut pos = view
|
||||
// .screen_coords_at_pos(&view.doc.text().slice(..), cursor)
|
||||
// .expect("Cursor is out of bounds.");
|
||||
// pos.col += viewport.x as usize;
|
||||
// pos.row += viewport.y as usize;
|
||||
// pos
|
||||
// };
|
||||
|
||||
// execute!(stdout, cursor::MoveTo(pos.col as u16, pos.row as u16));
|
||||
// }
|
||||
|
||||
impl Application {
|
||||
pub fn new(mut args: Args, executor: &'static smol::Executor<'static>) -> Result<Self, Error> {
|
||||
let backend = CrosstermBackend::new(stdout());
|
||||
@ -106,13 +83,14 @@ fn render(&mut self) {
|
||||
let editor = &mut self.editor;
|
||||
let compositor = &self.compositor;
|
||||
|
||||
// TODO: should be unnecessary
|
||||
// self.terminal.autoresize();
|
||||
let mut cx = crate::compositor::Context { editor, executor };
|
||||
let area = self.terminal.size().unwrap();
|
||||
|
||||
compositor.render(area, self.terminal.current_buffer_mut(), &mut cx);
|
||||
let pos = compositor.cursor_position(area, &mut cx);
|
||||
|
||||
self.terminal.draw();
|
||||
self.terminal.set_cursor(pos.col as u16, pos.row as u16);
|
||||
}
|
||||
|
||||
pub async fn event_loop(&mut self) {
|
||||
|
@ -1,20 +0,0 @@
|
||||
// IDEA: render to a cache buffer, then if not changed, copy the buf into the parent
|
||||
type Surface = ();
|
||||
pub trait Component {
|
||||
/// Process input events, return true if handled.
|
||||
fn process_event(&mut self, event: crossterm::event::Event, args: ()) -> bool;
|
||||
/// Should redraw? Useful for saving redraw cycles if we know component didn't change.
|
||||
fn should_update(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn render(&mut self, surface: &mut Surface, args: ());
|
||||
}
|
||||
|
||||
// HStack / VStack
|
||||
// focus by component id: each View/Editor gets it's own incremental id at create
|
||||
// Component: View(Arc<State>) -> multiple views can point to same state
|
||||
// id 0 = prompt?
|
||||
// when entering to prompt, it needs to direct Commands to last focus window
|
||||
// -> prompt.trigger(focus_id), on_leave -> focus(focus_id)
|
||||
// popups on another layer
|
@ -14,6 +14,7 @@
|
||||
// cursive does compositor.screen_mut().add_layer_at(pos::absolute(x, y), <component>)
|
||||
|
||||
use crossterm::event::Event;
|
||||
use helix_core::Position;
|
||||
use smol::Executor;
|
||||
use tui::buffer::Buffer as Surface;
|
||||
use tui::layout::Rect;
|
||||
@ -52,6 +53,10 @@ fn should_update(&self) -> bool {
|
||||
}
|
||||
|
||||
fn render(&self, area: Rect, frame: &mut Surface, ctx: &mut Context);
|
||||
|
||||
fn cursor_position(&self, area: Rect, ctx: &mut Context) -> Option<Position> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// struct Editor { };
|
||||
@ -138,4 +143,13 @@ pub fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) {
|
||||
layer.render(area, surface, cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_position(&self, area: Rect, cx: &mut Context) -> Position {
|
||||
for layer in self.layers.iter().rev() {
|
||||
if let Some(pos) = layer.cursor_position(area, cx) {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
panic!("No layer returned a position!");
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ pub struct EditorView {
|
||||
keymap: Keymaps,
|
||||
}
|
||||
|
||||
const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
|
||||
|
||||
impl EditorView {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@ -34,11 +36,10 @@ pub fn render_view(
|
||||
surface: &mut Surface,
|
||||
theme: &Theme,
|
||||
) {
|
||||
const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
|
||||
let area = Rect::new(OFFSET, 0, viewport.width - OFFSET, viewport.height - 2); // - 2 for statusline and prompt
|
||||
self.render_buffer(view, area, surface, theme);
|
||||
let area = Rect::new(0, viewport.height - 2, viewport.width, 1);
|
||||
self.render_statusline(view, viewport, surface, theme);
|
||||
self.render_statusline(view, area, surface, theme);
|
||||
}
|
||||
|
||||
// TODO: ideally not &mut View but highlights require it because of cursor cache
|
||||
@ -218,7 +219,7 @@ pub fn render_statusline(
|
||||
};
|
||||
// statusline
|
||||
surface.set_style(
|
||||
Rect::new(0, viewport.y, viewport.height, 1),
|
||||
Rect::new(0, viewport.y, viewport.width, 1),
|
||||
theme.get("ui.statusline"),
|
||||
);
|
||||
surface.set_string(1, viewport.y, mode, text_color());
|
||||
@ -306,6 +307,21 @@ fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) {
|
||||
}
|
||||
|
||||
// TODO: drop unwrap
|
||||
// TODO: !!! self.render_cursor(cx.editor.view().unwrap(), None, viewport);
|
||||
}
|
||||
|
||||
fn cursor_position(&self, area: Rect, ctx: &mut Context) -> Option<Position> {
|
||||
// match view.doc.mode() {
|
||||
// Mode::Insert => write!(stdout, "\x1B[6 q"),
|
||||
// mode => write!(stdout, "\x1B[2 q"),
|
||||
// };
|
||||
let view = ctx.editor.view().unwrap();
|
||||
let cursor = view.doc.state.selection().cursor();
|
||||
|
||||
let mut pos = view
|
||||
.screen_coords_at_pos(&view.doc.text().slice(..), cursor)
|
||||
.expect("Cursor is out of bounds.");
|
||||
pos.col += area.x as usize + OFFSET as usize;
|
||||
pos.row += area.y as usize;
|
||||
Some(pos)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::compositor::{Component, Context, EventResult};
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
|
||||
use helix_core::Position;
|
||||
use helix_view::Editor;
|
||||
use helix_view::Theme;
|
||||
use std::string::String;
|
||||
@ -200,4 +201,11 @@ fn handle_event(&mut self, event: Event, cx: &mut Context) -> EventResult {
|
||||
fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) {
|
||||
self.render_prompt(area, surface, &cx.editor.theme)
|
||||
}
|
||||
|
||||
fn cursor_position(&self, area: Rect, ctx: &mut Context) -> Option<Position> {
|
||||
Some(Position::new(
|
||||
area.height as usize - 1,
|
||||
area.x as usize + 2 + self.cursor,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user