mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Merge pull request #1050 from rtfeldman/home_end_keys
Home+End keys tests and bug fixes
This commit is contained in:
commit
93e8698007
10 changed files with 1636 additions and 556 deletions
|
@ -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.
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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<()>;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
35
editor/src/window/keyboard_input.rs
Normal file
35
editor/src/window/keyboard_input.rs
Normal 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
1
editor/src/window/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod keyboard_input;
|
Loading…
Add table
Add a link
Reference in a new issue