Another ugly progress commit

This commit is contained in:
Timothy Warren 2019-09-06 16:40:31 -04:00
parent e6d3995e4c
commit e720de0eb8
5 changed files with 51 additions and 30 deletions

1
Cargo.lock generated
View File

@ -43,7 +43,6 @@ version = "0.1.0"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@ -9,6 +9,5 @@ edition = "2018"
[dependencies]
bitflags = "1.1.0"
lazy_static = "1.4.0"
libc = "0.2"
# Rust wrappers for C/POSIX headers
nix = "0.15.0"

View File

@ -435,9 +435,11 @@ impl Editor {
None
};
let row = &mut rows[index];
let render_len = row.render.len();
// Reset the highlighting of the row
row.highlight = vec![Highlight::Normal; row.render.len()];
row.highlight = vec![Highlight::Normal; render_len];
if self.syntax.is_none() {
return;
@ -462,7 +464,7 @@ impl Editor {
let mut i = 0;
let bytes = row.render.clone().into_bytes();
'outer: while i < row.render.len() {
while i < render_len {
let c = bytes[i] as char;
let prev_highlight = if i > 0 {
row.highlight[i - 1]
@ -472,12 +474,12 @@ impl Editor {
// Single line comments
if scs.len() > 0 && !in_string && !in_comment {
let range = get_slice_range(i as usize, scs.len(), row.render.len());
let range = get_slice_range(i, scs.len(), render_len);
if &row.render[range] == scs {
// Pretty simple, highlight from the match to the end of the line
highlight_range(
&mut row.highlight,
i as usize..row.render.len(),
i..render_len,
Highlight::LineComment,
);
break;
@ -486,16 +488,16 @@ impl Editor {
// Multi-line comments
if mcs.len() > 0 && mce.len() > 0 && !in_string {
let mce_slice_range = get_slice_range(i as usize, mce.len(), row.render.len());
let mcs_slice_range = get_slice_range(i as usize, mcs.len(), row.render.len());
let mce_range = get_slice_range(i, mce.len(), render_len);
let mcs_range = get_slice_range(i, mcs.len(), render_len);
if in_comment {
row.highlight[i as usize] = Highlight::MultiLineComment;
row.highlight[i] = Highlight::MultiLineComment;
// End of a comment
if &row.render[mce_slice_range.clone()] == mce {
if &row.render[mce_range.clone()] == mce {
highlight_range(
&mut row.highlight,
mce_slice_range,
mce_range,
Highlight::MultiLineComment,
);
@ -507,11 +509,11 @@ impl Editor {
i += 1;
continue;
}
} else if &row.render[mcs_slice_range.clone()] == mcs {
} else if &row.render[mcs_range.clone()] == mcs {
// Start of a multi-line comment
highlight_range(
&mut row.highlight,
mcs_slice_range,
mcs_range,
Highlight::MultiLineComment,
);
@ -527,10 +529,10 @@ impl Editor {
.contains(SyntaxFlags::HIGHLIGHT_STRINGS)
{
if in_string {
row.highlight[i as usize] = Highlight::String;
row.highlight[i] = Highlight::String;
// Don't end highlighting for a string on an escaped quote
if c == '\\' && i + 1 < row.render.len() {
row.highlight[i as usize + 1] = Highlight::String;
if c == '\\' && i + 1 < render_len {
row.highlight[i + 1] = Highlight::String;
i += 2;
continue;
}
@ -547,7 +549,7 @@ impl Editor {
if (c == '"' || c == '\'') && prev_separator {
in_string = true;
str_start = c;
row.highlight[i as usize] = Highlight::String;
row.highlight[i] = Highlight::String;
i += 1;
continue;
}
@ -562,7 +564,7 @@ impl Editor {
if (c.is_ascii_digit() && (prev_separator || prev_highlight == Highlight::Number))
|| (c == '.' && prev_highlight == Highlight::Number)
{
row.highlight[i as usize] = Highlight::Number;
row.highlight[i] = Highlight::Number;
i += 1;
prev_separator = false;
continue;
@ -572,10 +574,14 @@ impl Editor {
// Keywords
if prev_separator {
for &keyword in keywords1 {
let search_range = get_slice_range(i as usize, keyword.len(), row.render.len());
if i + keyword.len() >= render_len {
continue;
}
let next_char_offset = i as usize + keyword.len() + 1;
let is_end_of_line = next_char_offset >= row.render.len();
let search_range = get_slice_range(i, keyword.len(), render_len);
let next_char_offset = i + keyword.len() + 1;
let is_end_of_line = next_char_offset >= render_len;
let next_char = if is_end_of_line {
'\0'
} else {
@ -589,10 +595,14 @@ impl Editor {
}
for &keyword in keywords2 {
let search_range = get_slice_range(i as usize, keyword.len(), row.render.len());
if i + keyword.len() >= render_len {
continue;
}
let next_char_offset = i as usize + keyword.len() + 1;
let is_end_of_line = next_char_offset >= row.render.len();
let search_range = get_slice_range(i, keyword.len(), render_len);
let next_char_offset = i + keyword.len() + 1;
let is_end_of_line = next_char_offset >= render_len;
let next_char = if is_end_of_line {
'\0'
} else {
@ -1579,8 +1589,9 @@ where
match res {
Ok(value) => value,
Err(e) => {
print!("\x1b[2J");
print!("\x1b[H");
disable_raw_mode();
println!("\r\n");
panic!("{:?}", e);
}
}
@ -1603,7 +1614,19 @@ mod tests {
#[test]
fn is_separator_works() {
assert_eq!(is_separator(' '), true);
assert_eq!(is_separator('_'), false);
// Check each explicit character
for ch in ",.()+-/*=~%<>[];".chars() {
assert_eq!(is_separator(ch), true);
}
// Check each whitespace character
for ch in " \t\n\x0c".chars() {
assert_eq!(is_separator(ch), true, "Character {:#} should be a separator", ch as u8);
}
// Letters are not separators!
for ch in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_".chars() {
assert_eq!(is_separator(ch), false);
}
}
}

View File

@ -9,7 +9,7 @@ mod terminal_helpers;
use crate::editor::Editor;
use crate::terminal_helpers::*;
use libc::STDIN_FILENO;
use nix::libc::STDIN_FILENO;
use nix::sys::termios::Termios;
use std::env;
use std::io::Error;

View File

@ -1,8 +1,8 @@
//! # Helpers
//!
//! Various functions calling C wrappers to get/set terminal functionality
use libc::ioctl;
use libc::{c_ushort, STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ};
use nix::libc::ioctl;
use nix::libc::{c_ushort, STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ};
use nix::sys::termios;
use nix::sys::termios::{
ControlFlags, InputFlags, LocalFlags, OutputFlags, SpecialCharacterIndices, Termios,