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

ruby-block-send sends unexpected block #171

Open
bo-tato opened this issue Jul 20, 2023 · 4 comments
Open

ruby-block-send sends unexpected block #171

bo-tato opened this issue Jul 20, 2023 · 4 comments

Comments

@bo-tato
Copy link
Contributor

bo-tato commented Jul 20, 2023

begin
  puts "outer" # cursor on this line
  begin
    puts "inner"
  end
  puts "outer again"
end

here if we do ruby send block with the cursor on the first puts "outer", I think expected behavior is to send the block containing puts "outer" but it sends puts "inner" block, as ruby-send-block is using ruby-end-of-block which uses ruby-move-to-block which moves to what it calls the sibling block, in other words just the next end statement, not the end of the block containing the cursor.
Another unexpected behavior is when the cursor is on the ending line of a block:

begin
  puts "first block"
end # cursor on this line
begin
  puts "second block"
end

with the cursor on the end line of the first block, ruby- block-send sends the second block.

In https://github.com/bo-tato/inf-ruby/tree/fix-ruby-send-block I change ruby-send-block to use er/ruby-forward-up which gives the behavior I'd expect for both those cases. I don't open a pull request as that introduces a dependency on expand-region package that I assume is undesired. If it's desired to change ruby-send-block to behave like this I can try to code it without adding extra dependency

@bo-tato
Copy link
Contributor Author

bo-tato commented Jul 20, 2023

I realize if we're ok with depending on expand-region it has another method that makes ruby-block-send even simpler, just:

(-let (((start . end) (er/get-ruby-block)))
    (ruby-send-region start end))

@dgutov
Copy link
Collaborator

dgutov commented Jul 21, 2023

Hi!

Speaking of the first example, arguably, either of the behaviors can make sense. expand-region behaves in a particular way, if only because of the name (expand).

Do you maybe have an example of other major mode where block-related commands behave in this specific way? Just as a way of making this argument.

@bo-tato
Copy link
Contributor Author

bo-tato commented Jul 22, 2023

Interesting, I'm just starting to learn ruby but I can see now some might expect the current behavior for the first example, that send block sends the next complete block after the cursor. To me at least though it's more intuitive that it sends the block the cursor is in. If anything the traditional send to repl commands for emacs I think are all sending the expression before the cursor not after. The one major mode I know with a comparable command is cider-eval-list-at-point for cider mode for clojure. If we translate the first example to clojure:

(do
  (println "outer") ; [cursor here]
  (do
    (println "inner"))
  (println "outer again"))

It will print outer, inner, outer again. The list (pair of parenthesis around cursor), is equivalent in ruby I think to the block (begin/end pair around cursor).

translating the example to python:

if True:
    print("outer")
    if True:
        print("inner")
    print("outer again")

I have in my emacs config the function:

(defun my/python-shell-send-block ()
  "Send the current block to the inferior python process for evaluation."
  (interactive)
  (save-excursion
    (let ((beginning (python-nav-beginning-of-block))
          (end (python-nav-end-of-block)))
      (python-shell-send-region beginning end))))

which behaves in this same way (sending the block the cursor is in), but I just copied that function from online somewhere, I don't think it's made it into any actual package. It's interesting python-nav-end-of-block is part of the official python package and it's behavior is different from ruby-end-of-block causing the difference in block-send. On the first outer, ruby-end-of-block will go to the end of the inner block, where python-nav-end-of-block will go to the end of the outer block.

@dgutov
Copy link
Collaborator

dgutov commented Sep 29, 2023

It's interesting python-nav-end-of-block is part of the official python package and it's behavior is different from ruby-end-of-block causing the difference in block-send. On the first outer, ruby-end-of-block will go to the end of the inner block, where python-nav-end-of-block will go to the end of the outer block.

You are right.

ruby-end-of-block and its twin are more simplistic. The behavior of python-nav-end-of-block should suit us better here, so it would be a good idea to adapt its algorithm.

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

No branches or pull requests

2 participants