Sooner or later we need to figure out how to do string editing - e.g. "foo" in Json or <foo> in XML.
I only have a rough idea now, but some things that make sense to me:
- Have a "stringly" node (defined below) that can be edited like a string.
- Allow languages to define escaping and unescaping functions - then the user can write unescaped text and it will become escaped when leaving string editation mode - this can be incredibly helpful as people often forget the escaping rules of different languages. This feature may be optional but it is probably easier to write it as mandatory for now.
- I don't believe it's a good idea to represent strings as lists of chars - likely not useful and a waste of memory
The API of stringly node can be described by this trait (which may or may not be an actual trait)
trait StringlyNode {
// Cow can save some allocations however we should inform the implementors which representation is more efficient.
// My guess for now is that it'll be more efficient to store escaped version as unescaped one will be only used in string edit mode
// Or maybe pass fmt::Write?
fn get_string_unescaped(&self) -> Cow<'_, str>;
// The user has to escape manually
fn get_string_escaped(&self) -> Cow<'_, str>;
// this generic can save some allocations while not caring about `&str` vs `String`
// returns Err if the string contains banned chars
// Alternatively we could use Cow to make this object safe
fn set_string_unescaped<S: Deref<Target=str> + Into<String>>(&mut self, string: S) -> Result<(), SetStringError>;
fn set_string_escaped<S: Deref<Target=str> + Into<String>>(&mut self, string: S) -> Result<(), SetStringError>;
// Validates the string, may be called after user typing each char and revert the change if this fn returns false
fn is_string_valid(&self, string: &str) -> bool;
}
I imagine this flow (pseudo code):
// when string edit mode is entered
// returned value imple StringlyNode
// returns Err if the node is not stringly
let stringly_node = tree.get_stringly_node(cursor)?;
let edited_string = String::from(stringly_node.get_tring_unescaped());
self.mode = Mode::StringEdit { stringly_node, };
// when leaving string edit mode:
match stringly_node.set_string_unescaped() {
Ok(_) => self.mode = Mode::Normal,
Err(error) => log_error!(error),
}
OT: so far I didn't have as much time to look at XML as I wished. I'm doing it now and maybe a bit tomorrow but I don't feel that great so I may be unable to finish it.
Sooner or later we need to figure out how to do string editing - e.g.
"foo"in Json or<foo>in XML.I only have a rough idea now, but some things that make sense to me:
The API of stringly node can be described by this trait (which may or may not be an actual trait)
I imagine this flow (pseudo code):
OT: so far I didn't have as much time to look at XML as I wished. I'm doing it now and maybe a bit tomorrow but I don't feel that great so I may be unable to finish it.