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

elpy-rpc--default-error-callback: Elpy error: yapf not installed #824

Closed
joostkremers opened this Issue Mar 9, 2016 · 6 comments

Comments

Projects
None yet
2 participants
@joostkremers

joostkremers commented Mar 9, 2016

I'm trying use C-c C-r f to run yapf on a region, but when I try this, Emacs responds with Elpy error: yapf not installed. (The subject lists the message as it appears in the *Messages* buffer.)

The relevant file uses a virtualenv, elpy-config reports the following:

Virtualenv........: python3 (/home/joost/src/mal/python3)
RPC Python........: 3.4.3 (/home/joost/src/mal/python3/bin/python)
Interactive Python: ipython (/home/joost/src/mal/python3/bin/ipython)
Emacs.............: 25.0.92.1
Elpy..............: 1.11.0
Jedi..............: 0.9.0
Rope..............: Not found (0.10.3 available)
Importmagic.......: 0.1.5
Autopep8..........: 1.2.2
Yapf..............: 0.6.3
Syntax checker....: flake8 (/home/joost/src/mal/python3/bin/flake8)

Which looks to me like everything should be fine. Note that yapf is only installed in the virtualenv, though, not system-wide. Should I install yapf system-wide as well? Won't that produce the wrong results, though, given that the system Python is version 2.7, whereas I use 3.4 in the virtualenv.

@jorgenschaefer jorgenschaefer added the bug label Mar 9, 2016

@jorgenschaefer jorgenschaefer added this to the v1.12 milestone Mar 9, 2016

@jorgenschaefer

This comment has been minimized.

Show comment
Hide comment
@jorgenschaefer

jorgenschaefer Mar 9, 2016

Owner

Hello, and thanks for the report! There should be no reason to install yapf system-wide, it should work in the virtualenv. Did you restart the RPC process after installing yapf, i.e. M-x elpy-rpc-restart?

Owner

jorgenschaefer commented Mar 9, 2016

Hello, and thanks for the report! There should be no reason to install yapf system-wide, it should work in the virtualenv. Did you restart the RPC process after installing yapf, i.e. M-x elpy-rpc-restart?

@joostkremers

This comment has been minimized.

Show comment
Hide comment
@joostkremers

joostkremers Mar 9, 2016

Yes, after M-x elpy-rpc-restart it started working. Thanks.

Two things, though: when running elpy-format-code on a region, point ends up somewhere else completely. I can't find any logic behind it, though. Also, when nothing is changed, the region is not deactivated. Perhaps that is by design, but it creates a strange effect when point is moved by the command. The first time this happened, I thought I had inadvertently pressed some unknown (to me) cursor motion command...

joostkremers commented Mar 9, 2016

Yes, after M-x elpy-rpc-restart it started working. Thanks.

Two things, though: when running elpy-format-code on a region, point ends up somewhere else completely. I can't find any logic behind it, though. Also, when nothing is changed, the region is not deactivated. Perhaps that is by design, but it creates a strange effect when point is moved by the command. The first time this happened, I thought I had inadvertently pressed some unknown (to me) cursor motion command...

@jorgenschaefer

This comment has been minimized.

Show comment
Hide comment
@jorgenschaefer

jorgenschaefer Mar 9, 2016

Owner

The point movement is a bit unfortunate but difficult to avoid. Your point should remain at the same line and column as before (as much as possible). It's difficult to know how the code in the changed file corresponds to the code in the old file, so that's the best guess we came up with.

The region not being deactivated sounds like a weird side effect. I'll look into it, thanks!

Owner

jorgenschaefer commented Mar 9, 2016

The point movement is a bit unfortunate but difficult to avoid. Your point should remain at the same line and column as before (as much as possible). It's difficult to know how the code in the changed file corresponds to the code in the old file, so that's the best guess we came up with.

The region not being deactivated sounds like a weird side effect. I'll look into it, thanks!

@joostkremers

This comment has been minimized.

Show comment
Hide comment
@joostkremers

joostkremers Mar 9, 2016

It's difficult to know how the code in the changed file corresponds to the code in the old file, so that's the best guess we came up with.

Yes, I see it now, in elpy--fix-code-with-formatter. But it seems to lead to the wrong result if elpy-format-code acts on a region. When (forward-line (1- line)) is called at the end of the function, point is not at (point-min), as is the case when the entire buffer is replaced. As a result, forward-line moves point too far down.

Wouldn't it be possible to use a marker? E.g., (not very well tested, but seems to work):

