Even when I open pure emacs -Q and a python file in it:
| - cursor
if smth:
| print("asd") # press TAB and cursor moves to "p" symbol, it's ok
if smth:
|print("asd") # press TAB and I get this:
if smth:
print("asd") # press TAB and I get prev step
So TAB makes a cyclic change of indentation level. Which I absolutely don't want to.
If to use smart-tab problem can be solved. But yasnippet (yas-global-mode 1) brings it again.
And that's where I can't find why.
If you had this problem (python+yasnippet+correct indent) - please give me a tip.
Or just a link to a working config.
Latest Emacs (24.3.50.1)
One way of controlling the cycling with TAB is to customize python-indent-trigger-commands.
The docstring of the variable states
Commands that might trigger a `python-indent-line' call.
However it is not clear from the docstring that the variable can be
used to control cycling (actually I am not even sure if setting this
variable if the correct way of controlling indentation cycling). The
docstring of python-indent-line explains the purpose of this variable better
When the variable last-command' is equal to one of the symbols
inside python-indent-trigger-commands or FORCE-TOGGLE is
non-nil it cycles levels indicated in the variable
python-indent-levels by setting the current level in the
variable `python-indent-current-level'.
So (setq python-indent-trigger-commands nil) (or you can just remove indent-for-tab-command from the list) can be used for disabling indentation cycling. There is
a slight disadvantage of this approach that you cannot use TAB indent code like the following where else
can either close for or if.
for ..:
if ..:
...
break
else:
...
You will have hit backspace before else to reindent it such that it
closes the for (by default it will be indented such that it closes the if)
Related
I am very new to python programming and debugging in pycharm. I want to find the value of a particular variable inside a if condition and have set a breakpoint , however the debugger shows that the variables are not available. Below is the screenshot of the code and the debugger:
I was facing the same issue and I fixed it by going through following steps :-
On the bottom left corner of your pycharm IDE, you will a settings option, click there and then go to "variable loading policy" and set this option to "on demand".
Hope it helps you.
It is because you're code isn't running yet. The print(...) line is inside the function, instead of outside the function. Your code can only run if something outside a function does something.
Fix: Just remove the tab in front of the print statement. Like so:
def factor(n):
# Your function body ...
for (...)
# Somewhere here is the return statement
print(factor(25)) # See the start of this `print` is inline with the `def`
You will see in the screenshot that pressing enter after pasting a multiline code doesnt run it but merely send each time a "...".
How can I run this multiline pasted code?
someone asked here, but did not get (the right) answer;
Did not work:
Backspace
Use the arrow key to move the cursor, then use the delete key
Escape
F2
Pressing enter twice when inside the Python interpreter executes a block of code, but you have an unmatched open parenthesis on the last line, so you haven't completed defining the block of code. Also, I'm not sure what dic is in the last line, because you haven't included its definition, so you may need to fix that as well.
Running
a=[1,2]
for x in a:
print(x)
actually works (pressing 2 enters worked as expected). So I made a mistake in the code above. I aplogise, I should have checked that before.
I don't delete the question since the one on google can be confusing (the guy did not mentioned it was his mistake, so I though there was a trick to be found. The trick is to check the code).
you could use IPython link which simplifies the process, better yet you have access to every command line as if executed inside the shell.
The other alternative is to encapsulate this inside a function
I know this answer is a bit late, but someone will need the information sometime:
When you make a new line, i.e. title.quote.... you need to press the tab to create an indent, then it will work. Without indenting, you get the "expected an indent" error message.
In older (I believe pre-5.0) versions of IPython, if I was working on a line/block, and suddenly discovered I needed to investigate something else to finish it, my approach was to hit Ctrl-C, which left the incomplete line/block on screen, but unexecuted, and gave me a fresh prompt. That is, I'd see something like:
In [1]: def foo():
...: stuff^C # <-- Just realized I needed to check something on stuff usage
In [2]: # <-- cursor goes to new line, but old stuff still on terminal
In newer IPython (which seems to have switched from readline to prompt_toolkit as the "CLI support framework"), the behavior of Ctrl-C differs; now, instead of giving me a newline, it just resets the current one, discarding everything I've typed and returning the cursor to the beginning of the line.
# Before:
In [1]: def foo():
...: stuff
# After Ctrl-C:
In [1]: # Hey, where'd everything go?
This is extremely annoying, since I can no longer see or copy/paste the code I was working on to resume my work after I've done whatever side task precipitated the need for a fresh prompt.
My question is: Is there any way to restore the old IPython behavior, where Ctrl-C does the following things:
Does not execute the line/block typed so far
Leaves it on the screen
Ability to choose (at config time is fine) whether to add to the history (this would be personal preference; do you want half-formed stuff in the history, or just on the terminal for copy/paste?)
Provides me with a fresh prompt below the text typed so far
I've searched everywhere, and the most I've found is a bug report comment that mentions this new behavior in passing as "...a change from earlier versions of IPython, but it is intentional."
I haven't been able to find anything documented about modifying the behavior in the IPython or prompt_toolkit documentation; I've found where a lot of these handlers are installed, but attempts at monkey-patching to alter the current behavior have failed (and frankly, monkey-patching undocumented code means I risk it breaking every upgrade, so I'd like to find some semi-supported fix for this; failing that, hacky monkey-patching is acceptable though).
And after more research, I found what appears to be a supported approach, relying on the IPython keyboard shortcuts documentation (documented slightly differently for 5.x and 6.x).
The solution is to create a file in ~/.ipython/profile_default/startup (any name, ending with .py or ipy is fine, e.g. fixctrlc.py), and add the following:
def fix_ctrlc():
'''Set up bindings so IPython 5.0+ responds to Ctrl-C as in pre-5.0
Specific behavior is to have Ctrl-C leave existing typed command on
screen and preserved in history. Easily modified to not put in history.
Since this is run as a startup script, all work, including imports,
is done in this function to avoid polluting global namespace.
Updates made as needed at https://stackoverflow.com/a/45600868/364696
'''
from IPython import get_ipython
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.keys import Keys
from prompt_toolkit.filters import HasFocus, ViInsertMode, EmacsInsertMode
ip = get_ipython()
# Determine if we're on a version of IPython that needs a fix,
# acquire the key bindings registry from the appropriate location,
# and establish closure state appropriate to that version of IPython
try:
try:
# IPython 5-6; render_as_done doesn't exist, but manual print works
registry = ip.pt_cli.application.key_bindings_registry
redraw_args = {}
doprint = True
except AttributeError:
# IPython 7+ (tested through 8.0.1)
# render_as_done necessary, and removes need for print
registry = ip.pt_app.key_bindings
redraw_args = {'render_as_done': True}
doprint = False
except AttributeError:
# On an old version of IPython that doesn't need the fix, or
# a new version that changed the registry location. Nothing to do.
return
def on_ctrlc(event):
text = event.cli.current_buffer.text.rstrip()
if text:
# Update cursor position to last non-space char in buffer (so Ctrl-C
# with cursor in middle of block doesn't lose text typed after cursor)
event.cli.current_buffer.cursor_position = len(text)
event.cli.current_buffer.text = text
# Redraw so cursor in correct position before print
event.cli._redraw(**redraw_args)
# (Optional) Put non-empty partial commands in history, not just left on screen
# Delete to leave them on screen, but not in history
event.cli.current_buffer.append_to_history()
# Print a newline to move us past currently typed text so it's not
# replaced on redraw
if doprint:
print()
# Reset/redraw prompt
event.cli.reset()
# Clear active buffer, leaving you with fresh, empty prompt
event.cli.current_buffer.reset()
registry.add_binding(
Keys.ControlC,
filter=(HasFocus(DEFAULT_BUFFER) & (ViInsertMode() | EmacsInsertMode()))
)(on_ctrlc)
fix_ctrlc()
del fix_ctrlc # Avoid polluting global namespace
Please feel free to contribute if you find a better solution.
When making a method in Eclipse using Python, is there a way to jump directly to next line, indented, after making input arguments? Instead of having to press end and enter, I keep missing that end key.
def _run_to_the_hills(self|):
Yes, you can use Shift+Enter for that (which in Eclipse means: move cursor to end of line and do a new line there).
I also recommend you read: http://pydev.blogspot.com.br/2014/03/mastering-writing-code-on-pydev.html at least once -- this is the first tip there, but there are other nice things there that you should know about too ;)
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.