3

When writing within docstrings in python-mode, I'm only able to tab/indent deeper than the leading edge of the string. For example:

def foo():
    """
|   | << the only places I can "tab" to.
    """
    pass

I'd like to be able to tab deeper within docstrings, to make editing easier for editing documentation, working with YAML, etc.

Is there any way I can advise python-mode to ignore indentation rules within docstrings?

Phill Oldham
  • 227
  • 1
  • 9

2 Answers2

2

Is there any way I can advise python-mode to ignore indentation rules within docstrings?

Yes, in Emacs 25.1 or greater (before that python-indent-context didn't distinguish string from docstring). Indentation works by setting indent-line-function to a mode-specific value:

indent-line-function is a variable defined in ‘indent.el’.
Its value is ‘python-indent-line-function’
Local in buffer foo.py; global value is indent-relative

  This variable may be risky if used as a file-local variable.

Documentation:
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.

You can advise python-indent-line like this:

(defun my-python-noindent-docstring (&optional _previous)
  (if (eq (car (python-indent-context)) :inside-docstring)
      'noindent))

(advice-add 'python-indent-line :before-until #'my-python-noindent-docstring)

Actually, you could technically do it without advice as such, by setting indent-line-function:

(defun my-python-indent-line ()
  (if (eq (car (python-indent-context)) :inside-docstring)
      'noindent
    (python-indent-line)))

(defun my-python-mode-hook ()
  (setq indent-line-function #'my-python-indent-line))
(add-hook 'python-mode-hook #'my-python-mode-hook)
npostavs
  • 9,033
  • 1
  • 21
  • 53
  • Instead of `'noindent` you can actually use any function. For me `(insert-tab)` Also works well. Thou the indentation is not smart btu for Writing doc-strings is also fine. – mfcabrera Jan 24 '18 at 10:34
  • When the buffer-local `indent-line-function` returns `noindent`, Emacs calls the global default value, which is `indent-relative`. You could also do `(setq-default indent-line-function #'insert-tab)` if you prefer. – npostavs Jan 24 '18 at 13:31
0

As far as I know, there's no simple way of disabling the indentation engine inside a doc-string. However, you can use various tools like mmm-mode to enable a different major-mode inside certain parts of the current buffer.

E.g., you can enable rst-mode inside docstrings and thus use the rst-mode indentation engine instead.

I answered a similar question to this some time ago with all the configuration details are available here: https://emacs.stackexchange.com/a/21087/2653

Xaldew
  • 1,181
  • 9
  • 20