Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] Layout impact #2

Draft
wants to merge 1 commit into
base: highlight
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> {
}
}

/// Moves the cursor to the same column in the line above
/// Moves the cursor to the same column in the line below
pub fn edit_move_line_down(&mut self, n: RepeatCount) -> Result<bool> {
if self.line.move_to_line_down(n) {
self.move_cursor()?;
Expand Down
74 changes: 72 additions & 2 deletions src/layout.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::cmp::Ordering;

use crate::line_buffer::{ChangeListener, DeleteListener, Direction};

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct Position {
pub col: usize, // The leftmost column is number 0.
Expand All @@ -21,13 +23,81 @@
}
}

/// (byte offset in input buffer <=> Screen cell)
pub type Cell = (usize, Position);

/// All positions are relative to start of the prompt == origin (col: 0, row: 0)
#[derive(Debug, Default)]
pub struct Layout {
/// Prompt Unicode/visible width and height
/// Prompt Unicode/visible width and last row (relative)
pub prompt_size: Position,
pub default_prompt: bool,
/// Cursor position (relative to the start of the prompt)
/// - cursor.row >= prompt_size.row
/// - if cursor.row >= prompt_size.row then cursor.col >=
/// prompt_size.col/width
// FIXME
pub cursor: Position,
/// Number of rows used so far (from start of prompt to end of input)
/// Number of rows used so far (from start of prompt to end
/// of input or hint)
/// - cursor <= end
// FIXME
pub end: Position,
/// Input breaked into sorted cells
// TODO ignore zero-width grapheme (even '\n') ?
pub cells: Vec<Cell>,
}

impl Layout {
/// Find the nearest byte / grapheme offset in input buffer
/// matching `pos`
fn find_byte_by(&self, pos: Position) -> &Cell {
match self.cells.binary_search_by_key(&pos, |cell| cell.1) {
Ok(i) => &self.cells[i],
Err(i) => {
if i < self.cells.len() {
&self.cells[i]
} else {
todo!()
}
}
}
}

/// Find the nearest cell in screen matching `offset`
fn find_position_by(&self, offset: usize) -> &Cell {
match self.cells.binary_search_by_key(&offset, |cell| cell.0) {
Ok(i) => &self.cells[i],
Err(i) => {
if i < self.cells.len() {
&self.cells[i]
} else {
todo!()
}
}
}
}
}

// TODO Update (cursor, end, cells) accordingly
// But we need to remember (old cursor/end row)
impl DeleteListener for Layout {
fn delete(&mut self, idx: usize, string: &str, dir: Direction) {

Check warning on line 85 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `idx`

Check warning on line 85 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `string`

Check warning on line 85 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `dir`
todo!()
}
}
// TODO Update (cursor, end, cells) accordingly
// But we need to remember (old cursor/end row)
impl ChangeListener for Layout {
fn insert_char(&mut self, idx: usize, c: char) {

Check warning on line 92 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `idx`

Check warning on line 92 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `c`
todo!()
}

fn insert_str(&mut self, idx: usize, string: &str) {

Check warning on line 96 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `idx`

Check warning on line 96 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `string`
todo!()
}

fn replace(&mut self, idx: usize, old: &str, new: &str) {

Check warning on line 100 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `idx`

Check warning on line 100 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `old`

Check warning on line 100 in src/layout.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unused variable: `new`
todo!()
}
}
6 changes: 5 additions & 1 deletion src/line_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ impl LineBuffer {
}

/// Moves the cursor to the same column in the line above
// FIXME
pub fn move_to_line_up(&mut self, n: RepeatCount) -> bool {
match self.buf[..self.pos].rfind('\n') {
Some(off) => {
Expand Down Expand Up @@ -610,6 +611,7 @@ impl LineBuffer {
/// N lines up starting from the current one
///
/// Fails if the cursor is on the first line
// FIXME
fn n_lines_up(&self, n: RepeatCount) -> Option<(usize, usize)> {
let mut start = if let Some(off) = self.buf[..self.pos].rfind('\n') {
off + 1
Expand All @@ -633,6 +635,7 @@ impl LineBuffer {
/// N lines down starting from the current one
///
/// Fails if the cursor is on the last line
// FIXME
fn n_lines_down(&self, n: RepeatCount) -> Option<(usize, usize)> {
let mut end = if let Some(off) = self.buf[self.pos..].find('\n') {
self.pos + off + 1
Expand All @@ -651,7 +654,8 @@ impl LineBuffer {
Some((start, end))
}

/// Moves the cursor to the same column in the line above
/// Moves the cursor to the same column in the line below
// FIXME
pub fn move_to_line_down(&mut self, n: RepeatCount) -> bool {
match self.buf[self.pos..].find('\n') {
Some(off) => {
Expand Down
4 changes: 4 additions & 0 deletions src/tty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ pub trait Renderer {
/// Compute layout for rendering prompt + line + some info (either hint,
/// validation msg, ...). on the screen. Depending on screen width, line
/// wrapping may be applied.
// FIXME
fn compute_layout(
&self,
prompt_size: Position,
default_prompt: bool,
line: &LineBuffer,
info: Option<&str>,
) -> Layout {
let mut cells = Vec::with_capacity(line.len());
// calculate the desired position of the cursor
let pos = line.pos();
let cursor = self.calculate_position(&line[..pos], prompt_size);
Expand All @@ -85,6 +87,7 @@ pub trait Renderer {
default_prompt,
cursor,
end,
cells,
};
debug_assert!(new_layout.prompt_size <= new_layout.cursor);
debug_assert!(new_layout.cursor <= new_layout.end);
Expand All @@ -93,6 +96,7 @@ pub trait Renderer {

/// Calculate the number of columns and rows used to display `s` on a
/// `cols` width terminal starting at `orig`.
// FIXME
fn calculate_position(&self, s: &str, orig: Position) -> Position;

fn write_and_flush(&mut self, buf: &str) -> Result<()>;
Expand Down
1 change: 1 addition & 0 deletions src/tty/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ fn get_win_size(fd: RawFd) -> (usize, usize) {
} else {
size.ws_row as usize
};
debug!(target: "rustyline", "winsize: cols: {}, rows: {}", cols, rows);
(cols, rows)
}
_ => (80, 24),
Expand Down
Loading