(defun elpy--fix-code-with-formatter (method)
  "Common routine for formatting python code."
  (if (use-region-p)
      (let ((pm (point-marker))
            (new-block (elpy-rpc method (list (elpy-rpc--region-contents))))
            (beg (region-beginning)) (end (region-end)))
        ;; Move `pm' marker with inserted text if point follows mark
        (if (<= (mark) (point))
            (set-marker-insertion-type pm t))
        (elpy-buffer--replace-region beg end new-block)
        ;; If no change was made, we must deactivate the region 
        (deactivate-mark)
        (goto-char pm)
        (set-marker pm nil))
    ;; Vector instead of list, json.el in Emacs 24.3 and before
    ;; breaks for single-element lists of alists.
    (let ((line (line-number-at-pos))
          (col (current-column))
          (new-block (elpy-rpc method (vector (elpy-rpc--buffer-contents))))
          (beg (point-min)) (end (point-max)))
      (elpy-buffer--replace-region beg end new-block)
      (forward-line (1- line))
      (forward-char col))))

The marker strategy doesn't work if the whole buffer is processed, so in that case the original strategy has to be maintained.

joostkremers commented Mar 9, 2016

It's difficult to know how the code in the changed file corresponds to the code in the old file, so that's the best guess we came up with.

Yes, I see it now, in elpy--fix-code-with-formatter. But it seems to lead to the wrong result if elpy-format-code acts on a region. When (forward-line (1- line)) is called at the end of the function, point is not at (point-min), as is the case when the entire buffer is replaced. As a result, forward-line moves point too far down.

Wouldn't it be possible to use a marker? E.g., (not very well tested, but seems to work):

(defun elpy--fix-code-with-formatter (method)
  "Common routine for formatting python code."
  (if (use-region-p)
      (let ((pm (point-marker))
            (new-block (elpy-rpc method (list (elpy-rpc--region-contents))))
            (beg (region-beginning)) (end (region-end)))
        ;; Move `pm' marker with inserted text if point follows mark
        (if (<= (mark) (point))
            (set-marker-insertion-type pm t))
        (elpy-buffer--replace-region beg end new-block)
        ;; If no change was made, we must deactivate the region 
        (deactivate-mark)
        (goto-char pm)
        (set-marker pm nil))
    ;; Vector instead of list, json.el in Emacs 24.3 and before
    ;; breaks for single-element lists of alists.
    (let ((line (line-number-at-pos))
          (col (current-column))
          (new-block (elpy-rpc method (vector (elpy-rpc--buffer-contents))))
          (beg (point-min)) (end (point-max)))
      (elpy-buffer--replace-region beg end new-block)
      (forward-line (1- line))
      (forward-char col))))

The marker strategy doesn't work if the whole buffer is processed, so in that case the original strategy has to be maintained.

@jorgenschaefer

This comment has been minimized.

Show comment
Hide comment
@jorgenschaefer

jorgenschaefer Mar 9, 2016

Owner

I like it! Do you actually need a marker at all? point should stay in the correct place when a region is replaced without any special handling?

(The comment about the vector should be before the elpy-rpc call and it does apply to the first call, too. :-))

Owner

jorgenschaefer commented Mar 9, 2016

I like it! Do you actually need a marker at all? point should stay in the correct place when a region is replaced without any special handling?

(The comment about the vector should be before the elpy-rpc call and it does apply to the first call, too. :-))

@joostkremers

This comment has been minimized.

Show comment
Hide comment
@joostkremers

joostkremers Mar 9, 2016

I like it! Do you actually need a marker at all? point should stay in the correct place when a region is replaced without any special handling?

My quick test showed that point is always placed at the beginning of the replaced region. (Which makes sense, because by default, a marker is not moved if text is inserted at its position.) So by saving (point-marker) and setting its insertion type to `t', it's possible to restore point to the end of the region if that's where it was before. To me, that would be preferable, though I'd be fine with point ending up at the start of the region.

Mind you, I haven't tested this extensively, so it's possible my code messes things up elsewhere...

(The comment about the vector should be before the elpy-rpc call and it does apply to the first call, too. :-))

Yeah, I wasn't sure what to make of that comment... 😉

joostkremers commented Mar 9, 2016

I like it! Do you actually need a marker at all? point should stay in the correct place when a region is replaced without any special handling?

My quick test showed that point is always placed at the beginning of the replaced region. (Which makes sense, because by default, a marker is not moved if text is inserted at its position.) So by saving (point-marker) and setting its insertion type to `t', it's possible to restore point to the end of the region if that's where it was before. To me, that would be preferable, though I'd be fine with point ending up at the start of the region.

Mind you, I haven't tested this extensively, so it's possible my code messes things up elsewhere...

(The comment about the vector should be before the elpy-rpc call and it does apply to the first call, too. :-))

Yeah, I wasn't sure what to make of that comment... 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment