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?

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)
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.