3

When I run the command forward-sexp at the beginning of the line in Python mode, my cursor jumps to the end of the line. I assume that the line is a statement, and is therefore considered to be a sexp. Can I modify this behavior so that forward-sexp only jumps to the end of the symbol?

Steps to Reproduce:

Paste the following lines into a buffer in Python mode

def dummy():
    my_count_variable = 0
    (a, b, c) = (1, 2, 3)
    return my_count_variable

Case 1:

  • Move the cursor to the m at the beginning of my_count_variable
  • Call forward-sexp (C-M-f)
  • Notice that the cursor has jumped to the end of the line
  • (I would prefer to jump to the end of the symbol here)

Case 2:

  • Place the cursor at the beginning of the second line, just under the d in def
  • Call forward-sexp (C-M-f)
  • Notice that the cursor has moved to the end of my_count_variable
  • (This seems inconsistent with Case 1)

Case 3:

  • Place the cursor at the first ( on the third line
  • Call forward-sexp (C-M-f)
  • Notice that the cursor jumps to the end of the first tuple instead of the end of the statement.
  • (Again, why not jump to the end of the expression?)

Is there a way to modify the behavior of forward-sexp so that it does not treat a python "statement" as a balanced expression? There seems to be some inconsistency which causes the command to work how I want, but only sometimes (i.e. cases 2 and 3).

Note: I am using the built-in python-mode from python.el

  • 1
    You should mention the python mode you're using. – politza May 7 '15 at 20:18
  • Are you sure it's a bug? This is the behavior that I would expect. – Qudit May 8 '15 at 0:01
  • @Qudit: I never suggested that it was a bug. Although I do believe there is an inconsistency. I am looking for a way to modify the behavior. I will modify the post to make this clearer. – nispio May 11 '15 at 23:19
  • 1
    @nispio It's true that it's arguably inconsistent. The problem is that forward-sexp is an inherently ambiguous concept in non-lisp languages. – Qudit May 12 '15 at 1:08
3

I'd agree it's an inconsistency (w.r.t. other programming modes); I ended up here searching for the same answer.

Ultimately, I found the answer in the python.el source code (version 0.24.2) which contains:

If you prefer cc-mode-like forward-sexp movement, setting forward-sexp-function to nil is enough, You can do that using the python-mode-hook:

(add-hook 'python-mode-hook
        (lambda () (setq forward-sexp-function nil)))
1

The behavior is correct and the expected one.

forward-sexp

means: Move forward across one balanced expression. However, what should be "balanced"? Obviously this is a very general term. Emacs takes a single word as balanced expression, but not a single operator-sign. Lists are commonly well detected as balanced.

When starting from "(" in your example, call python-nav-end-of-statement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.