jcollard / elm-mode

Elm mode for emacs
GNU General Public License v3.0
373 stars 67 forks source link

Evil - Deleting around a paragraph deletes to the end of buffer #163

Closed jsoo1 closed 4 years ago

jsoo1 commented 4 years ago

Environmental stuff

Using elm-mode at 1af80ff0a32f7ce7f2f1051acec49f280f95bdcc (and for about 2 years) Emacs 26.3, 28.0 Evil version 1.13.0

Steps to reproduce

Expected results

Actual results

Other notes

I tried using the evil mode test harness they provide without elm-mode and with -Q, etc, dap worked as expected.

purcell commented 4 years ago

What is "dap"? Not an Evil user, so more info is required. Also, if you can paste some sample code, that would be helpful.

jsoo1 commented 4 years ago

Hi! Thank you! You are so prompt!

dap deletes around a paragraph including surrounding whitespace.

Here's an example i think is a minimal reproduction:

module Example exposing (f, g, h)

f : String -> String -> String
f x y =
    x ++ y

g : String -> String -> List String
g x y =
    y ++ x
-- ^^ with point somewhere inside g

h : Int -> Int -> Int
h x y =
    x + y

Here's what I would expect when using dap:

module Example exposing (f, g, h)

f : String -> String -> String
f x y =
    x ++ y

h : Int -> Int -> Int
h x y =
    x + y

Here's what does happen:

module Example exposing (f, g, h)

f : String -> String -> String
f x y =
    x ++ y

Note that dip (delete a paragraph but not the surrounding whitespace) does do what i expect.

purcell commented 4 years ago

Thanks! My main question, really, was: is dap a command? How do I execute it? Is it a :dap command in evil, or something like that?

jsoo1 commented 4 years ago

dap is an evil-mode normal key sequence. So to use it you would be in evil normal mode, then put the point in the paragraph and press dap. It's a little hard to track down which top-level fn it uses. I believe it calls evil-delete with evil-a-paragraph but describe-key is unhelpful.

While trying to find some expression to use to reproduce I did some edebugging in evil-select-an-object. I think that may be where the wrong bounds are found but I don't know the exact top-level fn to evaluate. Debugging evil-select-an-object with debug-on-entry gives this stack:

Debugger entered--entering a function:
* evil-select-an-object(evil-paragraph nil nil line 1 t)
  evil-a-paragraph(nil nil nil nil)
  funcall-interactively(evil-a-paragraph nil nil nil nil)
  call-interactively(evil-a-paragraph)
  evil-motion-range(evil-a-paragraph nil nil)
  evil-operator-range(t)
  byte-code("\306\307\310\"\205\17\0\311\307\310\"\206\17\0\312\30\311\307\313\"\31`\314\211\32\33\314\211\34\25\16\26\26\27\315\316\317!\16\30\320 D\"`\262\2\f\25\321..." [evil-operator-range-motion evil-operator-range-type evil-operator-range-beginning evil-operator-range-end evil-inhibit-operator evil-inhibit-operator-value evil-has-command-property-p evil-delete :motion evil-get-command-property undefined :type nil append evil-operator-range t evil-yank-handler evil-visual-state-p region-active-p evil-visual-rotate upper-left :move-point this-command evil-this-operator evil-this-register deactivate-mark] 6)
  call-interactively(evil-delete nil nil)
  command-execute(evil-delete)

Another note. I tried to select around paragraph which also selects to the end of the buffer.

purcell commented 4 years ago

Navigating from that point with the regular forward-paragraph and backward-paragraph gives reasonable results, so I'd have to guess that Evil is doing something weird here.

jsoo1 commented 4 years ago

There is definitely a weird interaction going on. I am not sure where. I did these evaluations:

(bounds-of-thing-at-point 'evil-paragraph)
prog-mode: (89 . 144)
elm-mode: (89 . 144)

(evil-bounds-of-not-thing-at-point 'evil-paragraph)
prog-mode: (1 . 186)
elm-mode: (1 . 186)

(evil-select-an-object 'evil-paragraph nil nil 'line 1 t)
prog-mode: (89 146 line :expanded t)
elm-mode: (89 186 line :expanded t)

I'll keep investigating.

jsoo1 commented 4 years ago

I have dug more. When the point is at the indicated position (forward-thing 'evil-paragraph) and (forward-paragraph) do different things according to the mode.

module Example exposing (f, g, h)

f : String -> String -> String
f x y =
    x ++ y

g : String -> String -> List String
g x y =
    [ y, x ]
<-- point here
<-- elm-mode goes here
h : Int -> Int -> Int
h x y =
    x + y
<-- prog-mode goes here

I found the cause: (setq-local paragraph-separate "\\(\r\t\n\\|-}\\)$") at https://github.com/jcollard/elm-mode/blob/master/elm-mode.el#L160

When paragraph-separate is default forward-thing is fine.

I have also found navigating in doc comments awkward.

What should the regexp be, though?