I'm editing some Python code with rather long functions and decided it would be useful to quickly get the function name without scrolling up. I put this bit of code together to do it. Is there something built in to emacs in general, or the standard python mode in particular, which I can use instead?
(defun python-show-function-name()
"Message the name of the function the point is in"
(interactive)
(save-excursion
(beginning-of-defun)
(message (format "%s" (thing-at-point 'line)))))
You may find decent results with which-function-mode:
Which Function mode is a minor mode
that displays the current function
name in the mode line, updating it as
you move around in a buffer.
To either enable or disable Which
Function mode, use the command M-x
which-function-mode. This command is
global; it applies to all buffers,
both existing ones and those yet to be
created. However, it takes effect only
in certain major modes, those listed
in the value of which-func-modes. If
the value is t, then Which Function
mode applies to all major modes that
know how to support it—in other words,
all the major modes that support
Imenu.
Although I see it getting a little confused in one Python file that I have here...
Did you try py-beginning-of-def-or-class?
(defun python-show-function-name()
"Message the name of the function the point is in"
(interactive)
(save-excursion
(py-beginning-of-def-or-class)
(message (format "%s" (thing-at-point 'line)))))
I find it gives me better results than your beginning-of-defun, but if that's not the problem you're having, then maybe I'm just seeing another symptom of the cause of the wonkiness in my other answer.
C-c C-u (py-goto-block-up) might be what you want.
Related
How can I align my python arguments quickly in Vim. New to tabular plugin and cannot figure out command for aligning arguments properly:
Have this:
myfunc(arg1=value1,
arg2=value2,
arg3=value3,
arg4=value4,
arg5=value5,
arg6=value6,
arg7=value7)
Want this:
myfunc(arg1=value1,
arg2=value2,
arg3=value3,
arg4=value4,
arg5=value5,
arg6=value6,
arg7=value7)
You don't actually need Tabular.vim for this. Put your cursor at the top of myfunc (or a bit higher) and press =} (or =)). This runs equalprg across your function block to indent it appropriately.
From the help on 'equalprg':
External program to use for "=" command. When this option is empty
the internal formatting functions are used; either 'lisp', 'cindent'
or 'indentexpr'. When Vim was compiled without internal formatting,
the "indent" program is used.
Environment variables are expanded |:set_env|. See |option-backslash|
about including spaces and backslashes.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
BTW, if you do want to learn more about Tabular and its use cases, there’s a great video on vimcasts.
I have a simple question. Normally (and currently in other modes), after setting a mark with C-SPC, C-u C-SPC will return the cursor to that mark. However, in (Python) mode, and only (Python) mode, does that behavior not work, wherein it says "C-u C-SPC" is undefined.
I tried to look up the function and rebind it myself (i.e. C-h k then the command) but that returned as soon as I typed C-u. Can someone tell me the actual command C-u C-SPC invokes,
and/or why (Python) mode seems to debind it?
The actual command is set-mark-command bound to C-SPC, so you should be able to use C-h k C-SPC to see how it's bound. (C-u just adds a prefix argument).
For my emacs (24.3.1) C-u C-SPC works exactly as you say it should. What version are you using?
Works nicely from emacs -Q (python.el) as with python-mode.el
Also can't imagine one of the Python-IDE's out there took this key.
Maybe start from emacs -Q and load your init-file step by step.
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.
Does MicroFocus Cobol or any other, have a feature equivalent to Python's sys.settrace()?
The function passed as a parameter to such a tracing function, would be called after the execution of each line of the source code.
It's not an exact equivalent, but you can use READY TRACE for debugging. Enable it with the TRACE compiler directive.
OpenCOBOL supports
-ftrace Generate trace code
- Executed SECTION/PARAGRAPH
-ftraceall Generate trace code
- Executed SECTION/PARAGRAPH/STATEMENTS
- Turned on by -debug
cobc command line options. This isn't quite the same as the Python point of view, but outputs a tracer round on entry to sections, paragraphs and sentences when enabled. No doubt other compilers will have something equivalent. Along with the READY TRACE, debugging and >>D other debugging features like those allowed with DECLARATIVES. http://opencobol.add1tocobol.com/#declaratives
procedure division.
declaratives.
handle-errors section.
use after standard error procedure on filename-1.
handle-error.
display "Something bad happened with " filename-1 end-display.
.
helpful-debug section.
use for debugging on main-file.
help-me.
display "Just touched " main-file end-display.
.
end declaratives.
I find myself adding debugging "print" statements quite often -- stuff like this:
print("a_variable_name: %s" % a_variable_name)
How do you all do that? Am I being neurotic in trying to find a way to optimize this? I may be working on a function and put in a half-dozen or so of those lines, figure out why it's not working, and then cut them out again.
Have you developed an efficient way of doing that?
I'm coding Python in Emacs.
Sometimes a debugger is great, but sometimes using print statements is quicker, and easier to setup and use repeatedly.
This may only be suitable for debugging with CPython (since not all Pythons implement inspect.currentframe and inspect.getouterframes), but I find this useful for cutting down on typing:
In utils_debug.py:
import inspect
def pv(name):
record=inspect.getouterframes(inspect.currentframe())[1]
frame=record[0]
val=eval(name,frame.f_globals,frame.f_locals)
print('{0}: {1}'.format(name, val))
Then in your script.py:
from utils_debug import pv
With this setup, you can replace
print("a_variable_name: %s' % a_variable_name)
with
pv('a_variable_name')
Note that the argument to pv should be the string (variable name, or expression), not the value itself.
To remove these lines using Emacs, you could
C-x ( # start keyboard macro
C-s pv('
C-a
C-k # change this to M-; if you just want to comment out the pv call
C-x ) # end keyboard macro
Then you can call the macro once with C-x e
or a thousand times with C-u 1000 C-x e
Of course, you have to be careful that you do indeed want to remove all lines containing pv(' .
Don't do that. Use a decent debugger instead. The easiest way to do that is to use IPython and either to wait for an exception (the debugger will set off automatically), or to provoke one by running an illegal statement (e.g. 1/0) at the part of the code that you wish to inspect.
I came up with this:
Python string interpolation implementation
I'm just testing it and its proving handy for me while debugging.