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

Refactor waiting_proc and waiting_operator_proc #649

Merged
merged 7 commits into from Apr 14, 2024

Conversation

tompng
Copy link
Member

@tompng tompng commented Mar 19, 2024

Test will conflict with #645

Fixes #605

waiting_proc

Most waiting_proc will be cancelled when ARROW keys (and other symbol key) is pressed, but Reline did not implement cancel

# Method that uses waiting_proc and cancel when ARROW is pressed
incremental_search_history
vi_replace_char
vi_next_char
vi_to_next_char
vi_prev_char
vi_to_prev_char
# Exceptional case that readline inserts escape sequence when ARROW is pressed
ed_quoted_insert

Fixes except ed_quoted_insert.

waiting_operator_proc

Vi mode's waiting_operator_proc was complex.

c: vi_change_meta
d: vi_delete_meta
y: vi_yank

Reline's problem with waiting_operator

  • df_ does not terminate delete_meta
  • dd should clear line
  • cc should clear line
  • dc dy cd cy yd yc yy should cancel waiting_operator
  • For 3d5h, 5 should be used as @vi_arg but Reline does not
  • ARROW key should cancel waiting_operator

Fixes all of them.

@ima1zumi ima1zumi added the bug Something isn't working label Mar 25, 2024
input_keys('d2h')
assert_line_around_cursor('aaa bb', 'c')
input_keys('2d3h')
assert_line_around_cursor('aaa', 'c')
Copy link
Member

Choose a reason for hiding this comment

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

When I perform the same action in Vim, I get a different result. Is this intentional?

  1. Enter aaa bbc
  2. Place the cursor on c
  3. Enter 2d3h
  4. Only c remains

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice catch, looks like I misunderstood the correct behavior.
Updated the test to match with readline, fix implementation to use 2*3 = 6 as vi_arg in that case

# p should not paste yanked text because yank_meta is canceled
input_keys('dchdyhcdhcyhydhychyyhp')
assert_line_around_cursor('a', 'aa bbb ccc')
input_keys('dchdyhcdhcyhydhPychP')
Copy link
Member

@ima1zumi ima1zumi Apr 11, 2024

Choose a reason for hiding this comment

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

Can you split the input? This input is a bit complex. 😵‍💫

current_waiting_operator_proc.(byte_pointer_diff)
@waiting_operator_proc = old_waiting_operator_proc
}
send(@vi_waiting_operator, byte_pointer_diff)
Copy link
Member

Choose a reason for hiding this comment

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

For my learning: Why pass byte_pointer_diff? Are multi-byte characters allowed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. multi-byte characters are allowed.

vi_waiting_operator will do

  1. save cursor position (represented by @byte_pointer)
  2. accept VI_MOTIONS. cursor position moves. (@line_index does not change)
  3. Run an action(==@vi_waiting_operator) to a text between old cursor position and new cursor position

Current cursor position can be retrieved from @byte_pointer, so we need to pass old cursor_position or difference between old and new curspor_position
The original implementation selected diff, and this pull request follows it.

And we can choose how to represent cursor position: byte_pointer, string size, grapheme_cluster size width in column when rendered to terminal. Using byte_position is easiest because we don't need to translate @byte_pointer to another representation form.

Copy link
Member

Choose a reason for hiding this comment

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

I understood. Thanks for explaining!

if @vi_arg
@vi_arg = nil
end
@vi_arg = nil
Copy link
Member

Choose a reason for hiding this comment

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

For my learning: So all we need to do here is initialize vi_arg, why don't we call cleanup_waiting?

Copy link
Member Author

Choose a reason for hiding this comment

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

cleanup_waiting is to clear @waiting_proc relevant things. @waiting_proc is a mechanism to override input_key.
For example, C-h is normally handled by em_delete_prev_char, but in incremental search mode, it is handled by waiting_proc.

On the other hand, @vi_arg is not related to waiting_proc mechanism. It is passed to other normal ed_xxx vi_xxx em_xxx methods as a keyword parameter.

Copy link
Member Author

@tompng tompng Apr 11, 2024

Choose a reason for hiding this comment

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

Example: 2d3fo will do dfo (delete to next char o) 6 times,

2: ed_argument_digit sets @vi_arg = 2
d: vi_delete_meta sets @vi_waiting_operator, @vi_waiting_operator_arg = :vi_delete_meta_confirm, 2
3: ed_argument_digit sets @vi_arg = 3
f: vi_next_char sets @waiting_proc. run_for_operators should skips calling cleanup_waiting when @waiting_proc is set.
o: @vi_arg is set to 6, @waiting_proc is called (cursor moves), @vi_waiting_operator deletes text between cursor movement.

(I added this to test case)

Copy link
Member

Choose a reason for hiding this comment

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

I misunderstood the relationship between @waiting_operator and @vi_waiting_operator. Thanks!

Copy link
Member

@ima1zumi ima1zumi left a comment

Choose a reason for hiding this comment

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

LGTM!

@ima1zumi ima1zumi merged commit 777dffa into ruby:master Apr 14, 2024
40 checks passed
matzbot pushed a commit to ruby/ruby that referenced this pull request Apr 14, 2024
(ruby/reline#649)

* Fix waiting_proc precedence

* Fix waiting_operator bugs

* Add waiting_proc and vi_waiting_operator test

* Fix vi waiting operator arg number

vi_arg and vi_waiting_operator_arg should be multiplied

* Implement `yy` copies whole line in vi_command mode

* Simplify incremental search cancel test

* Add complex vi test with waiting_proc and vi_waiting_operator, split test input

ruby/reline@777dffae1c
@tompng tompng deleted the waiting_proc_fix branch April 14, 2024 16:53
tenderlove added a commit to tenderlove/ruby that referenced this pull request Apr 15, 2024
* master: (29 commits)
  Not all `nm`s support the `--help` option
  Emit a performance warning when redefining specially optimized methods
  YJIT: A64: Avoid intermediate register in `opt_and` and friends (ruby#10509)
  [ruby/reline] Remove not implemented method (ruby/reline#680)
  [ruby/reline] Fix vi_to_column which was broken (ruby/reline#679)
  Include more debug information in test_uplus_minus
  [Universal parser] DeVALUE of p->debug_lines and ast->body.script_lines
  Add more assertions in `test_uplus_minus`
  `super{}` doesn't use block
  fix incorrect warning.
  Update default gems list at fc36394 [ci skip]
  [ruby/optparse] bump up to 0.5.0
  show warning for unused block
  Emit `warn` event for duplicated hash keys on ripper
  [ruby/reline] Refactored Default Key Bindings (ruby/reline#678)
  [ruby/reline] Refactor waiting_proc and waiting_operator_proc (ruby/reline#649)
  [pty] Fix missing `or`
  [pty] Fix `ptsname_r` fallback
  [ruby/irb] Allow defining custom commands in IRB (ruby/irb#886)
  [ruby/reline] Support `menu-complete-backward` command for upward navigation (ruby/reline#677)
  ...
artur-intech pushed a commit to artur-intech/ruby that referenced this pull request Apr 26, 2024
(ruby/reline#649)

* Fix waiting_proc precedence

* Fix waiting_operator bugs

* Add waiting_proc and vi_waiting_operator test

* Fix vi waiting operator arg number

vi_arg and vi_waiting_operator_arg should be multiplied

* Implement `yy` copies whole line in vi_command mode

* Simplify incremental search cancel test

* Add complex vi test with waiting_proc and vi_waiting_operator, split test input

ruby/reline@777dffae1c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

Successfully merging this pull request may close these issues.

IRB crashes in vi-mode when moving after delete with find
2 participants