Merge pull request #1050 from rtfeldman/home_end_keys

Home+End keys tests and bug fixes
This commit is contained in:
Richard Feldman 2021-03-07 23:08:19 -05:00 committed by GitHub
commit 93e8698007
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 1636 additions and 556 deletions

View file

@ -59,12 +59,14 @@ e.g. you have a test `calculate_sum_test` that only uses the function `add`, whe
* [Math Inspector](https://mathinspector.com/), [github](https://github.com/MathInspector/MathInspector)
* [Lamdu](http://www.lamdu.org/) live functional programming.
* [Sourcetrail](https://www.sourcetrail.com/) nice tree-like source explorer.
* [Unisonweb](https://www.unisonweb.org), definition based [editor](https://twitter.com/shojberg/status/1364666092598288385) as opposed to file based.
### Productivity features
* When refactoring;
- Cutting and pasting code to a new file should automatically add imports to the new file and delete them from the old file.
- Ability to link e.g. variable name in comments to actual variable name. Comment is automatically updated when variable name is changed.
- Ability to link e.g. variable name in comments to actual variable name. Comment is automatically updated when variable name is changed.
- AST backed renaming, changing variable/function/type name should change it all over the codebase.
* Automatically create all "arms" when pattern matching after entering `when var is` based on the type.
- All `when ... is` should be updated if the type is changed, e.g. adding Indigo to the Color type should add an arm everywhere where `when color is` is used.
* When a function is called like `foo(false)`, the name of the boolean argument should be shown automatically; `foo(`*is_active:*`false)`. This should be done for booleans and numbers.

View file

@ -408,20 +408,20 @@ fn begin_render_pass<'a>(
fn queue_editor_text(
size: &PhysicalSize<u32>,
_editor_lines: &str,
editor_lines: &str,
caret_pos: TextPos,
config: &Config,
glyph_brush: &mut GlyphBrush<()>,
) {
let area_bounds = (size.width as f32, size.height as f32).into();
// let code_text = Text {
// position: CODE_TXT_XY.into(),
// area_bounds,
// text: editor_lines,
// size: settings.code_font_size,
// ..Default::default()
// };
let code_text = Text {
position: CODE_TXT_XY.into(),
area_bounds,
text: editor_lines,
size: config.code_font_size,
..Default::default()
};
let s = format!("Ln {}, Col {}", caret_pos.line, caret_pos.column);
let text = s.as_str();
@ -438,7 +438,7 @@ fn queue_editor_text(
queue_text_draw(&caret_pos_label, glyph_brush);
// TODO convert to ast and render with render_ast::render_expr2
//queue_code_text_draw(&code_text, &ed_theme.syntax_high_map, settings, glyph_brush);
queue_text_draw(&code_text, glyph_brush);
}
fn _queue_no_file_text(

View file

@ -6,6 +6,7 @@ use crate::ui::text::{
text_pos::TextPos,
};
use crate::ui::ui_error::UIResult;
use crate::window::keyboard_input::from_winit;
use winit::event::{ModifiersState, VirtualKeyCode};
pub fn handle_copy(app_model: &mut AppModel) -> EdResult<()> {
@ -92,13 +93,15 @@ pub fn handle_cut(app_model: &mut AppModel) -> EdResult<()> {
}
pub fn pass_keydown_to_focused(
modifiers: &ModifiersState,
modifiers_winit: &ModifiersState,
virtual_keycode: VirtualKeyCode,
app_model: &mut AppModel,
) -> UIResult<()> {
let modifiers = from_winit(modifiers_winit);
if let Some(ref mut ed_model) = app_model.ed_model_opt {
if ed_model.has_focus {
ed_model.text.handle_key_down(modifiers, virtual_keycode)?;
ed_model.text.handle_key_down(&modifiers, virtual_keycode)?;
}
}

View file

@ -12,6 +12,7 @@ mod editor;
mod graphics;
pub mod lang; //TODO remove pub for unused warnings
mod ui;
mod window;
use std::io;
use std::path::Path;

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@ use super::selection::validate_selection;
use super::selection::Selection;
use super::text_pos::TextPos;
use crate::ui::ui_error::UIResult;
use winit::event::ModifiersState;
use crate::window::keyboard_input::Modifiers;
#[derive(Debug, Copy, Clone)]
pub struct CaretWSelect {
@ -11,7 +11,11 @@ pub struct CaretWSelect {
}
fn mk_some_sel(start_pos: TextPos, end_pos: TextPos) -> UIResult<Option<Selection>> {
Ok(Some(validate_selection(start_pos, end_pos)?))
if start_pos == end_pos {
Ok(None)
} else {
Ok(Some(validate_selection(start_pos, end_pos)?))
}
}
impl Default for CaretWSelect {
@ -31,43 +35,42 @@ impl CaretWSelect {
}
}
pub fn move_caret_w_mods(&mut self, new_pos: TextPos, mods: &ModifiersState) -> UIResult<()> {
let caret_pos = self.caret_pos;
pub fn move_caret_w_mods(&mut self, new_pos: TextPos, mods: &Modifiers) -> UIResult<()> {
let old_caret_pos = self.caret_pos;
// one does not simply move the caret
let valid_sel_opt = if new_pos != caret_pos {
if mods.shift() {
let valid_sel_opt = if mods.shift {
if new_pos != old_caret_pos {
if let Some(old_sel) = self.selection_opt {
if new_pos < old_sel.start_pos {
if caret_pos > old_sel.start_pos {
if old_caret_pos > old_sel.start_pos {
mk_some_sel(new_pos, old_sel.start_pos)?
} else {
mk_some_sel(new_pos, old_sel.end_pos)?
}
} else if new_pos > old_sel.end_pos {
if caret_pos < old_sel.end_pos {
if old_caret_pos < old_sel.end_pos {
mk_some_sel(old_sel.end_pos, new_pos)?
} else {
mk_some_sel(old_sel.start_pos, new_pos)?
}
} else if new_pos > caret_pos {
} else if new_pos > old_caret_pos {
mk_some_sel(new_pos, old_sel.end_pos)?
} else if new_pos < caret_pos {
} else if new_pos < old_caret_pos {
mk_some_sel(old_sel.start_pos, new_pos)?
} else {
// TODO should this return none?
None
}
} else if new_pos < self.caret_pos {
mk_some_sel(new_pos, caret_pos)?
mk_some_sel(new_pos, old_caret_pos)?
} else {
mk_some_sel(caret_pos, new_pos)?
mk_some_sel(old_caret_pos, new_pos)?
}
} else {
None
self.selection_opt
}
} else {
self.selection_opt
None
};
self.caret_pos = new_pos;

View file

@ -5,9 +5,10 @@ use crate::ui::text::{
text_pos::TextPos,
};
use crate::ui::ui_error::UIResult;
use crate::window::keyboard_input::Modifiers;
use bumpalo::collections::String as BumpString;
use bumpalo::Bump;
use winit::event::{ModifiersState, VirtualKeyCode};
use winit::event::VirtualKeyCode;
pub trait Lines {
fn get_line(&self, line_nr: usize) -> UIResult<&str>;
@ -27,13 +28,17 @@ pub trait SelectableLines {
fn set_caret(&mut self, caret_pos: TextPos);
fn move_caret_left(&mut self, shift_pressed: bool) -> UIResult<()>;
fn move_caret_left(&mut self, modifiers: &Modifiers) -> UIResult<()>;
fn move_caret_right(&mut self, shift_pressed: bool) -> UIResult<()>;
fn move_caret_right(&mut self, modifiers: &Modifiers) -> UIResult<()>;
fn move_caret_up(&mut self, shift_pressed: bool) -> UIResult<()>;
fn move_caret_up(&mut self, modifiers: &Modifiers) -> UIResult<()>;
fn move_caret_down(&mut self, shift_pressed: bool) -> UIResult<()>;
fn move_caret_down(&mut self, modifiers: &Modifiers) -> UIResult<()>;
fn move_caret_home(&mut self, modifiers: &Modifiers) -> UIResult<()>;
fn move_caret_end(&mut self, modifiers: &Modifiers) -> UIResult<()>;
fn get_selection(&self) -> Option<Selection>;
@ -48,6 +53,14 @@ pub trait SelectableLines {
fn select_all(&mut self) -> UIResult<()>;
fn last_text_pos(&self) -> TextPos;
fn last_char(&self, line_nr: usize) -> UIResult<Option<char>>;
fn handle_key_down(
&mut self,
modifiers: &Modifiers,
virtual_keycode: VirtualKeyCode,
) -> UIResult<()>;
}
pub trait MutSelectableLines {
@ -61,10 +74,4 @@ pub trait MutSelectableLines {
fn pop_char(&mut self) -> UIResult<()>;
fn del_selection(&mut self) -> UIResult<()>;
fn handle_key_down(
&mut self,
modifiers: &ModifiersState,
virtual_keycode: VirtualKeyCode,
) -> UIResult<()>;
}

View file

@ -44,10 +44,10 @@ pub fn validate_selection(start_pos: TextPos, end_pos: TextPos) -> UIResult<Sele
);
ensure!(
!(start_pos.line == end_pos.line && start_pos.column > end_pos.column),
!(start_pos.line == end_pos.line && start_pos.column >= end_pos.column),
InvalidSelection {
err_msg: format!(
"start_pos.column ({}) should be smaller than or equal to end_pos.column ({}) when start_pos.line equals end_pos.line",
"start_pos.column ({}) should be smaller than end_pos.column ({}) when start_pos.line equals end_pos.line",
start_pos.column,
end_pos.column
)

View file

@ -0,0 +1,35 @@
pub struct Modifiers {
pub shift: bool,
pub ctrl: bool,
pub alt: bool,
pub logo: bool,
}
impl Default for Modifiers {
fn default() -> Self {
Self {
shift: false,
ctrl: false,
alt: false,
logo: false,
}
}
}
pub fn no_mods() -> Modifiers {
Modifiers {
shift: false,
ctrl: false,
alt: false,
logo: false,
}
}
pub fn from_winit(winit_mods: &winit::event::ModifiersState) -> Modifiers {
Modifiers {
shift: winit_mods.shift(),
ctrl: winit_mods.ctrl(),
alt: winit_mods.alt(),
logo: winit_mods.logo(),
}
}

1
editor/src/window/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod keyboard_input;