Emacs proper indentation for python code after newline ala PyCharm - python

PyCharm will ident the line after a == b correctly after I press enter:
if a == b:
print "something"
but when in emacs, it will give me:
if a == b:
print something
I already have python-mode enabled together with ergoemacs. Can someone who has done this before share how to to it ala PyCharm ?
Update:
*alt-return seems to be doing what I want*

C-j does newline-and-indent, which is what you are looking for probably.
With python-mode.el, RET is bound to py-newline-and-indent by default.

I'm guessing you're running the "wrong" python mode.
Your distribution most likely ships python-mode.el, which I - personally - find to be a bit clumsy.
Instead, try python.el. Just download the file, put it into ~/.emacs.d/ and add
(load "~/.emacs.d/python.el")
to your ~/.emacs file.
While you're at it, here are some good settings for whitespace and maximum line length:
(add-hook 'python-mode-hook '(lambda ()
(setq whitespace-line-column 79)
(setq whitespace-style '(face empty tabs lines-tail trailing))))

Press 'tab' key anywhere on the print something line - it should indent properly. This works for most modes.
EDIT
In other modes which do not have strict indenting rules like python you can highlight everything and Ctrl+Meta+\ will try to format everything.

Related

emacs 24: How do I get back emacs-23 sexp behavior for python mode?

I'm running both emacs 23 and 24 with "--no-init-file" to avoid loading my customizations. But then I explicitly load my ancient version of python-mode.el (version 3.105, last copyright notice 1998), and see the same behavior I'm about to describe, so I believe it's core emacs, not python.
Consider this code (the * marks the cursor location):
*def emacs_is_fun():
for x in range(3):
print(x)
Put the cursor at column 4 at the start of "def".
With emacs 23, running mark-sexp selects "def".
With emacs 24, mark-sexp selects the entire code block, to the end
of the print statement.
This isn't bad. The main problem is this common usage:
*very_long_var_name[very_long_expn] += long_function_call(long_arg_list, blah)
Again, the cursor is at the start of the printable part of the line, col 4.
In emacs 23, mark-sexp selects very_long_var_name.
In emacs 24, mark-sexp selects the full line, from col 4 to the end.
I've been using Ctrl-alt-space alt-w to quickly save variable names.
(Or alt-2 ctrl-alt-space alt-w to save a ref expression.) Now it's
gone. It's emacs, so this must be customizable, but I haven't found
where the new behaviour is implemented (and remember I'm using a python-mode
that is about 15 years old). What do I need to put in my .emacs file?
#Eric Interesting. Thanks for the context in the comment of my other answer.
I think you may just want this then:
(add-hook 'python-mode-hook (lambda () (setq forward-sexp-function nil)))
From comments inside python-mode built-in emacs 24 (which I think you may be getting instead)
At last but not least the specialized python-nav-forward-sexp allows easy navigation between code blocks. If you prefer cc-mode-like forward-sexp movement, setting forward-sexp-function to nil is enough...
This gels closer to what I think of a sexp as, like mentioned in my other answer, but outside of lisp a sexp seems at least somewhat ambiguous.
Seems like this was a bug fix in emacs 24. As that is technically now marking the full sexp. It seems like you want the functionality of marking a symbol instead.
I think by putting this in your .emacs you'll get the functionality you want.
(defun your-mark-symbol (&optional arg allow-extend)
"mark-sexp in lisp.el but with fowrad-symbol instead of foward-sexp"
(interactive "P\np")
(cond ((and allow-extend
(or (and (eq last-command this-command) (mark t))
(and transient-mark-mode mark-active)))
(setq arg (if arg (prefix-numeric-value arg)
(if (< (mark) (point)) -1 1)))
(set-mark
(save-excursion
(goto-char (mark))
(forward-symbol arg)
(point))))
(t
(push-mark
(save-excursion
(forward-symbol (prefix-numeric-value arg))
(point))
nil t))))
(global-set-key (kbd "C-M-SPC") 'your-mark-symbol)
Note that is literally a copy of mark-sexp but with foward-symbol instead of forward-sexp.
This could very well cause unexpected weirdness if you're using mark-sexp via C-M-SPC in other buffers/modes, in which case you would want to do make this keybinding via mode hook instead.

Indentation not working properly in emacs for python

I am using emacs-for-python provided by gabrielelanaro at this link.
Indentation doesn't seem to be working for me at all.
It doesn't happen automatically when I create a class, function or any other block of code that requires automatic indentation(if, for etc.) and press enter or Ctrl + j. Instead emacs says "Arithmetic Error".
It doesn't happen when I press Tab anywhere in a .py file. Again, every Tab press causes "Arithmetic error".
Also, when I manually indent code using spaces, I can't erase those spaces! Backspace-ing these indents also causes "Arithmetic Error".
This problem surfaces when I use the regular Python AC mode as well.
emacs : GNU Emacs 24.3.1 (x86_64-pc-linux-gnu, GTK+ Version 3.10.7)
of 2014-03-07 on lamiak, modified by Debian
Check the value of python-indent-offset. If it is 0, change it M-x set-variable RET python-indent-offset RET 4 RET.
Emacs tries to guess the offset used in a Python file when opening it. It might get confused and set that variable to 0 for some badly-formatted Python file. If this is indeed the problem, please do file a bug report using M-x report-emacs-bug and the text of the Python file so that the auto-detection can be fixed.
It is related to this bug
http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15975
The quickest workaround which I found was too add Jorgens Answer into .emacs file, add the following at the end of your .emacs file
(add-hook 'python-mode-hook
(lambda () (setq python-indent-offset 4)))
Can you comment the lines related to auto-complete in your init.el?
; (add-to-list 'load-path "~/.emacs.d/auto-complete-1.3.1")
; (require 'auto-complete)
; (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")
; (require 'auto-complete-config)
; (ac-config-default)
; (global-auto-complete-mode t)

Emacs 24.3 python: Can't guess python-indent-offset, using defaults 4

Can anyone who understands Lisp please help resolve this warning?
I upgraded to Emacs 24.3 and whenever I create a Python file using Emacs I get this warning message. Searched in python.el and found the following section of code that produces the warning:
(let ((indentation (when block-end
(goto-char block-end)
(python-util-forward-comment)
(current-indentation))))
(if indentation
(set (make-local-variable 'python-indent-offset) indentation)
(message "Can't guess python-indent-offset, using defaults: %s"
python-indent-offset)))
And here is my .emacs setup:
(setq-default c-basic-offset 4
tab-width 4
indent-tabs-mode nil)
(add-hook 'c-mode-common-hook
(lambda ()
(c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close 0)))
(add-hook 'python-mode-hook
(lambda ()
(c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close 0)))
When you open a python file, emacs guesses the indentation offset (number of spaces to indent) based on that file style. When you create a file (the case you describe), emacs cannot guess (file is empty) so it uses your default (4) and notifies the user.
In other words: it is a harmless warning; if you find this is a bug please report it as such.
If you don't like emacs guessing the offset, customize the variable python-indent-guess-indent-offset to nil, and then emacs will use always your default (very unsafe in python, where indentation has meaning and you could be editing a file created by somebody else with other defaults).
If all you want is to silence the warnings, while letting emacs still guess the offset as juanleon's answer explains, you can switch the python-indent-guess-indent-offset-verbose variable off.
(setq python-indent-guess-indent-offset t)
(setq python-indent-guess-indent-offset-verbose nil)
Per this comprehensive answer on the emacs SE.
Look in python.el, not python.elc. If you do not have python.el, then google for it (at least to look at it -- you do not need it to use Emacs). *.elc is a byte-compiled file, which is pretty much incomprehensible to humans.
The source code, in python.el, will tell you just what python-indent-guess-indent-offset does, and hence why you see the result you see.
In addition to the previous answers, and silencing the warning, this procedure deals with the problem and gives two examples for why the warning is useful.
Get a list of currently open buffers with C-x C-b. Filter those with a Python
extension, add quotes around them, and replace them in this command:
(dolist (f '(
"/path/to/file1"
"/path/to/file2"
))
(message (concat "Opening file: " f))
(find-file (expand-file-name f)))
Execute the command (select the region, then M-x evaluate-region). Then *Messages* looks like this:
Opening file: /path/to/file1
Opening file: /path/to/file2
Can’t guess python-indent-offset, using defaults: 4
For information about GNU Emacs and the GNU system, type C-h C-a.
I had files I had used for testing and that I had forgotten, for example:
from time import sleep
sleep(10000)
I only realized it thanks to this message and I deleted the files.
In another case, I had a useful file with just global variables, so I added this
line:
# -*- mode: python; python-indent-offset: 4 -*-
SOME_GLOBAL_VAR = 0
Although this does set the buffer-local variable (check by changing to 6, then
checking the value with C-h v python-indent-offset), it only does so after the
warning message, not before. I decided to tolerate this message.

emacs mode for snakemake?

snakemake is a python-like replacement for make that is geared more towards workflows than compilation. It's quite nice, but also quite new, and I cannot seem to find a mode for it in Emacs. I just want something very simple: a very slight modification from fundamental-mode, so I in perusing the emacs manual, I started the following in init.el:
(define-derived-mode snake-mode fundamental-mode
...
)
like make, snakemake is strict about indents (actual tab "\t" characters, not how emacs behaves by default when one types TAB). When I instead type "C-q TAB" it puts a real tab character in the buffer : this works, I tried it with a Snakefile in fundamental-mode and it runs perfectly. So to avoid typing "C-q TAB" each time I want a TAB in this mode, the first addition I would like to make to snake-mode is to rebind the TAB key to "C-q TAB" (or something like this). So I perused the emacs manual and tried:
(define-derived-mode snake-mode fundamental-mode
(global-set-key (kbd "\t") (kbd "C-q \t"))
...
)
but this and other alternatives aren't working ... maybe rebinding standard keys like the TAB key is not a recommended practice?
the other addition to the snake-mode I would like is for it to highlight syntax according to python (but not have any python behaviour, e.g., python indenting behaviour)
To conclude, just these 2 simple modifications to fundamental-mode in creating a "snake-mode" and a way to also invoke snake-mode if the filename is "Snakefile" was all I was looking for, but I've already spent several hours perusing the emacs manual and doing some googling, and it seems I'm not even close. This is so simple, and I'm quite sure it is possible; any advice?
Thanks
Murray
Your prayers have been answered:
https://github.com/kyleam/snakemake-mode
I am very happy with it.
Can be gotten from melpa as snakemake-mode.
The following (somewhat elegant, I think ... well at least it is short) kludge does the trick for now. It indeed does the two things I was asking for, i.e., (1) rebinds the TAB key (in a nice way), and (2) does syntax highlighting according to python (plus it only goes to this mode when the file is called "Snakefile", which is nice), and hence this answers my question
; snake-mode
(add-to-list 'auto-mode-alist '("Snakefile" . snake-mode))
(defun insert-tab ()
(interactive)
(insert " ")) ; a "real" tab, i.e., what "C-q \t" would give
(define-minor-mode snake-mode
"Snakemake."
:lighter " snake-make"
(python-mode)
(setq indent-line-function 'insert-tab)
)
; how to hard-code "\t" to a "real" tab (not recommended)
; (global-set-key "\t" `insert-tab)
; end snake-mode
How elegant this is, is, I'm sure, up for debate. And it is only a start on a journey for a proper mode for snakemake (that does highlighting for snakemake specific words like "rule" and "output:", etc., etc.)
Don't do this. It's not how major modes are supposed to handle indentation. They should never rebind TAB, see C-h v indent-line-function:
Function to indent the current line.
This function will be called with no arguments.
If it is called somewhere where auto-indentation cannot be done
(e.g. inside a string), the function should simply return `noindent'.
Setting this function is all you need to make TAB indent appropriately.
Don't rebind TAB unless you really need to.
It won't work anyway, because you can't bind key bindings to other key bindings.
Instead, set indent-tabs-mode to t in your mode function, to make Emacs use tab characters for indentation, and set indent-line-function buffer-locally, to a function that indents appropriately according to the rules of the language. You have to write this function yourself, obviously.
The define-derived-mode macro automatically provides a keymap named after the mode it defines. You can use that together with define-key to make the TAB key simply insert a tab like this:
(define-derived-mode snake-mode fundamental-mode "Snake"
"A mode for Python's snakemake."
(define-key snake-mode-map "\t" 'self-insert-command))
Alternatively, you could set up the indentation mechanism of your mode so that it intelligently indents a line by inserting a (single) TAB at the beginning of the line whenever that is appropriate. That way you don't have to rebind TAB, although of course it's much harder to implement intelligent indentation correctly than to simply rebind a key. See lunaryorn's answer for more information.

How to start ropemacs-mode automatically?

When I open a python file I have to manually start ropemacs-mode to get the key bindings each time. I tried adding something like this to automatically start ropemacs:
(add-hook 'python-mode-hook (lambda ()
(ropemacs-mode)
))
But it seems to break flymake. What am I doing wrong here?
Dont use ropemacs but the readme says like this
After installing pymacs, add these lines to your ~/.emacs file::
(require 'pymacs)
(pymacs-load "ropemacs" "rope-")
My problem was with some code for using autocomplete.el along with ropemacs and yas which I found here:
http://hide1713.wordpress.com/2009/01/30/setup-perfect-python-environment-in-emacs/
Once I commented out the block relating to autocomplete everything else started working as expected.

Categories

Resources