fortran-lang / fprettify

auto-formatter for modern fortran source code
https://pypi.python.org/pypi/fprettify
Other
370 stars 76 forks source link

Add feature with parser that also indents preprocessor directives #87

Closed helmutwecke closed 3 years ago

helmutwecke commented 3 years ago

Hello @pseewald

I added a new feature for the preprocessor directives (#:), which indents them as normal code when its parser is True. The other fypp preprocessors are unchanged. When the parser is False (default) fprettify functions the same way as before. This functionality was added by request of @aradi who is interested in using fprettify with this new feature.

Best regards, Helmut Wecke

pseewald commented 3 years ago

Awesome! Could you add a test?

helmutwecke commented 3 years ago

Hello, I have already added the test for the fypp-preprocessor indenting

pseewald commented 3 years ago

I wonder why the indentation is restricted to #: directives, why not extend it also to $: and @:?

pseewald commented 3 years ago

A last comment: indenting fypp statements may lead to inconsistent indentation such as the example reported in #89:

#:if worktype
      ${worktype}$, &
#:else
      ${type}$, &
#:endif
         DIMENSION(${arr_exp}$), &
         POINTER :: work

becoming

#:if worktype
      ${worktype}$, &
         #:else
         ${type}$, &
         #:endif
         DIMENSION(${arr_exp}$), &
         POINTER :: work

I'll merge this feature as an option (as you proposed) but I don't think this should be default.

aradi commented 3 years ago

@pseewald Let me understand before the merge: Why would that strange indentation occur? (This is definitely not, what were intenting...). What I'd like to see is:

  print *, "Hello"
  #:if SOME_COND
     print *, "SOME_COND"
  #:else
     print *, "NOT SOME_COND"
  #:endif

If this can not be robustly achieved, than it is better probably not to care about the Fypp-stuff at all...

As for the restriction: on #:for and #:if: We only wanted to use the for those Fypp block constructs (with a corresponding #:end) which often occur embedded in normal Fortran source code.

pseewald commented 3 years ago

I think getting the corner cases right will be difficult, already now we have issues like #89 and this will only get more complicated if we extend indentation rules to fypp.

If you still think it's worth it, the Fortran line parser InputStream class would need to be adapted as it currently ignores fypp statements.

helmutwecke commented 3 years ago

Hello,

I have uploaded the code that is able to do this functionality. For this I had to change the NOTFORTRAN_LINE_RE in fparse_utils.py. I think this does not affect the original functionality, but please check if I am right.

pseewald commented 3 years ago

Perfect! Except for some corner cases that will be formatted in a strange way, this seems to be a good enough solution. I'll test and merge this next week.

helmutwecke commented 3 years ago

Great! I did not new if it would affect something, this is why I tried with the previous commits. I am happy this is a good enough solution.

pseewald commented 3 years ago

I worked towards making this feature stable and there should be no problems anymore. It's enabled by default.