Skip to content
Merged
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
7 changes: 7 additions & 0 deletions src/bin/edit/documents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ impl DocumentManager {
Ok(self.list.front_mut().unwrap())
}

pub fn reflow_all(&self) {
for doc in &self.list {
let mut tb = doc.buffer.borrow_mut();
tb.reflow();
}
}

pub fn open_for_reading(path: &Path) -> apperr::Result<File> {
File::open(path).map_err(apperr::Error::from)
}
Expand Down
27 changes: 22 additions & 5 deletions src/bin/edit/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ use draw_menubar::*;
use draw_statusbar::*;
use edit::arena::{self, Arena, ArenaString, scratch_arena};
use edit::framebuffer::{self, IndexedColor};
use edit::helpers::{KIBI, MEBI, MetricFormatter, Rect, Size};
use edit::helpers::{CoordType, KIBI, MEBI, MetricFormatter, Rect, Size};
use edit::input::{self, kbmod, vk};
use edit::oklab::oklab_blend;
use edit::tui::*;
use edit::vt::{self, Token};
use edit::{apperr, arena_format, base64, path, sys};
use edit::{apperr, arena_format, base64, path, sys, unicode};
use localization::*;
use state::*;

Expand Down Expand Up @@ -85,7 +85,7 @@ fn run() -> apperr::Result<()> {
let mut input_parser = input::Parser::new();
let mut tui = Tui::new()?;

let _restore = setup_terminal(&mut tui, &mut vt_parser);
let _restore = setup_terminal(&mut tui, &mut state, &mut vt_parser);

state.menubar_color_bg = oklab_blend(
tui.indexed(IndexedColor::Background),
Expand Down Expand Up @@ -509,7 +509,7 @@ impl Drop for RestoreModes {
}
}

fn setup_terminal(tui: &mut Tui, vt_parser: &mut vt::Parser) -> RestoreModes {
fn setup_terminal(tui: &mut Tui, state: &mut State, vt_parser: &mut vt::Parser) -> RestoreModes {
sys::write_stdout(concat!(
// 1049: Alternative Screen Buffer
// I put the ASB switch in the beginning, just in case the terminal performs
Expand All @@ -524,6 +524,12 @@ fn setup_terminal(tui: &mut Tui, vt_parser: &mut vt::Parser) -> RestoreModes {
"\x1b]4;8;?;9;?;10;?;11;?;12;?;13;?;14;?;15;?\x07",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I SEE THOSE BELs

// OSC 10 and 11 queries for the current foreground and background colors.
"\x1b]10;?\x07\x1b]11;?\x07",
// Test whether ambiguous width characters are two columns wide.
// We use "…", because it's the most common ambiguous width character we use,
// and the old Windows conhost doesn't actually use wcwidth, it measures the
// actual display width of the character and assigns it columns accordingly.
// We detect it by writing the character and asking for the cursor position.
"\r…\x1b[6n",
// CSI c reports the terminal capabilities.
// It also helps us to detect the end of the responses, because not all
// terminals support the OSC queries, but all of them support CSI c.
Expand All @@ -534,6 +540,7 @@ fn setup_terminal(tui: &mut Tui, vt_parser: &mut vt::Parser) -> RestoreModes {
let mut osc_buffer = String::new();
let mut indexed_colors = framebuffer::DEFAULT_THEME;
let mut color_responses = 0;
let mut ambiguous_width = 1;

while !done {
let scratch = scratch_arena(None);
Expand All @@ -544,7 +551,12 @@ fn setup_terminal(tui: &mut Tui, vt_parser: &mut vt::Parser) -> RestoreModes {
let mut vt_stream = vt_parser.parse(&input);
while let Some(token) = vt_stream.next() {
match token {
Token::Csi(state) if state.final_byte == 'c' => done = true,
Token::Csi(csi) => match csi.final_byte {
'c' => done = true,
// CPR (Cursor Position Report) response.
'R' => ambiguous_width = csi.params[1] as CoordType - 1,
_ => {}
},
Token::Osc { mut data, partial } => {
if partial {
osc_buffer.push_str(data);
Expand Down Expand Up @@ -601,6 +613,11 @@ fn setup_terminal(tui: &mut Tui, vt_parser: &mut vt::Parser) -> RestoreModes {
}
}

if ambiguous_width == 2 {
unicode::setup_ambiguous_width(2);
state.documents.reflow_all();
}

if color_responses == indexed_colors.len() {
tui.setup_indexed_colors(indexed_colors);
}
Expand Down
48 changes: 23 additions & 25 deletions src/buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ impl TextBuffer {
false
} else {
self.margin_enabled = enabled;
self.reflow(true);
self.reflow();
true
}
}
Expand Down Expand Up @@ -477,7 +477,7 @@ impl TextBuffer {
false
} else {
self.width = width;
self.reflow(true);
self.reflow();
true
}
}
Expand All @@ -494,7 +494,7 @@ impl TextBuffer {
false
} else {
self.tab_size = width;
self.reflow(true);
self.reflow();
true
}
}
Expand All @@ -519,7 +519,7 @@ impl TextBuffer {
self.ruler = column;
}

fn reflow(&mut self, force: bool) {
pub fn reflow(&mut self) {
// +1 onto logical_lines, because line numbers are 1-based.
// +1 onto log10, because we want the digit width and not the actual log10.
// +3 onto log10, because we append " | " to the line numbers to form the margin.
Expand All @@ -531,24 +531,25 @@ impl TextBuffer {

let text_width = self.text_width();
// 2 columns are required, because otherwise wide glyphs wouldn't ever fit.
let word_wrap_column =
self.word_wrap_column =
if self.word_wrap_enabled && text_width >= 2 { text_width } else { 0 };

if force || self.word_wrap_column > word_wrap_column {
self.word_wrap_column = word_wrap_column;

if self.cursor.offset != 0 {
self.cursor = self
.cursor_move_to_logical_internal(Default::default(), self.cursor.logical_pos);
}

// Recalculate the line statistics.
if self.word_wrap_enabled {
let end = self.cursor_move_to_logical_internal(self.cursor, Point::MAX);
self.stats.visual_lines = end.visual_pos.y + 1;
// Recalculate the cursor position.
self.cursor = self.cursor_move_to_logical_internal(
if self.word_wrap_column > 0 {
Default::default()
} else {
self.stats.visual_lines = self.stats.logical_lines;
}
self.goto_line_start(self.cursor, self.cursor.logical_pos.y)
},
self.cursor.logical_pos,
);

// Recalculate the line statistics.
if self.word_wrap_column > 0 {
let end = self.cursor_move_to_logical_internal(self.cursor, Point::MAX);
self.stats.visual_lines = end.visual_pos.y + 1;
} else {
self.stats.visual_lines = self.stats.logical_lines;
}

self.cursor_for_rendering = None;
Expand Down Expand Up @@ -578,7 +579,7 @@ impl TextBuffer {
self.set_selection(None);
self.search = None;
self.mark_as_clean();
self.reflow(true);
self.reflow();
}

/// Copies the contents of the buffer into a string.
Expand Down Expand Up @@ -2280,9 +2281,7 @@ impl TextBuffer {
}

self.search = None;

// Also takes care of clearing `cursor_for_rendering`.
self.reflow(false);
self.cursor_for_rendering = None;
}

/// Undo the last edit operation.
Expand Down Expand Up @@ -2396,8 +2395,7 @@ impl TextBuffer {
}
}

// Also takes care of clearing `cursor_for_rendering`.
self.reflow(false);
self.cursor_for_rendering = None;
}

/// For interfacing with ICU.
Expand Down
Loading