Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding reStructuredText in Python docstrings

I'd like to see some nice syntax highlighting and colouring in my Python's docstrings which (of course) are valid RESt. For example:

'''
A section
=========

an example::

    some code
'''
rest of python code

The closest I've got is this in my .vim/after/syntax/python.vim:

syn include syntax/rst.vim 
syn region pythonDocstring  start=+^\s*'''+ end=+'''+ contained

According to the documentation of syntax-include that should be sufficient to. Also note that rst.vim re-defines a bunch of python entities so I've had to comment out all sections related to code:

" syn region rstCodeBlock contained matchgroup=rstDirective
"       \ start=+\%(sourcecode\|code\%(-block\)\=\)::\_s*\n\ze\z(\s\+\)+
"       \ skip=+^$+
"       \ end=+^\z1\@!+
"       \ contains=@NoSpell
" syn cluster rstDirectives add=rstCodeBlock

" if !exists('g:rst_syntax_code_list')
[...]

Lastly, I can't use !runtime because rst.vim does nothing if the b:current_syntax variable is already defined:

if exists("b:current_syntax")
  finish
endif

Despite my efforts my docstring stays the same colour as other comments, with no syntax highlighting.

I've tried also this:

syn region pythonDocstring  start=+^\s*'''+ end=+'''+ contains=CONTAINED

But I only managed to change the colour of the block to be Special rather than Comment.

Perhaps I should define the pythonDocstring not to have any default colouring?

Further note: if I remove references to python raw strings in python.vim, colouring disappears but I only get the python keywords highlighted.


Update

Trying one of the solutions below with my after/syntax/python.vim file:

syn include @pythonRst syntax/rst.vim 
syn region pythonDocstring  start=+^\s*'''+ end=+'''+ contains=@pythonRst

Resulted in the RESt file being grayed out when opening a file with .py extension:

python syntax

While opening the same file with a .rst. extension seems to work fine (just to show that I have a rest syntax file):

rest syntax

Note that I've tried both with and without colorscheme in my .vimrc

like image 401
lorenzog Avatar asked Nov 05 '15 17:11

lorenzog


People also ask

How do you use Docstrings in Python?

Declaring Docstrings: The docstrings are declared using ”'triple single quotes”' or “””triple double quotes””” just below the class, method or function declaration. All functions should have a docstring.

Should I use Docstrings in Python?

Using docstrings, Python developers can provide a simple explanation of what a function or class is used for. Without such documentation, it would be very difficult—if not impossible—to learn new Python modules. Docstrings can also be used to generate API's (Application Programming Interfaces).

What should be included in Docstrings?

The docstrings for Python Modules should list all the available classes, functions, objects and exceptions that are imported when the module is imported. They should also have a one-line summary for each item.

Where do you put Docstrings?

Module docstrings are placed at the top of the file even before any imports. Module docstrings should include the following: A brief description of the module and its purpose. A list of any classes, exception, functions, and any other objects exported by the module.


2 Answers

I've finally managed to crack it.

Firstly I copied the rst.vim file from $VIMRUNTIME/syntax into my .vim/syntax/ folder

Secondly, this is my .vim/after/syntax/python.vim file (thanks @Ingo):

syn include @pythonRst syntax/rst.vim 
syn region pythonDocstring  start=+^\s*"""+ end=+"""+ contains=@pythonRst

Thirdly I edited the file and commented out this block to ignore whether current syntax is set:

if exists("b:current_syntax")
  finish
endif

This block to load code plugins (it was causing some recursive problem because it was trying to load a python syntax file, which loaded this syntax file:

for code in g:rst_syntax_code_list
    unlet! b:current_syntax
[...]
   unlet! prior_isk
endfor

And finally this block at the end:

let b:current_syntax = "rst"

So that the syntax would stay as python.

Result:

success!

like image 38
lorenzog Avatar answered Sep 29 '22 12:09

lorenzog


As the reST syntax should only be applied inside Python doc strings, you have to include them into a syntax cluster (here: @pythonRst). Otherwise, Vim would try to match them everywhere.

syn include @pythonRst syntax/rst.vim

Then, define a region covering those doc strings, and explicitly instruct Vim to highlight reST syntax in there (via contains=)

syn region pythonDocstring  start=+^\s*'''+ end=+'''+ contains=@pythonRst
like image 106
Ingo Karkat Avatar answered Sep 29 '22 13:09

Ingo Karkat