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

fix: Simplify cursor repositioning during the 'ToggleDone' command #1712

Merged

Conversation

kedestin
Copy link
Contributor

@kedestin kedestin commented Mar 1, 2023

Description

Partially supercedes #1703

This PR is one in a collection of PRs with the ultimate goal of providing an option to write tasks using a plaintext version of this plugin's task format.

This PR's goal is to pave the way for implementing that plaintext task format, specifically by:

  • fix: Slightly reworking how the cursor is repositioned during the ToggleDone command. This to make it be agnostic to the task's format.

Users should expect the following cursor behavior:

  • When toggling a task, the cursor won't change columns. If toggling a task makes it shorter and leaves the cursor out of bounds, it is moved to the end of the line. This essentially was the previous behavior, except in a few edge cases.
  • When toggling an empty line or a line with just a list marker (number, bullet, dash), the cursor will jump to the end of the line so that a user can continue typing.

except in a few edge cases.

The specific edge case that are fixed are that:

  • If the cursor is at the start of a line, and a hyphen (-) and space follows
    • previously after ToggleDone the cursor was placed inside the [ and ]
    • now, the cursor is placed at the end of the line
  • With a trailing space at the end of a recurring task line
    • previously after ToggleDone the cursor used to move one character to the left for each trailing space.
    • now, the cursor retains its original position

Motivation and Context

When the ToggleDone command moves the cursor after inserting text, it regexes for a completion date with a regex specific to the default task format.

// Special-case for done-date append, fixes #449
const doneDateLength = ' ✅ YYYY-MM-DD'.length;
if (toggledLine.match(TaskRegularExpressions.doneDateRegex) && newLineLen - line.length >= doneDateLength) {
newLineLen -= doneDateLength;
}

Given the goal to introduce new task formats, I wanted to make the cursor repositioning work consistently regardless of which Task Format you were using. The simplest way I found to do that was to change the behavior to what I described in the #Description section which mostly matched the existing behavior according to the test suite.

How has this been tested?

Leverages the existing test suite for Toggle Done.

A small number of those tests were modified to reflect the changed behavior.

Screenshots (if appropriate)

Types of changes

Changes visible to users:

  • Bug fix (prefix: fix - non-breaking change which fixes an issue)
  • New feature (prefix: feat - non-breaking change which adds functionality)
  • Breaking change (prefix: feat!! or fix!! - fix or feature that would cause existing functionality to not work as expected)
  • Documentation (prefix: docs - improvements to any documentation content)
  • Sample vault (prefix: vault - improvements to the Tasks-Demo sample vault)

Internal changes:

  • Refactor (prefix: refactor - non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)
  • Tests (prefix: test - additions and improvements to unit tests and the smoke tests)
  • Infrastructure (prefix: chore - examples include GitHub Actions, issue templates)

Checklist

Terms

    When repositioning the cursor after toggling a task,
    the previous behavior had an explicit consideration for
    a completion date that was appended to a task and does so
    by regex'ing a hard-coded date format and a hard-coded completion
    symbol.

    Given that:
       * In most cases, the current behavior is that the cursor stays
            in place.
       * The hard-coded regex may not be applicable to other task
            formats

    This commit updates the way the the ToggleDone command repositions
    the cursor to *semantically* be "Leave it where it was before".
    The notable exceptions to this being toggling an *empty* line
    and a line that only has a list indictor. In both of those cases,
    the cursor is moved to the end of a line, to let a user continue
    typing out a task without needing to move the cursor manually.
@claremacrae
Copy link
Collaborator

Thank you!

The description of the change in behaviour is really clear.

When toggling a task, the cursor won't change columns. This essentially was the previous behavior, except in a few edge cases.

It would be helpful if this could also say what will happen if the cursor was inside a 'done date' before toggling, and the done date is removed.

When toggling an empty line or a line with just a list marker (number, bullet, dash), the cursor will jump to the end of the line so that a user can continue typing.

I do feel that makes this a bug-fix instead of a breaking change. The original behaviour was really annoying.

Which modes does this affect? I presume Live Preview and Source.

@claremacrae
Copy link
Collaborator

After some previous fixes to Toggle Done, the following file was created to support additional manual testing, by opening the Tasks-Demo folder as an Obsdian vault.

https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/resources/sample_vaults/Tasks-Demo/Manual%20Testing/Toggle%20Done%20Cursor%20Fixes.md

If you have time, would you mind running through the test steps, and updating anything that has been changed by this PR please?

(I guess it will also confirm that a load of things have not changed...)

@kedestin kedestin changed the title feat!!: Simplify cursor repositioning during the ToggleDone command fix: Simplify cursor repositioning during the ToggleDone command Mar 1, 2023
@kedestin
Copy link
Contributor Author

kedestin commented Mar 1, 2023

Thank you!

The description of the change in behaviour is really clear.

When toggling a task, the cursor won't change columns. This essentially was the previous behavior, except in a few edge cases.

It would be helpful if this could also say what will happen if the cursor was inside a 'done date' before toggling, and the done date is removed.

The description has been updated to document that if toggling a task would result in a cursor that is out of bounds, the cursor is moved to the end of the line.

- [x] ✅ 2023-|03-01 -> - [ ] |

When toggling an empty line or a line with just a list marker (number, bullet, dash), the cursor will jump to the end of the line so that a user can continue typing.

I do feel that makes this a bug-fix instead of a breaking change. The original behaviour was really annoying.

