Compare commits
2 commits
a311f49e4b
...
dac1dfdb4a
| Author | SHA1 | Date | |
|---|---|---|---|
| dac1dfdb4a | |||
| e4f4866411 |
4 changed files with 42 additions and 23 deletions
|
|
@ -23,6 +23,3 @@
|
||||||
- [ ] Replace
|
- [ ] Replace
|
||||||
|
|
||||||
## Issues to fix
|
## Issues to fix
|
||||||
|
|
||||||
- Can't use left/right to edit text in finder
|
|
||||||
- Pressing return on `foo {|bar` should wrap `bar` in a block
|
|
||||||
55
src/state.rs
55
src/state.rs
|
|
@ -87,7 +87,11 @@ impl Text {
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
for (i, line) in self.lines().enumerate() {
|
for (i, line) in self.lines().enumerate() {
|
||||||
if i as isize == coord[1] {
|
if i as isize == coord[1] {
|
||||||
return pos + coord[0].clamp(0, line.len().saturating_sub(1) as isize) as usize;
|
return pos
|
||||||
|
+ coord[0].clamp(
|
||||||
|
0,
|
||||||
|
line.len().saturating_sub(line.ends_with(&['\n']) as usize) as isize,
|
||||||
|
) as usize;
|
||||||
} else {
|
} else {
|
||||||
pos += line.len();
|
pos += line.len();
|
||||||
}
|
}
|
||||||
|
|
@ -565,7 +569,9 @@ impl Buffer {
|
||||||
fn remove_inner(&mut self, range: Range<usize>) -> Change {
|
fn remove_inner(&mut self, range: Range<usize>) -> Change {
|
||||||
self.unsaved = true;
|
self.unsaved = true;
|
||||||
|
|
||||||
// TODO: Bell if false?
|
// Force range to be valid
|
||||||
|
let range = range.start.min(self.text.chars.len())..range.end.min(self.text.chars.len());
|
||||||
|
|
||||||
let removed = self.text.chars.drain(range.clone()).collect();
|
let removed = self.text.chars.drain(range.clone()).collect();
|
||||||
self.highlights_stale = true;
|
self.highlights_stale = true;
|
||||||
Change {
|
Change {
|
||||||
|
|
@ -602,12 +608,17 @@ impl Buffer {
|
||||||
self.push_undo(change);
|
self.push_undo(change);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_after(&mut self, cursor_id: CursorId, chars: impl IntoIterator<Item = char>) {
|
pub fn insert_after(
|
||||||
|
&mut self,
|
||||||
|
cursor_id: CursorId,
|
||||||
|
at: Option<usize>,
|
||||||
|
chars: impl IntoIterator<Item = char>,
|
||||||
|
) {
|
||||||
let Some(cursor) = self.cursors.get(cursor_id) else {
|
let Some(cursor) = self.cursors.get(cursor_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let old_cursor = *cursor;
|
let old_cursor = *cursor;
|
||||||
self.insert(old_cursor.pos, chars);
|
self.insert(at.unwrap_or(old_cursor.pos), chars);
|
||||||
let Some(cursor) = self.cursors.get_mut(cursor_id) else {
|
let Some(cursor) = self.cursors.get_mut(cursor_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -642,7 +653,10 @@ impl Buffer {
|
||||||
} else*/
|
} else*/
|
||||||
if let Some(pos) = cursor.pos.checked_sub(1) {
|
if let Some(pos) = cursor.pos.checked_sub(1) {
|
||||||
// If a backspace is performed on a space, a deindent takes place instead
|
// If a backspace is performed on a space, a deindent takes place instead
|
||||||
if self.text.chars().get(pos) == Some(&' ') {
|
if self.text.chars().get(pos) == Some(&' ')
|
||||||
|
// Ensure there's only whitespace to our left
|
||||||
|
&& self.text.chars().get(line_start..pos).unwrap_or(&[]).iter().all(|c| "\t ".contains(*c))
|
||||||
|
{
|
||||||
self.indent_at(pos, false);
|
self.indent_at(pos, false);
|
||||||
} else {
|
} else {
|
||||||
self.remove(pos..pos + 1);
|
self.remove(pos..pos + 1);
|
||||||
|
|
@ -667,6 +681,7 @@ impl Buffer {
|
||||||
};
|
};
|
||||||
let coord = self.text.to_coord(cursor.pos);
|
let coord = self.text.to_coord(cursor.pos);
|
||||||
let line_start = self.text.to_pos([0, coord[1]]);
|
let line_start = self.text.to_pos([0, coord[1]]);
|
||||||
|
let line_end = self.text.to_pos([1000000, coord[1]]);
|
||||||
|
|
||||||
let prev_indent = self
|
let prev_indent = self
|
||||||
.text
|
.text
|
||||||
|
|
@ -677,7 +692,8 @@ impl Buffer {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let next_indent = self.text.indent_of_line(coord[1] + 1).to_vec();
|
let next_indent = self.text.indent_of_line(coord[1] + 1).to_vec();
|
||||||
|
|
||||||
let (close_block, extra_indent, trailing_indent, base_indent) = if let Some(last_pos) =
|
// Determine whether we're creating/forming a new code block
|
||||||
|
let (close_block, extra_indent, closing_indent, base_indent) = if let Some(last_pos) =
|
||||||
cursor
|
cursor
|
||||||
.selection()
|
.selection()
|
||||||
.map_or(cursor.pos, |s| s.start)
|
.map_or(cursor.pos, |s| s.start)
|
||||||
|
|
@ -697,7 +713,7 @@ impl Buffer {
|
||||||
.next()
|
.next()
|
||||||
&& let next_char = self.text.chars().get(next_pos)
|
&& let next_char = self.text.chars().get(next_pos)
|
||||||
{
|
{
|
||||||
let close_block = (next_tok.map_or(true, |c| *c == '\n') // TODO: More robust is_line_end check
|
let close_block = (true//next_tok.map_or(true, |c| *c == '\n') // TODO: More robust is_line_end check
|
||||||
&& next_indent
|
&& next_indent
|
||||||
.strip_prefix(&*prev_indent)
|
.strip_prefix(&*prev_indent)
|
||||||
.map_or(false, |i| i.is_empty()))
|
.map_or(false, |i| i.is_empty()))
|
||||||
|
|
@ -715,19 +731,24 @@ impl Buffer {
|
||||||
(None, false, false, prev_indent)
|
(None, false, false, prev_indent)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Indent to same level as last line
|
// Where is the end of the new code block?
|
||||||
self.enter(
|
let end_of_block = line_end.max(cursor.pos);
|
||||||
cursor_id,
|
|
||||||
['\n'].into_iter().chain(base_indent.iter().copied()),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(r) = close_block {
|
if let Some(r) = close_block {
|
||||||
self.insert_after(cursor_id, [r]);
|
self.insert_after(cursor_id, Some(end_of_block), [r]);
|
||||||
}
|
}
|
||||||
if trailing_indent {
|
if closing_indent {
|
||||||
self.insert_after(cursor_id, core::iter::once('\n').chain(base_indent));
|
// Indent the block closer to the base level
|
||||||
|
self.insert_after(
|
||||||
|
cursor_id,
|
||||||
|
Some(end_of_block),
|
||||||
|
core::iter::once('\n').chain(base_indent.iter().copied()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indent to same level as last line
|
||||||
|
self.enter(cursor_id, ['\n'].into_iter().chain(base_indent));
|
||||||
if extra_indent {
|
if extra_indent {
|
||||||
|
// If we're starting a new block, increase the indent
|
||||||
self.indent(cursor_id, true);
|
self.indent(cursor_id, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -771,7 +792,7 @@ impl Buffer {
|
||||||
&& let Some(text) = cursor.selection().and_then(|s| self.text.chars().get(s))
|
&& let Some(text) = cursor.selection().and_then(|s| self.text.chars().get(s))
|
||||||
{
|
{
|
||||||
// cursor.place_at(s.end);
|
// cursor.place_at(s.end);
|
||||||
self.insert_after(cursor_id, text.to_vec())
|
self.insert_after(cursor_id, None, text.to_vec())
|
||||||
} else {
|
} else {
|
||||||
let coord = self.text.to_coord(cursor.pos);
|
let coord = self.text.to_coord(cursor.pos);
|
||||||
let line = self
|
let line = self
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ impl Finder {
|
||||||
return Ok(Resp::end(None));
|
return Ok(Resp::end(None));
|
||||||
}
|
}
|
||||||
Some(Action::Go) => return Ok(Resp::end(None)),
|
Some(Action::Go) => return Ok(Resp::end(None)),
|
||||||
Some(Action::Move(dir, Dist::Char, false, false)) => {
|
Some(Action::Move(dir @ (Dir::Up | Dir::Down), Dist::Char, false, false)) => {
|
||||||
match dir {
|
match dir {
|
||||||
Dir::Up => {
|
Dir::Up => {
|
||||||
self.selected = (self.selected + self.results.len().saturating_sub(1))
|
self.selected = (self.selected + self.results.len().saturating_sub(1))
|
||||||
|
|
|
||||||
|
|
@ -292,12 +292,13 @@ impl Input {
|
||||||
.text([1, 0], &format!("{:>line_num_w$}", line_num + 1)),
|
.text([1, 0], &format!("{:>line_num_w$}", line_num + 1)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let line_selected = buffer.text.to_coord(cursor.pos)[1] == line_num as isize;
|
||||||
|
|
||||||
// Line
|
// Line
|
||||||
{
|
{
|
||||||
let mut frame = frame.rect([margin_w, i], [!0, 1]);
|
let mut frame = frame.rect([margin_w, i], [!0, 1]);
|
||||||
for i in 0..frame.size()[0] {
|
for i in 0..frame.size()[0] {
|
||||||
let coord = self.focus[0] + i as isize;
|
let coord = self.focus[0] + i as isize;
|
||||||
let line_selected = (line_pos..line_pos + line.len()).contains(&cursor.pos);
|
|
||||||
let pos = if i < line.len() {
|
let pos = if i < line.len() {
|
||||||
Some(line_pos + coord as usize)
|
Some(line_pos + coord as usize)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue