81 lines
3.1 KiB
ReStructuredText
81 lines
3.1 KiB
ReStructuredText
|
Add Python docstring to the beginning of anything in Emacs
|
|||
|
##########################################################
|
|||
|
|
|||
|
:date: 2016-11-30T07:52:37Z
|
|||
|
:category: blog
|
|||
|
:tags: development,python,emacs
|
|||
|
:url: 2016/11/30/add-python-docstring-to-the-beginning-of-anything/
|
|||
|
:save_as: 2016/11/30/add-python-docstring-to-the-beginning-of-anything/index.html
|
|||
|
:status: published
|
|||
|
:author: Gergely Polonkai
|
|||
|
|
|||
|
Now that I write Python code for a living, I write a lot of functions, classes, and modules. What
|
|||
|
I still tend to forget, and also find tedious, is adding docstrings. Unlike many developers,
|
|||
|
writing documentation is not an enemy of mine, but it usually comes to my mind when I finish
|
|||
|
implementation. The procedure, roughly, is this:
|
|||
|
|
|||
|
* Decide where I am (in a function, in a class but not in one of its methods, or not inside such a
|
|||
|
block at all)
|
|||
|
* Go to the beginning of the thing
|
|||
|
* Insert ``"""``
|
|||
|
* Leave a blank line
|
|||
|
* Insert ``"""``
|
|||
|
|
|||
|
One of my mottos is if something takes more than one step and you have to do it more than twice,
|
|||
|
you should automate it after the first time. This puts a small(ish) overhead on the second
|
|||
|
invocation (when you implement the automation), but it usually worth the time.
|
|||
|
|
|||
|
Since I use Emacs for pretty much everything coding-related (and many more, but that’s the topic
|
|||
|
of a different post), I wrote a small function to do it for me.
|
|||
|
|
|||
|
.. code-block:: lisp
|
|||
|
|
|||
|
(defun gpolonkai/prog-in-string-p ()
|
|||
|
"Return `t' if point is inside a string."
|
|||
|
(nth 3 (syntax-ppss)))
|
|||
|
|
|||
|
(defun gpolonkai/prog-in-comment-p ()
|
|||
|
"Return `t' if point is inside a comment."
|
|||
|
(nth 4 (syntax-ppss)))
|
|||
|
|
|||
|
(defun gpolonkai/python-add-docstring ()
|
|||
|
"Add a Python docstring to the current thing. If point is
|
|||
|
inside a function, add docstring to that. If point is in a
|
|||
|
class, add docstring to that. If neither, add docstring to the
|
|||
|
beginning of the file."
|
|||
|
(interactive)
|
|||
|
(save-restriction
|
|||
|
(widen)
|
|||
|
(beginning-of-defun)
|
|||
|
(if (not (looking-at-p "\\(def\\|class\\) "))
|
|||
|
(progn
|
|||
|
(goto-char (point-min))
|
|||
|
(back-to-indentation)
|
|||
|
(forward-char)
|
|||
|
(while (gpolonkai/prog-in-comment-p)
|
|||
|
(forward-line)
|
|||
|
(back-to-indentation)
|
|||
|
(forward-char)))
|
|||
|
(search-forward ":")
|
|||
|
(while (or (gpolonkai/prog-in-string-p)
|
|||
|
(gpolonkai/prog-in-comment-p))
|
|||
|
(search-forward ":")))
|
|||
|
(if (eq 1 (count-lines 1 (point)))
|
|||
|
(open-line-above)
|
|||
|
(open-line-below))
|
|||
|
(insert "\"\"\"")
|
|||
|
(open-line-below)
|
|||
|
(insert "\"\"\"")
|
|||
|
(open-line-above)))
|
|||
|
|
|||
|
There are still a lot of things to improve:
|
|||
|
|
|||
|
* it always inserts double quotes (althoug I couldn’t show a use-case when single quotes are
|
|||
|
preferred)
|
|||
|
* it doesn’t check for an existing docstring, just happily inserts a new one (leaving the old one
|
|||
|
alone, but generating a syntax error this way)
|
|||
|
* it would also be nice if I could jump to the beginning of a file even from a class method. I
|
|||
|
guess I will use prefix keys for that, but I’m not sure yet.
|
|||
|
|
|||
|
You can bet I will implement these features, so check back soon for an updated version!
|