Title and description have been updated to position this as a bugfix.

Which modes does this affect? I presume Live Preview and Source.

As far as I'm aware, this only affects cursor repositioning as a result of running the ToggleDone command.

(I'm new to this plugin, and your question may be going over my head)

@claremacrae
Copy link
Collaborator

Hi @kedestin, I just wanted to say many thanks for this PR and all your replies - much appreciated.

I'm busy today, so will pick this up as soon as I can, as I realise it will be blocking your next PR...

@kedestin
Copy link
Contributor Author

kedestin commented Mar 1, 2023

I'm busy today, so will pick this up as soon as I can, as I realise it will be blocking your next PR...

I'm thankful for how receptive you've been to these changes, and want to re-iterate that I'm happy to continue with this at your leisure.

I have a personal build that meets my needs already, so I personally have no time-pressure to get my changes upstreamed into the official repo. I apologise if my eagerness to respond to feedback made it seem like I was trying to force this in as quickly as possible.

@claremacrae
Copy link
Collaborator

Thank you.

I apologise if my eagerness to respond to feedback made it seem like I was trying to force this in as quickly as possible.

Don't worry, it didn't!

Copy link
Collaborator

@claremacrae claremacrae left a comment

Choose a reason for hiding this comment

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

I've spent about an hour reading the code. I really like how many lines it has deleted, so how much of a simplification it is 😄 .

I've tried forming a mental model of how the new code works, and haven't really made much progress, so I've asked for a some comments in a few locations, to help whoever maintains this in future.

I also tried breaking the implementation in a few places to confirm the test coverage, and the tests did pick up the breakage.

Bit of a grumble to my past self (not requesting any changes in this area):
But as the author of the test tests, I do wish I had made any failures display any test failures by showing the wrong cursor position with a | marker in the string (if it was in range), for easier intepretation.

src/Commands/ToggleDone.ts Outdated Show resolved Hide resolved
src/Commands/ToggleDone.ts Show resolved Hide resolved
src/Commands/ToggleDone.ts Outdated Show resolved Hide resolved
src/Commands/ToggleDone.ts Outdated Show resolved Hide resolved
src/Commands/ToggleDone.ts Outdated Show resolved Hide resolved
src/Commands/ToggleDone.ts Show resolved Hide resolved
src/Commands/ToggleDone.ts Outdated Show resolved Hide resolved
src/Commands/ToggleDone.ts Outdated Show resolved Hide resolved
tests/Commands/ToggleDone.test.ts Outdated Show resolved Hide resolved
@claremacrae
Copy link
Collaborator

Just to note that I've edited the description to detail the changes of behaviour observed in the tests.

@claremacrae claremacrae added the scope: commands Additions and changes to the commands supplied by Tasks label Mar 4, 2023
@kedestin
Copy link
Contributor Author

kedestin commented Mar 4, 2023

I've tried forming a mental model of how the new code works, and haven't really made much progress, so I've asked for a some comments in a few locations, to help whoever maintains this in future.

In addition to the inline comments, I'll try to also describe the key ideas that I've been using to reason about this PR here:

  • toggleLine now tells the caller where to move the cursor, vs the previous implementation where the caller had to try and infer a cursor offset based on just the text that toggleLine returned.
  • Reason about cursor position using line number and column (a.k.a EditorPosition). The prior implementation treated the file as a single line which complicated how it dealt with repositioning the cursor across multiple lines.

@kedestin
Copy link
Contributor Author

kedestin commented Mar 5, 2023

After some previous fixes to Toggle Done, the following file was created to support additional manual testing, by opening the Tasks-Demo folder as an Obsdian vault.

https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/resources/sample_vaults/Tasks-Demo/Manual%20Testing/Toggle%20Done%20Cursor%20Fixes.md

If you have time, would you mind running through the test steps, and updating anything that has been changed by this PR please?

(I guess it will also confirm that a load of things have not changed...)

Not sure how to attest that I did this other than by saying "I did it" and hoping that you trust that I'm acting in good faith.


Running through the manual tests did highlight a behavior change that I don't think is particularly obvious when looking at the unit tests:

The vertical bar | denotes the position of the editor cursor

Before

Start End
wib|ble - wib|ble
>|> wibble >|> - wibble
- wi|bble - [ ] wi|bble
>|> - wibble >|> - [ ] wibble

After

Start End
wib|ble - wibble|
>|> wibble >> - wibble|
- wi|bble - [ ] wibble|
>|> - wibble >> - [ ] wibble|

The current tests do technically capture this behavior change, but I added some more assertions that make it more obvious that the cursor will jump to the end of the line.

@claremacrae claremacrae changed the title fix: Simplify cursor repositioning during the ToggleDone command fix: Simplify cursor repositioning during the 'ToggleDone' command Mar 5, 2023
@claremacrae
Copy link
Collaborator

I think this is now ready to go ahead and merge. Do you agree @kedestin?

@kedestin
Copy link
Contributor Author

kedestin commented Mar 5, 2023

Looks good to me.

@claremacrae claremacrae merged commit feaafaf into obsidian-tasks-group:main Mar 6, 2023
@claremacrae
Copy link
Collaborator

@kedestin Many thanks for a great simplification of the code - I learned a lot from it too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: commands Additions and changes to the commands supplied by Tasks
Projects
Status: 🎉 Released
Development

Successfully merging this pull request may close these issues.

None yet

2 participants