move AutoComplete

This commit is contained in:
Simon Gardling 2022-05-11 21:45:11 -04:00
parent 2dfa0dd5af
commit 30475eb4f4
7 changed files with 113 additions and 115 deletions

View File

@ -11,7 +11,7 @@ pub use crate::{
autocomplete_helper::compile_hashmap,
parsing::{process_func_str, BackingFunction},
suggestions::{
generate_hint, get_last_term, split_function, split_function_chars, Hint, HINT_EMPTY,
SUPPORTED_FUNCTIONS,
generate_hint, get_last_term, split_function, split_function_chars, AutoComplete, Hint,
Movement, HINT_EMPTY, SUPPORTED_FUNCTIONS,
},
};

View File

@ -253,3 +253,110 @@ impl<'a> Hint<'a> {
}
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
#[derive(PartialEq, Debug)]
pub enum Movement {
Complete,
#[allow(dead_code)]
Down,
#[allow(dead_code)]
Up,
None,
}
impl Movement {
pub const fn is_none(&self) -> bool { matches!(&self, Self::None) }
}
impl const Default for Movement {
fn default() -> Self { Self::None }
}
#[derive(Clone)]
pub struct AutoComplete<'a> {
pub i: usize,
pub hint: &'a Hint<'a>,
pub string: String,
}
impl<'a> const Default for AutoComplete<'a> {
fn default() -> AutoComplete<'a> { AutoComplete::EMPTY }
}
impl<'a> AutoComplete<'a> {
const EMPTY: AutoComplete<'a> = Self {
i: 0,
hint: &HINT_EMPTY,
string: String::new(),
};
#[allow(dead_code)]
pub fn update_string(&mut self, string: &str) {
if self.string != string {
// catch empty strings here to avoid call to `generate_hint` and unnecessary logic
if string.is_empty() {
*self = Self::EMPTY;
} else {
self.string = string.to_owned();
self.do_update_logic();
}
}
}
/// Runs update logic assuming that a change to `self.string` has been made
fn do_update_logic(&mut self) {
self.i = 0;
self.hint = generate_hint(&self.string);
}
#[allow(dead_code)]
pub fn register_movement(&mut self, movement: &Movement) {
if movement.is_none() {
return;
}
match self.hint {
Hint::Many(hints) => {
// Impossible for plural hints to be singular or non-existant
unsafe {
assume(hints.len() > 1);
assume(!hints.is_empty());
}
match movement {
Movement::Up => {
// if self.i is below 1, it's at
match self.i {
0 => self.i = hints.len() - 1,
_ => self.i -= 1,
}
}
Movement::Down => {
// add one, if resulting value is above maximum i value, set i to 0
self.i += 1;
if self.i > (hints.len() - 1) {
self.i = 0;
}
}
Movement::Complete => {
unsafe { assume(hints.len() >= (self.i + 1)) }
self.apply_hint(hints[self.i]);
}
_ => unreachable!(),
}
}
Hint::Single(hint) => {
if movement == &Movement::Complete {
self.apply_hint(hint);
}
}
_ => unreachable!(),
}
}
pub fn apply_hint(&mut self, hint: &str) {
self.string.push_str(hint);
self.do_update_logic();
}
}

View File

@ -2,13 +2,13 @@
use crate::math_app::AppSettings;
use crate::misc::*;
use crate::widgets::AutoComplete;
use egui::{
plot::{BarChart, PlotUi, Value},
widgets::plot::Bar,
Checkbox, Context,
};
use epaint::Color32;
use parsing::AutoComplete;
use parsing::{process_func_str, BackingFunction};
use std::{
fmt::{self, Debug},

View File

@ -1,9 +1,10 @@
use crate::consts::is_mobile;
use crate::function_entry::FunctionEntry;
use crate::widgets::{widgets_ontop, Movement};
use crate::widgets::widgets_ontop;
use egui::{Button, Id, Key, Modifiers, TextEdit, WidgetText};
use emath::vec2;
use parsing::Hint;
use parsing::Movement;
use std::ops::BitXorAssign;
use uuid::Uuid;

View File

@ -27,7 +27,6 @@ pub use crate::{
decimal_round, option_vec_printer, resolution_helper, storage_create, storage_read,
SteppedVector,
},
widgets::{AutoComplete, Movement},
};
cfg_if::cfg_if! {

View File

@ -1,111 +1,3 @@
use std::intrinsics::assume;
use parsing::{generate_hint, Hint, HINT_EMPTY};
#[derive(PartialEq, Debug)]
pub enum Movement {
Complete,
Down,
Up,
None,
}
impl Movement {
pub const fn is_none(&self) -> bool { matches!(&self, Self::None) }
}
impl const Default for Movement {
fn default() -> Self { Self::None }
}
#[derive(Clone)]
pub struct AutoComplete<'a> {
pub i: usize,
pub hint: &'a Hint<'a>,
pub string: String,
}
impl<'a> const Default for AutoComplete<'a> {
fn default() -> AutoComplete<'a> { AutoComplete::EMPTY }
}
impl<'a> AutoComplete<'a> {
const EMPTY: AutoComplete<'a> = Self {
i: 0,
hint: &HINT_EMPTY,
string: String::new(),
};
#[allow(dead_code)]
pub fn update_string(&mut self, string: &str) {
if self.string != string {
// catch empty strings here to avoid call to `generate_hint` and unnecessary logic
if string.is_empty() {
*self = Self::EMPTY;
} else {
self.string = string.to_owned();
self.do_update_logic();
}
}
}
/// Runs update logic assuming that a change to `self.string` has been made
fn do_update_logic(&mut self) {
self.i = 0;
self.hint = generate_hint(&self.string);
}
pub fn register_movement(&mut self, movement: &Movement) {
if movement.is_none() {
return;
}
match self.hint {
Hint::Many(hints) => {
// Impossible for plural hints to be singular or non-existant
unsafe {
assume(hints.len() > 1);
assume(!hints.is_empty());
}
match movement {
Movement::Up => {
// if self.i is below 1, it's at
match self.i {
0 => self.i = hints.len() - 1,
_ => self.i -= 1,
}
}
Movement::Down => {
// add one, if resulting value is above maximum i value, set i to 0
self.i += 1;
if self.i > (hints.len() - 1) {
self.i = 0;
}
}
Movement::Complete => {
unsafe { assume(hints.len() >= (self.i + 1)) }
self.apply_hint(hints[self.i]);
}
_ => unreachable!(),
}
}
Hint::Single(hint) => {
if movement == &Movement::Complete {
self.apply_hint(hint);
}
}
_ => unreachable!(),
}
}
pub fn apply_hint(&mut self, hint: &str) {
self.string.push_str(hint);
self.do_update_logic();
}
}
pub fn widgets_ontop<R>(
ui: &egui::Ui, id: String, re: &egui::Response, y_offset: f32,
add_contents: impl FnOnce(&mut egui::Ui) -> R,

View File

@ -1,5 +1,4 @@
use parsing::Hint;
use ytbn_graphing_software::{AutoComplete, Movement};
use parsing::{AutoComplete, Hint, Movement};
enum Action<'a> {
AssertIndex(usize),