Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an edit_ops.rs file #1263

Merged
merged 19 commits into from
Apr 30, 2020
Merged

Add an edit_ops.rs file #1263

merged 19 commits into from
Apr 30, 2020

Conversation

TDecking
Copy link
Collaborator

@TDecking TDecking commented Apr 27, 2020

Summary

This PR does the following:

  • It moves central editing operation away from editor.rs, closing Move editing functions out of editor.rs #1199.
  • Said operations no longer require a View to operate, but take a &[SelRegion] instead.
    • This will help with Move selection modification out of view.rs #1198, as someone working with raw selections no
      longer has to construct a View to use them for these functions.
    • The operations used the View not just to get selections, but also for functions
      like offset_of_line to get the lines. In case of View these are visual lines, not logical ones.
      Activating word wrap thus changed their behaviour, with special mention to
      duplicate_line, which was extremly broken. By making them think in logical lines,
      many previously undiscovered bugs have been fixed.
  • It also applies the changes demanded by clippy 0.0.212.
  • I have responded to reviews and made changes where appropriate.
  • I have tested the code with cargo test --all / ./rust/run_all_checks.
  • I have updated comments / documentation related to the changes I made.
  • I have rebased my PR branch onto xi-editor/master.

@cmyr
Copy link
Member

cmyr commented Apr 28, 2020

sorry I didn't notice this and fixed the various lints separately, want to rebase and I'll take a look?

@TDecking
Copy link
Collaborator Author

Rebased.

Copy link
Member

@cmyr cmyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I have a few preliminary comments, let me know what you think and I'll take another look.

/// A trait from which lines and columns in a document can be calculated
/// into offsets inside a rope an vice versa.
pub trait LineOffset {
// use own breaks if present, or text if not (no line wrapping)

/// Returns the byte offset corresponding to the given visual line.
/// Returns the byte offset corresponding to the given line.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visual is an important distinction, here; it indicates a distinction from 'logical' lines, which are just lines that end in a newline character. a 'visual' line may not end in a line break, and may be the result of word wrap.

I guess this whole comment is slightly out of date, having been moved from view.rs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LineOffset deals with both visual lines and logical lines, so this comment is indeed out of date.

I don't think that one trait coming with two behaviours is ideal in the long run,
but perhaps there is a way out of this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, so this was an intentional choice, to the best of my recollection; the idea is that in the absence of line breaks, the hard breaks are the visual lines. This means that all edit ops can work with just a buffer, but things 'just work' when you add a view?

It may be that this isn't helpful, but that was the original thinking.

rust/core-lib/src/tabs.rs Outdated Show resolved Hide resolved
@@ -16,6 +16,8 @@
//! It's useful to explicitly represent these operations so they can be
//! shared across multiple subsystems.

#![allow(clippy::many_single_char_names)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer this to be on a specific function of that is possible?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

rust/core-lib/src/line_offset.rs Show resolved Hide resolved
if !region.is_caret() {
region.min()
} else {
// backspace deletes max(1, tab_size) contiguous spaces
let (_, c) = view.offset_to_line_col(&text, region.start);
let (_, c) = DefaultLineOffset.offset_to_line_col(&text, region.start);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be changing the behaviour? by not using the view we may get different results here when word wrap is enabled. I'm not sure if this is a problem in practice, but it feels fishy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

view.line_of_offset calls lines.visual_line_of_offset, so different behaviour on word wrap was the default and the change a bugfix (see PR summary).
I've renamed DefaultLineOffset to LogicalLines, which should make the change more obvious (and DefaultLineOffset more descriptive).

builder.replace(interval, Rope::from(capitalized_text));
Transpose => {
let delta = edit_ops::transpose(&self.text, regions);
if !delta.is_identity() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to set EditType::Transpose here. It is probably worth doing another close read and make sure the edit type is correct in other places as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. There was indeed another case, but I belive that got them all.

(Are we testing undo and redo behaviour?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few tests around recording that exercise undo/redo, but overall not really. 😒

if start > 0 && self.text.byte_at(start - 1) == (b'-') {
start -= 1;
match cmd {
Delete { movement, kill } => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reading through this patch, I think my personal inclination would be to keep using the separate do_$thing methods, and then just in those methods call out to edit_ops; a major advantage of this approach is that it makes this diff easier to read and verify.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reversed this.
I didn't want multiple related functions with the same name doing different things when I made this. For now, the functions in editor.rs that call edit_ops.rs functions have the do_-prefix, while the functions in edit_ops.rs do not have that prefix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great yea this was the intended pattern originally; do_ meant that "this is the entry point for some command".

@codecov-io
Copy link

Codecov Report

Merging #1263 into master will increase coverage by 0.29%.
The diff coverage is 78.53%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1263      +/-   ##
==========================================
+ Coverage   71.09%   71.39%   +0.29%     
==========================================
  Files          81       83       +2     
  Lines       14961    14812     -149     
==========================================
- Hits        10637    10575      -62     
+ Misses       4324     4237      -87     
Impacted Files Coverage Δ
rust/core-lib/src/annotations.rs 70.43% <ø> (-1.47%) ⬇️
rust/core-lib/src/core.rs 42.62% <ø> (-1.64%) ⬇️
rust/core-lib/src/event_context.rs 83.39% <ø> (+0.13%) ⬆️
rust/core-lib/src/find.rs 82.21% <0.00%> (+2.54%) ⬆️
rust/core-lib/src/plugins/catalog.rs 25.39% <0.00%> (-0.41%) ⬇️
rust/core-lib/src/plugins/mod.rs 2.73% <ø> (ø)
rust/core-lib/src/rpc.rs 73.80% <ø> (-3.47%) ⬇️
rust/core-lib/src/width_cache.rs 84.09% <ø> (-2.28%) ⬇️
rust/core-lib/tests/rpc.rs 98.93% <ø> (-0.11%) ⬇️
rust/experimental/lang/src/language/plaintext.rs 0.00% <0.00%> (ø)
... and 98 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 65911d9...d3395c8. Read the comment docs.

Copy link
Member

@cmyr cmyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, this looks good to me, and is a helpful bit of cleanup. I'm currently working on text stuff in druid, and may at some point soon want to figure out a way to use some core xi stuff (edit ops, selections, movement) there. I'm not sure if this will mean moving that stuff to its own crate, or adding a default feature without which we only include some minimum set of things.

I'll leave this up for a minute in case you have further tweaks to make, and you can ping me when you'd like it merged.

@TDecking
Copy link
Collaborator Author

I don't have any further tweaks to make. Please go ahead and merge.

@cmyr cmyr merged commit add9e3e into xi-editor:master Apr 30, 2020
@cmyr
Copy link
Member

cmyr commented Apr 30, 2020

Thanks!

This was referenced Jun 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants