vim-python / python-syntax

Python syntax highlighting for Vim
MIT License
438 stars 84 forks source link

Allow multiline strings to be rendered as comments #57

Closed wmvanvliet closed 7 months ago

wmvanvliet commented 5 years ago

Picking this up from #45

So, docstrings are an important part of Python code and one may wish to render them as comments instead of normal strings. However, differentiating when a multiline string is being used as a docstring and when not, is tricky and probably slow.

In absence of a perfect solution, I propose the following. We split out multiline strings into their own class pythonMultiString. By default, it is linked to String like we do with so many other string types:

highlight link pythonMultiString String

So, nothing changes out of the box.

However, if users want to assume all multiline strings are docstrings, they can add this to their configs:

highlight link pythonMultiString Comment

and everyone can be happy.

nfnty commented 4 years ago

Highlighting all multiline strings as comments seems really strange to me. Not sure about this, since it adds complexity and possibly making highlighting less performant.

Also, there are a few string groups that haven't been split into multiline yet in this PR.

wmvanvliet commented 4 years ago

Highlighting all multiline strings as comments seems really strange to me.

And for me, not highlighting docstrings as comments looks weird in most colorschemes. I work a lot on data analysis code and docstrings spanning 50 lines are common.

Hence a user configurable variable to turn it on/off depending on your preference.

nfnty commented 4 years ago

I understand the docstring usecase, but like I said highlighting all multiline strings as comments is weird and hacky.

naught101 commented 3 years ago

I think the solution here is quite useful: https://stackoverflow.com/a/43001535/210945

syn region pythonDocString start=+^\s*"""+ end=+"""+ keepend contains=...

It doesn't match all multi-line strings, only ones that fall at the start of a line (e.g. not directly following an assignment).

This will false-positively catch multi-line strings that fall inside parentheses where the string starts on a new line. I think that those cases are negligibly rare though, I think it would be worth including.

adigitoleo commented 3 years ago

@naught101 I think it's a little more complicated, because of optional string prefices (e.g. r"""). For example, I currently use the following snippet in .config/nvim/after/syntax/python.vim to enable docstring folding:

syn region  pythonString matchgroup=pythonTripleQuotes
      \ start=+[uU]\=\z('''\|"""\)+ skip=+\\["']+ end="\z1" keepend
      \ contains=pythonEscape,pythonSpaceError,pythonDoctest,@Spell
      \ fold
syn region  pythonRawString matchgroup=pythonTripleQuotes
      \ start=+[uU]\=[rR]\z('''\|"""\)+ end="\z1" keepend
      \ contains=pythonSpaceError,pythonDoctest,@Spell
      \ fold

I think it comes from this SO post originally.

naught101 commented 3 years ago

That seems irrelevant to me.. why would anyone use unicode or raw string types as docscrings?

The key thing is that docstrings are always at the start of the line, and not part of an expression. And they should be marked differently to normal multiline strings, because they are used differently.

adigitoleo commented 3 years ago

After further consideration I think you're right. Better to use the simpler regex, and it's true I've never used raw or unicode for docstrings (I think I've seen it only once).

There are still some people who use triple single quotes (not me), but I suppose it's not recommended so overall I'm fine with start=+^\s*"""+ end=+"""+. And I agree that this would be nice to have (maybe even with support for folding...)

Anyway, thanks for pointing me to a better SO answer :)

wmvanvliet commented 7 months ago

Closing in favor of #83