Soft tabs and user-settable tab-widths are now supported.
Also, indentation style is automatically detected on file load.
This commit is contained in:
parent
0941339906
commit
ff6c763821
|
@ -9,10 +9,10 @@ const TAB_WIDTH: uint = 4;
|
|||
|
||||
/// Returns the visual width of a grapheme given a starting
|
||||
/// position on a line.
|
||||
fn grapheme_vis_width_at_vis_pos(g: &str, pos: uint) -> uint {
|
||||
fn grapheme_vis_width_at_vis_pos(g: &str, pos: uint, tab_width: uint) -> uint {
|
||||
match g {
|
||||
"\t" => {
|
||||
let ending_pos = ((pos / TAB_WIDTH) + 1) * TAB_WIDTH;
|
||||
let ending_pos = ((pos / tab_width) + 1) * tab_width;
|
||||
return ending_pos - pos;
|
||||
},
|
||||
|
||||
|
@ -233,11 +233,11 @@ impl Line {
|
|||
|
||||
|
||||
/// Returns the visual cell width of the line
|
||||
pub fn vis_width(&self) -> uint {
|
||||
pub fn vis_width(&self, tab_width: uint) -> uint {
|
||||
let mut width = 0;
|
||||
|
||||
for g in self.as_str().graphemes(true) {
|
||||
let w = grapheme_vis_width_at_vis_pos(g, width);
|
||||
let w = grapheme_vis_width_at_vis_pos(g, width, tab_width);
|
||||
width += w;
|
||||
}
|
||||
|
||||
|
@ -263,8 +263,8 @@ impl Line {
|
|||
}
|
||||
|
||||
|
||||
pub fn grapheme_width_at_index(&self, index: uint) -> uint {
|
||||
let mut iter = self.grapheme_vis_iter();
|
||||
pub fn grapheme_width_at_index(&self, index: uint, tab_width: uint) -> uint {
|
||||
let mut iter = self.grapheme_vis_iter(tab_width);
|
||||
let mut i = 0;
|
||||
|
||||
for (_, _, width) in iter {
|
||||
|
@ -282,13 +282,13 @@ impl Line {
|
|||
|
||||
|
||||
/// Translates a grapheme index into a visual horizontal position
|
||||
pub fn grapheme_index_to_closest_vis_pos(&self, index: uint) -> uint {
|
||||
pub fn grapheme_index_to_closest_vis_pos(&self, index: uint, tab_width: uint) -> uint {
|
||||
let mut pos = 0;
|
||||
let mut iter = self.as_str().graphemes(true);
|
||||
|
||||
for _ in range(0, index) {
|
||||
if let Some(g) = iter.next() {
|
||||
let w = grapheme_vis_width_at_vis_pos(g, pos);
|
||||
let w = grapheme_vis_width_at_vis_pos(g, pos, tab_width);
|
||||
pos += w;
|
||||
}
|
||||
else {
|
||||
|
@ -301,14 +301,14 @@ impl Line {
|
|||
|
||||
|
||||
/// Translates a visual horizontal position to the closest grapheme index
|
||||
pub fn vis_pos_to_closest_grapheme_index(&self, vis_pos: uint) -> uint {
|
||||
pub fn vis_pos_to_closest_grapheme_index(&self, vis_pos: uint, tab_width: uint) -> uint {
|
||||
let mut pos = 0;
|
||||
let mut i = 0;
|
||||
let mut iter = self.as_str().graphemes(true);
|
||||
|
||||
while pos < vis_pos {
|
||||
if let Some(g) = iter.next() {
|
||||
let w = grapheme_vis_width_at_vis_pos(g, pos);
|
||||
let w = grapheme_vis_width_at_vis_pos(g, pos, tab_width);
|
||||
if (w + pos) > vis_pos {
|
||||
let d1 = vis_pos - pos;
|
||||
let d2 = (pos + w) - vis_pos;
|
||||
|
@ -483,10 +483,11 @@ impl Line {
|
|||
|
||||
|
||||
/// Returns an iterator over the graphemes of the line
|
||||
pub fn grapheme_vis_iter<'a>(&'a self) -> LineGraphemeVisIter<'a> {
|
||||
pub fn grapheme_vis_iter<'a>(&'a self, tab_width: uint) -> LineGraphemeVisIter<'a> {
|
||||
LineGraphemeVisIter {
|
||||
graphemes: self.grapheme_iter(),
|
||||
vis_pos: 0,
|
||||
tab_width: tab_width,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -629,6 +630,7 @@ impl<'a> Iterator<&'a str> for LineGraphemeIter<'a> {
|
|||
pub struct LineGraphemeVisIter<'a> {
|
||||
graphemes: LineGraphemeIter<'a>,
|
||||
vis_pos: uint,
|
||||
tab_width: uint,
|
||||
}
|
||||
|
||||
impl<'a> LineGraphemeVisIter<'a> {
|
||||
|
@ -666,7 +668,7 @@ impl<'a> Iterator<(&'a str, uint, uint)> for LineGraphemeVisIter<'a> {
|
|||
fn next(&mut self) -> Option<(&'a str, uint, uint)> {
|
||||
if let Some(g) = self.graphemes.next() {
|
||||
let pos = self.vis_pos;
|
||||
let width = grapheme_vis_width_at_vis_pos(g, self.vis_pos);
|
||||
let width = grapheme_vis_width_at_vis_pos(g, self.vis_pos, self.tab_width);
|
||||
self.vis_pos += width;
|
||||
return Some((g, pos, width));
|
||||
}
|
||||
|
|
|
@ -50,12 +50,12 @@ impl Buffer {
|
|||
}
|
||||
|
||||
|
||||
pub fn get_grapheme_width(&self, index: uint) -> uint {
|
||||
pub fn get_grapheme_width(&self, index: uint, tab_width: uint) -> uint {
|
||||
if index >= self.len() {
|
||||
panic!("Buffer::get_grapheme_width(): index past last grapheme.");
|
||||
}
|
||||
else {
|
||||
return self.text.get_grapheme_width_recursive(index);
|
||||
return self.text.get_grapheme_width_recursive(index, tab_width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,13 +112,13 @@ impl Buffer {
|
|||
}
|
||||
|
||||
|
||||
pub fn pos_vis_2d_to_closest_1d(&self, pos: (uint, uint)) -> uint {
|
||||
pub fn pos_vis_2d_to_closest_1d(&self, pos: (uint, uint), tab_width: uint) -> uint {
|
||||
if pos.0 >= self.line_count() {
|
||||
return self.len();
|
||||
}
|
||||
else {
|
||||
let gs = self.pos_2d_to_closest_1d((pos.0, 0));
|
||||
let h = self.get_line(pos.0).vis_pos_to_closest_grapheme_index(pos.1);
|
||||
let h = self.get_line(pos.0).vis_pos_to_closest_grapheme_index(pos.1, tab_width);
|
||||
return gs + h;
|
||||
}
|
||||
}
|
||||
|
@ -129,9 +129,9 @@ impl Buffer {
|
|||
}
|
||||
|
||||
|
||||
pub fn pos_1d_to_closest_vis_2d(&self, pos: uint) -> (uint, uint) {
|
||||
pub fn pos_1d_to_closest_vis_2d(&self, pos: uint, tab_width: uint) -> (uint, uint) {
|
||||
let (v, h) = self.text.pos_1d_to_closest_2d_recursive(pos);
|
||||
let vis_h = self.get_line(v).grapheme_index_to_closest_vis_pos(h);
|
||||
let vis_h = self.get_line(v).grapheme_index_to_closest_vis_pos(h, tab_width);
|
||||
return (v, vis_h);
|
||||
}
|
||||
|
||||
|
|
|
@ -202,18 +202,18 @@ impl BufferNode {
|
|||
}
|
||||
|
||||
|
||||
pub fn get_grapheme_width_recursive(&self, index: uint) -> uint {
|
||||
pub fn get_grapheme_width_recursive(&self, index: uint, tab_width: uint) -> uint {
|
||||
match self.data {
|
||||
BufferNodeData::Leaf(ref line) => {
|
||||
return line.grapheme_width_at_index(index);
|
||||
return line.grapheme_width_at_index(index, tab_width);
|
||||
},
|
||||
|
||||
BufferNodeData::Branch(ref left, ref right) => {
|
||||
if index < left.grapheme_count {
|
||||
return left.get_grapheme_width_recursive(index);
|
||||
return left.get_grapheme_width_recursive(index, tab_width);
|
||||
}
|
||||
else {
|
||||
return right.get_grapheme_width_recursive(index - left.grapheme_count);
|
||||
return right.get_grapheme_width_recursive(index - left.grapheme_count, tab_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
174
src/editor.rs
174
src/editor.rs
|
@ -2,6 +2,7 @@
|
|||
|
||||
use buffer::Buffer;
|
||||
use std::path::Path;
|
||||
use std::cmp::min;
|
||||
use files::{load_file_to_buffer, save_buffer_to_file};
|
||||
use string_utils::grapheme_count;
|
||||
|
||||
|
@ -25,9 +26,9 @@ impl Cursor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_vis_start(&mut self, buf: &Buffer) {
|
||||
pub fn update_vis_start(&mut self, buf: &Buffer, tab_width: uint) {
|
||||
let (v, h) = buf.pos_1d_to_closest_2d(self.range.0);
|
||||
self.vis_start = buf.get_line(v).grapheme_index_to_closest_vis_pos(h);
|
||||
self.vis_start = buf.get_line(v).grapheme_index_to_closest_vis_pos(h, tab_width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,8 @@ impl Cursor {
|
|||
pub struct Editor {
|
||||
pub buffer: Buffer,
|
||||
pub file_path: Path,
|
||||
pub soft_tabs: bool,
|
||||
pub tab_width: uint,
|
||||
pub dirty: bool,
|
||||
|
||||
// The dimensions and position of the editor's view within the buffer
|
||||
|
@ -52,6 +55,8 @@ impl Editor {
|
|||
Editor {
|
||||
buffer: Buffer::new(),
|
||||
file_path: Path::new(""),
|
||||
soft_tabs: false,
|
||||
tab_width: 4,
|
||||
dirty: false,
|
||||
view_dim: (0, 0),
|
||||
view_pos: (0, 0),
|
||||
|
@ -62,14 +67,20 @@ impl Editor {
|
|||
pub fn new_from_file(path: &Path) -> Editor {
|
||||
let buf = load_file_to_buffer(path).unwrap();
|
||||
|
||||
Editor {
|
||||
let mut ed = Editor {
|
||||
buffer: buf,
|
||||
file_path: path.clone(),
|
||||
soft_tabs: false,
|
||||
tab_width: 4,
|
||||
dirty: false,
|
||||
view_dim: (0, 0),
|
||||
view_pos: (0, 0),
|
||||
cursor: Cursor::new(),
|
||||
}
|
||||
};
|
||||
|
||||
ed.auto_detect_indentation_style();
|
||||
|
||||
return ed;
|
||||
}
|
||||
|
||||
pub fn save_if_dirty(&mut self) {
|
||||
|
@ -79,6 +90,100 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn auto_detect_indentation_style(&mut self) {
|
||||
let mut tab_blocks: uint = 0;
|
||||
let mut space_blocks: uint = 0;
|
||||
let mut space_histogram: [uint, ..9] = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
let mut last_indent = (false, 0u); // (was_tabs, indent_count)
|
||||
|
||||
// Collect statistics
|
||||
let mut line_i: uint = 0;
|
||||
for line in self.buffer.line_iter() {
|
||||
let mut g_iter = line.grapheme_iter();
|
||||
match g_iter.next() {
|
||||
Some("\t") => {
|
||||
// Count leading tabs
|
||||
let mut count = 1;
|
||||
for g in g_iter {
|
||||
if g == "\t" {
|
||||
count += 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update stats
|
||||
if last_indent.0 && last_indent.1 < count {
|
||||
tab_blocks += 1;
|
||||
}
|
||||
|
||||
// Store last line info
|
||||
last_indent = (true, count);
|
||||
},
|
||||
|
||||
Some(" ") => {
|
||||
// Count leading spaces
|
||||
let mut count = 1;
|
||||
for g in g_iter {
|
||||
if g == " " {
|
||||
count += 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update stats
|
||||
if !last_indent.0 && last_indent.1 < count {
|
||||
space_blocks += 1;
|
||||
let amount = count - last_indent.1;
|
||||
if amount < 9 {
|
||||
space_histogram[amount] += 1;
|
||||
}
|
||||
else {
|
||||
space_histogram[8] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Store last line info
|
||||
last_indent = (false, count);
|
||||
},
|
||||
|
||||
_ => {},
|
||||
}
|
||||
|
||||
// Stop after 1000 lines
|
||||
line_i += 1;
|
||||
if line_i > 1000 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Analyze stats and make a determination
|
||||
if space_blocks == 0 && tab_blocks == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
if space_blocks > (tab_blocks * 2) {
|
||||
let mut width = 0;
|
||||
let mut width_count = 0;
|
||||
for i in range(0, 9) {
|
||||
if space_histogram[i] > width_count {
|
||||
width = i;
|
||||
width_count = space_histogram[i];
|
||||
}
|
||||
}
|
||||
|
||||
self.soft_tabs = true;
|
||||
self.tab_width = width;
|
||||
}
|
||||
else {
|
||||
self.soft_tabs = false;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_dim(&mut self, h: uint, w: uint) {
|
||||
self.view_dim = (h, w);
|
||||
}
|
||||
|
@ -86,7 +191,7 @@ impl Editor {
|
|||
|
||||
/// Moves the editor's view the minimum amount to show the cursor
|
||||
pub fn move_view_to_cursor(&mut self) {
|
||||
let (v, h) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0);
|
||||
let (v, h) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0, self.tab_width);
|
||||
|
||||
// Horizontal
|
||||
if h < self.view_pos.1 {
|
||||
|
@ -115,12 +220,43 @@ impl Editor {
|
|||
// Move cursor
|
||||
self.cursor.range.0 += str_len;
|
||||
self.cursor.range.1 += str_len;
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
}
|
||||
|
||||
pub fn insert_tab_at_cursor(&mut self) {
|
||||
if self.soft_tabs {
|
||||
// Figure out how many spaces to insert
|
||||
let (v, h) = self.buffer.pos_1d_to_closest_2d(self.cursor.range.0);
|
||||
let vis_pos = self.buffer.get_line(v).grapheme_index_to_closest_vis_pos(h, self.tab_width);
|
||||
let next_tab_stop = ((vis_pos / self.tab_width) + 1) * self.tab_width;
|
||||
let space_count = min(next_tab_stop - vis_pos, 8);
|
||||
|
||||
|
||||
// Insert spaces
|
||||
let space_strs = ["", " ", " ", " ", " ", " ", " ", " ", " "];
|
||||
self.buffer.insert_text(space_strs[space_count], self.cursor.range.0);
|
||||
self.dirty = true;
|
||||
|
||||
// Move cursor
|
||||
self.cursor.range.0 += space_count;
|
||||
self.cursor.range.1 += space_count;
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
}
|
||||
else {
|
||||
self.insert_text_at_cursor("\t");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn backspace_at_cursor(&mut self) {
|
||||
self.remove_text_behind_cursor(1);
|
||||
}
|
||||
|
||||
pub fn insert_text_at_grapheme(&mut self, text: &str, pos: uint) {
|
||||
self.dirty = true;
|
||||
let buf_len = self.buffer.len();
|
||||
|
@ -139,7 +275,7 @@ impl Editor {
|
|||
// Move cursor
|
||||
self.cursor.range.0 -= tot_g;
|
||||
self.cursor.range.1 -= tot_g;
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
|
@ -154,7 +290,7 @@ impl Editor {
|
|||
self.dirty = true;
|
||||
|
||||
// Move cursor
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
|
@ -169,7 +305,7 @@ impl Editor {
|
|||
|
||||
// Move cursor
|
||||
self.cursor.range.1 = self.cursor.range.0;
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
|
@ -177,7 +313,7 @@ impl Editor {
|
|||
|
||||
pub fn cursor_to_beginning_of_buffer(&mut self) {
|
||||
self.cursor.range = (0, 0);
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
|
@ -186,7 +322,7 @@ impl Editor {
|
|||
pub fn cursor_to_end_of_buffer(&mut self) {
|
||||
let end = self.buffer.len();
|
||||
self.cursor.range = (end, end);
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
|
@ -201,7 +337,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
self.cursor.range.1 = self.cursor.range.0;
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
|
@ -216,17 +352,17 @@ impl Editor {
|
|||
}
|
||||
|
||||
self.cursor.range.0 = self.cursor.range.1;
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
self.cursor.update_vis_start(&(self.buffer), self.tab_width);
|
||||
|
||||
// Adjust view
|
||||
self.move_view_to_cursor();
|
||||
}
|
||||
|
||||
pub fn cursor_up(&mut self, n: uint) {
|
||||
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0);
|
||||
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0, self.tab_width);
|
||||
|
||||
if v >= n {
|
||||
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v - n, self.cursor.vis_start));
|
||||
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v - n, self.cursor.vis_start), self.tab_width);
|
||||
self.cursor.range.1 = self.cursor.range.0;
|
||||
}
|
||||
else {
|
||||
|
@ -238,10 +374,10 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn cursor_down(&mut self, n: uint) {
|
||||
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0);
|
||||
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0, self.tab_width);
|
||||
|
||||
if v < (self.buffer.line_count() - n) {
|
||||
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v + n, self.cursor.vis_start));
|
||||
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v + n, self.cursor.vis_start), self.tab_width);
|
||||
self.cursor.range.1 = self.cursor.range.0;
|
||||
}
|
||||
else {
|
||||
|
@ -299,8 +435,8 @@ impl Editor {
|
|||
|
||||
pub fn jump_to_line(&mut self, n: uint) {
|
||||
let pos = self.buffer.pos_2d_to_closest_1d((n, 0));
|
||||
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(pos);
|
||||
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v, self.cursor.vis_start));
|
||||
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(pos, self.tab_width);
|
||||
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v, self.cursor.vis_start), self.tab_width);
|
||||
self.cursor.range.1 = self.cursor.range.0;
|
||||
|
||||
// Adjust view
|
||||
|
|
|
@ -136,11 +136,11 @@ impl TermUI {
|
|||
},
|
||||
|
||||
K_TAB => {
|
||||
self.editor.insert_text_at_cursor("\t");
|
||||
self.editor.insert_tab_at_cursor();
|
||||
},
|
||||
|
||||
K_BACKSPACE => {
|
||||
self.editor.remove_text_behind_cursor(1);
|
||||
self.editor.backspace_at_cursor();
|
||||
},
|
||||
|
||||
K_DELETE => {
|
||||
|
@ -312,7 +312,8 @@ impl TermUI {
|
|||
LineEnding::LS => "LS",
|
||||
LineEnding::PS => "PS",
|
||||
};
|
||||
let info_line = format!("UTF8:{} tabs:4", nl);
|
||||
let soft_tabs_str = if editor.soft_tabs {"spaces"} else {"tabs"};
|
||||
let info_line = format!("UTF8:{} {}:{}", nl, soft_tabs_str, editor.tab_width);
|
||||
self.rb.print(c2.1 - 30, c1.0, rustbox::RB_NORMAL, foreground, background, info_line.as_slice());
|
||||
|
||||
// Draw main text editing area
|
||||
|
@ -336,13 +337,13 @@ impl TermUI {
|
|||
|
||||
loop {
|
||||
if let Some(line) = line_iter.next() {
|
||||
let mut g_iter = line.grapheme_vis_iter();
|
||||
let mut g_iter = line.grapheme_vis_iter(editor.tab_width);
|
||||
let excess = g_iter.skip_vis_positions(editor.view_pos.1);
|
||||
|
||||
vis_col_num += excess;
|
||||
print_col_num += excess;
|
||||
|
||||
grapheme_index = editor.buffer.pos_vis_2d_to_closest_1d((vis_line_num, vis_col_num));
|
||||
grapheme_index = editor.buffer.pos_vis_2d_to_closest_1d((vis_line_num, vis_col_num), editor.tab_width);
|
||||
|
||||
for (g, pos, width) in g_iter {
|
||||
print_col_num = pos - editor.view_pos.1;
|
||||
|
@ -395,7 +396,7 @@ impl TermUI {
|
|||
// Print cursor if it's at the end of the text, and thus wasn't printed
|
||||
// already.
|
||||
if editor.cursor.range.0 >= editor.buffer.len() {
|
||||
let vis_cursor_pos = editor.buffer.pos_1d_to_closest_vis_2d(editor.cursor.range.0);
|
||||
let vis_cursor_pos = editor.buffer.pos_1d_to_closest_vis_2d(editor.cursor.range.0, editor.tab_width);
|
||||
if (vis_cursor_pos.0 >= editor.view_pos.0) && (vis_cursor_pos.1 >= editor.view_pos.1) {
|
||||
let print_cursor_pos = (vis_cursor_pos.0 - editor.view_pos.0 + c1.0, vis_cursor_pos.1 - editor.view_pos.1 + c1.1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user