Custom functions list rules



  • Hello everyone,

    I am trying to create functions list rules for Fortran 90 as it is not available by default. I am following this tutorial: http://notepad-plus-plus.org/features/function-list.html

    This is what I have done so far:

    <?xml version=“1.0” encoding=“UTF-8” ?>

    <NotepadPlus>
    <functionList>

    <associationMap>

    <association ext=".f90" id=“fortran_function”/>
    </associationMap>

    <parsers>

    <parser id=“fortran_function” displayName=“Fortran 90” commentExpr="(!.?$)">
    <function
    mainExpr="^\s
    function\s*[\w_]+\s*(.)^\send\sfunction\s[\w_]+"
    displayMode="$functionName$">
    <functionName>
    <nameExpr expr="[\w_]+"/>
    </functionName>
    </function>
    </parser>

    </parsers>
    </functionList>
    </NotepadPlus>

    A regular Fortran 90 function is something like this:
    (optional type) function my_function (optional arguments)
    some stuff
    end function my_function

    But it seems not to work…can someone tell me what I am doing wrong? (surely everything…)

    Thank you in advance.

    I apologize if the code is not clear, I don’t know how to indent or to include a code on this forum…



  • Hello Keurfon-Luu,

    I would prefer to use

    <association langID="25" id="fortran_function"/>
    

    instead of the extension. I don’t know why but it seem to work better.

    Your regex for mainExpr looks weird in the case that
    you allow whitespaces in front of the functionname only but the example
    suggests that there might be a optional type in front.

    As I don’t have any experience in fortran I need to have a full sample code with explanation
    in order to be helpful.

    I apologize if the code is not clear, I don’t know how to indent or to include a code on this forum…

    just indent with 4 or more spaces that’s it.
    I would suggest to write the question in npp and indent the code accordingly ;-D

    Cheers
    Claudia



  • Thank you for your reply.

    I used the extension and not the langID as the native Fortran syntax coloration is for old Fortran code (77). Therefore I created my own theme for Fortran 90.

    For some reasons, there are * that are not displayed (it seems it makes the text italic instead).
    The same code with indentation that displays correctly the *.

    <?xml version="1.0" encoding="UTF-8" ?>
    <NotepadPlus>
        <functionList>
            <associationMap>
                ...
                <association ext=".f90" id="fortran_function"/>
            </associationMap>
            <parsers>
                ...
                <parser id="fortran_function" displayName="Fortran 90" commentExpr="(!*.?$)">
                    <function
                        mainExpr="^\s*function\s*[\w_]+\s*\(.*\)^\s*end\s*function\s*[\w_]+"
                        displayMode="$functionName$">
                        <functionName>
                            <nameExpr expr="[\w_]+"/>
                        </functionName>
                    </function>
                </parser>
            </parsers>
        </functionList>
    </NotepadPlus>
    

    Here are two examples of Fortran functions that computes x², but written differently.

    function xsquare(x)
        real, intent(in) :: x
        real :: xsquare
        xsquare = x*x
        return
    end function xsquare
    
    real function xsquare(x)
        real, intent(in) :: x
        xsquare = x*x
        return
    end function xsquare
    

    Thank you again for your help.



  • Hello Keurfon-Luu,

            <parser id="fortran_function" displayName="Fortran 90" commentExpr="(!*.?$)">
                <function
                    mainExpr="^.*function\s+\K(.*)(?=\()"
                    displayMode="$functionName$">
                    <functionName>
                        <nameExpr expr=".+"/>
                    </functionName>
                </function>
            </parser>
    

    should do the trick.

    ^              from the start
    .*             zero or more chars followed by
    function       and followed by
    \s+            one or more whitspace chars
    \K             reset to current position
    (.*)           group of zero or more chars followed by
    (?=\()         a ( which we aren't interested in.
    

    Cheers
    Claudia



  • Thank you very much Claudia! It actually does the trick. I slightly modified your code so that it can also handle (correctly) functions ending with “result” (yeah, Fortran is quite a mess…), and subroutines.

    function xsquare(x) result(y)
        real, intent(in) :: x
        real :: y
        t = x*x
        return
    end function xsquare
    
    subroutine hello()
        print *, "Hello World!"
        return
    end subroutine hello
    

    Here is the code for the few people that are interested in coding in Fortran 90.

    <?xml version="1.0" encoding="UTF-8" ?>
    <NotepadPlus>
        <functionList>
            <associationMap>
                ...
                <association userDefinedLangName="Fortran90" id="fortran_function"/>
            </associationMap>
            <parsers>
                ...
                <parser id="fortran_function" displayName="Fortran 90" commentExpr="(!*.?$)">
                    <function
                        mainExpr="^.*(function|subroutine)\s+\K([\w]+)(?=\()"
                        displayMode="$functionName$">
                        <functionName>
                            <nameExpr expr="[\w]+"/>
                        </functionName>
                    </function>
                </parser>
            </parsers>
        </functionList>
    </NotepadPlus>
    

    Note that it did not work at all with “ext” in the association map. If one is okay with NPP’s native Fortran syntax coloration, just change the association map as suggested by Claudia.

    <association langID="25" id="fortran_function"/>
    

    Thank you again Claudia, you made my NPP almost perfect for my work. Now, I just have to find a way to include a better terminal than the console of NppExec.



  • Your welcome Keurfon,

    good to see that you have a working fortran development environment but what do
    you mean by a better terminal than the console of NppExec. ;-)
    Can there be something better??

    Cheers
    Claudia



  • I got a “fork” error when using Make. I think it may be due to Windows 10. My problem is the same as on this topic:
    http://sourceforge.net/p/npp-plugins/bugs/294/

    I still have a small issue with the function lists, and I did not manage to solve it myself. It still cannot find functions with no argument (like the hello() function described in my previous post).

    Any idea? Thank you in advance :)



  • Hello Keurfon-Luu,

    regarding the cygwin/NppExec problem I don’t have any experiance here but
    from what I read on the web (discussion between MS and cygwin devs) it seems that it isn’t easily solveable.
    And bringing NppExec inbetween seems to be another step of complexity.

    Regarding the regular expression, I assume there is a bug in function list code.
    Becasue when using the find dialog with regular expression everything
    gets found as expected. The workaround seems to be that you add an
    additional space char at the end of the function line like

    subroutine hello()__one_extra_space_char
        print *, "Hello World!"
        return
    end subroutine hello
    

    then it is found.
    Or, the problem is still between monitor and chair and I still have problems understanding regex.

    Sorry
    Claudia


Log in to reply