Uso il pacchetto chiamato yasnippet per qualcosa di simile a questo. Dopo alcune piccole modifiche l'ho adattato per utilizzare invece lo stile docstring di Google:
Si noti tuttavia che richiede alcune impostazioni:
Lo snippet stesso deve eseguire un codice elisp di utilità per generare il testo. Questo è in genere risolto creando un file chiamato .yas-setup.el
con il codice all'interno della python-mode
directory dello snippet. Tuttavia è anche possibile posizionare il codice da qualche parte all'interno del tuo .emacs
.
Il codice per lo snippet è:
# -*- mode: snippet -*-
# Insert Google style docstring and function definition.
# name: Python Google style Docstring
# key: defg
# type: snippet
# contributor: Xaldew
# --
def ${1:name}($2):
\"\"\"$3
${2:$(python-args-to-google-docstring yas-text t)}
${5:Returns:
$6
}
\"\"\"
${0:$$(let ((beg yas-snippet-beg)
(end yas-snippet-end))
(yas-expand-snippet
(buffer-substring-no-properties beg end) beg end
(quote ((yas-indent-line nil) (yas-wrap-around-region nil))))
(delete-trailing-whitespace beg (- end 1)))}
Il codice per il .yas-setup.el
è:
(defun python-args-to-google-docstring (text &optional make-fields)
"Return a reST docstring format for the python arguments in yas-text."
(let* ((indent (concat "\n" (make-string (current-column) 32)))
(args (python-split-args text))
(nr 0)
(formatted-args
(mapconcat
(lambda (x)
(concat " " (nth 0 x)
(if make-fields (format " ${%d:arg%d}" (cl-incf nr) nr))
(if (nth 1 x) (concat " \(default " (nth 1 x) "\)"))))
args
indent)))
(unless (string= formatted-args "")
(concat
(mapconcat 'identity
(list "" "Args:" formatted-args)
indent)
"\n"))))
Si noti che python-split-args
è fornito dagli snippet standard . Vale a dire:
https://github.com/AndreaCrotti/yasnippet-snippets/tree/master Tuttavia, li ottieni di default quando installi il pacchetto package.el
.
Con tutto impostato correttamente, dovresti essere in grado di scrivere "defg" seguito da Tabper espandere lo snippet (vedi l'immagine per un esempio).
Esiste ancora un problema con l'utilizzo di questo rientro nidificato, ad esempio all'interno di classi o come funzioni nidificate. In quei casi, per qualche motivo la dotstring viene indentata erroneamente un tempo extra. Aggiornerò questo post se riesco a risolverlo.
Lo snippet ora dovrebbe funzionare all'interno di altri ambiti vietando yasnippet
di rientrare automaticamente nella seconda espansione.