为现代 Fortran 更新 NEdit 中的语法高亮

Updating syntax highliting in NEdit for modern Fortran

我通常使用 NEdit 并有一个文件可以突出显示常用的 Fortran 语言。

我试图添加一些缺失的关键字,如 DEALLOCATE、CONTIGUOUS 等,但结果很糟糕。我在这里使用示例:https://groups.google.com/forum/#!topic/comp.lang.fortran/D8JtR7m53z4

有没有人有更新版 NEdit for F90+ 的好链接?

亮点是在第 308 行附近将 Fortran90 放在 Fortran 之前。!?OMP 仍然有问题,但工作得很好,我对 Fortran 内在函数使用 CAPS,对大多数变量、子例程和函数使用 CamelCase...

! Preferences file for NEdit
!
! This file is overwritten by the "Save Defaults..." command in NEdit 
! and serves only the interactively settable options presented in the NEdit
! "Preferences" menu.  To modify other options, such as key bindings, use 
! the .Xdefaults file in your home directory (or the X resource 
! specification method appropriate to your system).  The contents of this 
! file can be moved into an X resource file, but since resources in this file
! override their corresponding X resources, either this file should be 
! deleted or individual resource lines in the file should be deleted for the
! moved lines to take effect.

nedit.fileVersion: 5.5
nedit.shellCommands: \
    spell:Alt+B:s:ED:\n\
        (cat;echo "") | spell\n\
    wc::w:ED:\n\
        wc | awk '{print  " lines, "  " words, "  " characters"}'\n\
    sort::o:EX:\n\
        sort\n\
    number lines::n:AW:\n\
        nl -ba\n\
    make:Alt+Z:m:W:\n\
        make\n\
    expand::p:EX:\n\
        expand\n\
    unexpand::u:EX:\n\
        unexpand\n
nedit.macroCommands: \
    Complete Word:Alt+D::: {\n\
        # Tuning parameters\n\
        ScanDistance = 200\n\
        \n\
        # Search back to a word boundary to find the word to complete\n\
        startScan = max(0, $cursor - ScanDistance)\n\
        endScan = min($text_length, $cursor + ScanDistance)\n\
        scanString = get_range(startScan, endScan)\n\
        keyEnd = $cursor-startScan\n\
        keyStart = search_string(scanString, "<", keyEnd, "backward", "regex")\n\
        if (keyStart == -1)\n\
            return\n\
        keyString = "<" substring(scanString, keyStart, keyEnd)\n\
        \n\
        # search both forward and backward from the cursor position.  Note that\n\
        # using a regex search can lead to incorrect results if any of the special\n\
        # regex characters is encountered, which is not considered a delimiter\n\
        backwardSearchResult = search_string(scanString, keyString, keyStart-1, \\n\
                "backward", "regex")\n\
        forwardSearchResult = search_string(scanString, keyString, keyEnd, "regex")\n\
        if (backwardSearchResult == -1 && forwardSearchResult == -1) {\n\
            beep()\n\
            return\n\
        }\n\
        \n\
        # if only one direction matched, use that, otherwise use the nearest\n\
        if (backwardSearchResult == -1)\n\
            matchStart = forwardSearchResult\n\
        else if (forwardSearchResult == -1)\n\
            matchStart = backwardSearchResult\n\
        else {\n\
            if (keyStart - backwardSearchResult <= forwardSearchResult - keyEnd)\n\
                matchStart = backwardSearchResult\n\
            else\n\
                matchStart = forwardSearchResult\n\
        }\n\
        \n\
        # find the complete word\n\
        matchEnd = search_string(scanString, ">", matchStart, "regex")\n\
        completedWord = substring(scanString, matchStart, matchEnd)\n\
        \n\
        # replace it in the window\n\
        replace_range(startScan + keyStart, $cursor, completedWord)\n\
    }\n\
    Fill Sel. w/Char:::R: {\n\
        if ($selection_start == -1) {\n\
            beep()\n\
            return\n\
        }\n\
        \n\
        # Ask the user what character to fill with\n\
        fillChar = string_dialog("Fill selection with what character?", "OK", "Cancel")\n\
        if ($string_dialog_button == 2 || $string_dialog_button == 0)\n\
            return\n\
        \n\
        # Count the number of lines in the selection\n\
        nLines = 0\n\
        for (i=$selection_start; i<$selection_end; i++)\n\
            if (get_character(i) == "\n")\n\
                nLines++\n\
        \n\
        # Create the fill text\n\
        rectangular = $selection_left != -1\n\
        line = ""\n\
        fillText = ""\n\
        if (rectangular) {\n\
            for (i=0; i<$selection_right-$selection_left; i++)\n\
            line = line fillChar\n\
            for (i=0; i<nLines; i++)\n\
            fillText = fillText line "\n"\n\
            fillText = fillText line\n\
        } else {\n\
            if (nLines == 0) {\n\
                for (i=$selection_start; i<$selection_end; i++)\n\
                    fillText = fillText fillChar\n\
            } else {\n\
                startIndent = 0\n\
                for (i=$selection_start-1; i>=0 && get_character(i)!="\n"; i--)\n\
                    startIndent++\n\
                for (i=0; i<$wrap_margin-startIndent; i++)\n\
                    fillText = fillText fillChar\n\
                fillText = fillText "\n"\n\
            for (i=0; i<$wrap_margin; i++)\n\
                line = line fillChar\n\
            for (i=0; i<nLines-1; i++)\n\
                fillText = fillText line "\n"\n\
            for (i=$selection_end-1; i>=$selection_start && get_character(i)!="\n"; \\n\
                    i--)\n\
                fillText = fillText fillChar\n\
            }\n\
        }\n\
        \n\
        # Replace the selection with the fill text\n\
        replace_selection(fillText)\n\
    }\n\
    Quote Mail Reply:::: {\n\
        if ($selection_start == -1)\n\
            replace_all("^.*$", "\\> &", "regex")\n\
        else\n\
            replace_in_selection("^.*$", "\\> &", "regex")\n\
    }\n\
    Unquote Mail Reply:::: {\n\
        if ($selection_start == -1)\n\
            replace_all("(^\\> )(.*)$", "\\2", "regex")\n\
        else\n\
            replace_in_selection("(^\\> )(.*)$", "\\2", "regex")\n\
    }\n\
    Comments>/* Comment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
        selStart = $selection_start\n\
        selEnd = $selection_end\n\
        replace_range(selStart, selEnd, "/* " get_selection() " */")\n\
        select(selStart, selEnd + 6)\n\
    }\n\
    Comments>/* Uncomment */@C@C++@Java@CSS@JavaScript@Lex:::R: {\n\
        sel = get_selection()\n\
        selStart = $selection_start\n\
        selEnd = $selection_end\n\
        commentStart = search_string(sel, "/*", 0)\n\
        if (substring(sel, commentStart + 2, commentStart + 3) == " ")\n\
            keepStart = commentStart + 3\n\
        else\n\
            keepStart = commentStart + 2\n\
        keepEnd = search_string(sel, "*/", length(sel), "backward")\n\
        commentEnd = keepEnd + 2\n\
        if (substring(sel, keepEnd - 1, keepEnd) == " ")\n\
            keepEnd = keepEnd - 1\n\
        replace_range(selStart + commentStart, selStart + commentEnd, \\n\
            substring(sel, keepStart, keepEnd))\n\
        select(selStart, selEnd - (keepStart-commentStart) - \\n\
            (commentEnd - keepEnd))\n\
    }\n\
    Comments>// Comment@C@C++@Java@JavaScript:::R: {\n\
        replace_in_selection("^.*$", "// &", "regex")\n\
    }\n\
    Comments>// Uncomment@C@C++@Java@JavaScript:::R: {\n\
        replace_in_selection("(^[ \\t]*// ?)(.*)$", "\\2", "regex")\n\
    }\n\
    Comments># Comment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
        replace_in_selection("^.*$", "#&", "regex")\n\
    }\n\
    Comments># Uncomment@Perl@Sh Ksh Bash@NEdit Macro@Makefile@Awk@Csh@Python@Tcl:::R: {\n\
        replace_in_selection("(^[ \\t]*#)(.*)$", "\\2", "regex")\n\
    }\n\
    Comments>-- Comment@SQL:::R: {\n\
        replace_in_selection("^.*$", "--&", "regex")\n\
    }\n\
    Comments>-- Uncomment@SQL:::R: {\n\
        replace_in_selection("(^[ \\t]*--)(.*)$", "\\2", "regex")\n\
    }\n\
    Comments>! Comment@X Resources:::R: {\n\
        replace_in_selection("^.*$", "!&", "regex")\n\
    }\n\
    Comments>! Uncomment@X Resources:::R: {\n\
        replace_in_selection("(^[ \\t]*!)(.*)$", "\\2", "regex")\n\
    }\n\
    Comments>% Comment@LaTeX:::R: {\n\
                        replace_in_selection("^.*$", "%&", "regex")\n\
                        }\n\
    Comments>% Uncomment@LaTeX:::R: {\n\
                        replace_in_selection("(^[ \\t]*%)(.*)$", "\\2", "regex")\n\
                        }\n\
    Comments>Bar Comment@C:::R: {\n\
        if ($selection_left != -1) {\n\
            dialog("Selection must not be rectangular")\n\
            return\n\
        }\n\
        start = $selection_start\n\
        end = $selection_end-1\n\
        origText = get_range($selection_start, $selection_end-1)\n\
        newText = "/*\n" replace_in_string(get_range(start, end), \\n\
            "^", " * ", "regex") "\n */\n"\n\
        replace_selection(newText)\n\
        select(start, start + length(newText))\n\
    }\n\
    Comments>Bar Uncomment@C:::R: {\n\
        selStart = $selection_start\n\
        selEnd = $selection_end\n\
        newText = get_range(selStart+3, selEnd-4)\n\
        newText = replace_in_string(newText, "^ \\* ", "", "regex")\n\
        replace_range(selStart, selEnd, newText)\n\
        select(selStart, selStart + length(newText))\n\
    }\n\
    Make C Prototypes@C@C++:::: {\n\
        if ($selection_start == -1) {\n\
            start = 0\n\
            end = $text_length\n\
        } else {\n\
            start = $selection_start\n\
            end = $selection_end\n\
        }\n\
        string = get_range(start, end)\n\
        nDefs = 0\n\
        searchPos = 0\n\
        prototypes = ""\n\
        staticPrototypes = ""\n\
        for (;;) {\n\
            headerStart = search_string(string, \\n\
                "^[a-zA-Z]([^;#\"'{}=><!/]|\n)*\\)[ \t]*\n?[ \t]*\\{", \\n\
                searchPos, "regex")\n\
            if (headerStart == -1)\n\
            break\n\
            headerEnd = search_string(string, ")", $search_end,"backward") + 1\n\
            prototype = substring(string, headerStart, headerEnd) ";\n"\n\
            if (substring(string, headerStart, headerStart+6) == "static")\n\
            staticPrototypes = staticPrototypes prototype\n\
            else\n\
                        prototypes = prototypes prototype\n\
            searchPos = headerEnd\n\
            nDefs++\n\
        }\n\
        if (nDefs == 0) {\n\
            dialog("No function declarations found")\n\
            return\n\
        }\n\
        new()\n\
        focus_window("last")\n\
        replace_range(0, 0, prototypes staticPrototypes)\n\
    }\n
nedit.bgMenuCommands: \
    Undo:::: {\n\
        undo()\n\
    }\n\
    Redo:::: {\n\
        redo()\n\
    }\n\
    Cut:::R: {\n\
        cut_clipboard()\n\
    }\n\
    Copy:::R: {\n\
        copy_clipboard()\n\
    }\n\
    Paste:::: {\n\
        paste_clipboard()\n\
    }\n

nedit.highlightPatterns: Ada:Default\n\
    Awk:Default\n\
    C++:Default\n\
    C:Default\n\
    CSS:Default\n\
    Csh:Default\n\
    Fortran:Default\n\
    Fortran90:1:30{\n\
    Continuation:"&":::Flag::\n\
    String:"'":"'":"\n([^ \t]| [^ \t]|  [^ \t]|   [^ \t]|    [^ \t]|     [ \t0]| *\t[^1-9])":String::\n\
    Keywords:"<(LT|GT|EQ|AND|OR|ACCEPT|[Aa]ccept|ASSIGN|[Aa]ssign|AUTOMATIC|[Aa]utomatic|BACKSPACE|[Bb]ackspace|BLOCK|[Bb]lock|CALL|[Cc]all|CLOSE|[Cc]lose|COMMON|[Cc]ommon|CONTINUE|[Cc]ontinue|DATA|[Dd]ata|DECODE|[Dd]ecode|DELETE|[Dd]elete|DIMENSION|[Dd]imension|DO|[Dd]o|ELSE|[Ee]lse|ELSEIF|[Ee]lseif|ENCODE|[Ee]ncode|ENDFILE|[Ee]nd[Ff]ile|ENDFILE|[Ee]ndfile|END|[Ee]nd|ENDIF|[Ee]ndif|ENTRY|[Ee]ntry|EQUIVALENCE|[Ee]quivalence|EXIT|[Ee]xit|EXTERNAL|[Ee]xternal|FORMAT|[Ff]ormat|FUNCTION|[Ff]unction|GOTO|[Gg]oto|IF|[Ii]f|IMPLICIT|[Ii]mplicit|INCLUDE|[Ii]nclude|INQUIRE|[Ii]nquire|INTRINSIC|[Ii]ntrinsic|LOGICAL|[Ll]ogical|MAP|[Mm]ap|NONE|[Nn]one|ON|[Oo]n|OPEN|[Oo]pen|PARAMETER|[Pp]arameter|PAUSE|[Pp]ause|POINTER|[Pp]ointer|PRINT|[Pp]rint|PROGRAM|[Pp]rogram|READ|[Rr]ead|RECORD|[Rr]ecord|RETURN|[Rr]eturn|REWIND|[Rr]ewind|SAVE|[Ss]ave|STATIC|[Ss]tatic|STOP|[Ss]top|STRUCTURE|[Ss]tructure|SUBROUTINE|[Ss]ubroutine|SYSTEM|[Ss]ystem|THEN|[Tt]hen|TO|[Tt]o|TYPE|[Tt]ype|UNION|[Uu]nion|MAP|UNLOCK|[Uu]nlock|VIRTUAL|[Vv]irtual|VOLATILE|[Vv]olatile|WHILE|[Ww]hile|WRITE|[Ww]rite)>":::Keyword::D\n\
    Data Types:"<(BYTE|[Bb]yte|CHARACTER|[Cc]haracter|COMPLEX|[Cc]omplex|DOUBLE COMPLEX|[Dd]ouble *[Cc]omplex|DOUBLE *PRECISION|[Dd]ouble [Pp]recision|DOUBLE|[Dd]ouble|INTEGER|[Ii]nteger|REAL|[Rr]eal)(\*[0-9]+)?>":::Keyword::D\n\
    F90 Keywords:"<('!'DIR'$'|DIR|OMP|DEC|EQV|NEQV|KIND|SIMD|PARALLEL OFF|PARALLEL ON|ALLOCATABLE|[Aa]llocatable|ALLOCATE|[Aa]llocate|CASE|[Cc]ase|CASE|[Cc]ase|CONTAINS|CONTIGUOUS|[Cc]ontiguous|[Cc]ontains|CYCLE|[Cc]ycle|DEALLOCATE|[Dd]eallocate|ELSEWHERE|[Ee]lsewhere|ENDWHERE|[Ee]ndwhere|INTENT|[Ii]ntent|INTERFACE|[Ii]nterface|MODULE|[Mm]odule|NAMELIST|[Nn]amelist|OPTIONAL|[Oo]ptional|PRIVATE|[Pp]rivate|PROCEDURE|[Pp]rocedure|PUBLIC|[Pp]ublic|REWRITE|[Rr]ewrite|SELECT|[Ss]elect|USE|[Uu]se|WHERE|[Ww]here)>":::Keyword::D\n\
    Numeric const:"<[0-9]+(\.[0-9]*)?([DEde][-+]?[0-9]*)?|\.[0-9]+([DEde][-+]?[0-9]*)?>":::Numeric Const::D\n\
    Comment:"! ":"$"::Comment::\n\
        }\n\
    Java:Default\n\
    JavaScript:Default\n\
    LaTeX:Default\n\
    Lex:Default\n\
    Makefile:Default\n\
    Matlab:Default\n\
    NEdit Macro:Default\n\
    Pascal:Default\n\
    Perl:Default\n\
    PostScript:Default\n\
    Python:Default\n\
    Regex:Default\n\
    SGML HTML:Default\n\
    SQL:Default\n\
    Sh Ksh Bash:Default\n\
    Tcl:Default\n\
    VHDL:Default\n\
    Verilog:Default\n\
    XML:Default\n\
    X Resources:Default\n\
    Yacc:Default
nedit.languageModes:    Ada:.ada .ad .ads .adb .a:::::::\n\
    Awk:.awk:::::::\n\
    C++:.cc .hh .C .H .i .cxx .hxx .cpp .c++::::::".,/\`'!|@#%^&*()-=+{}[]"":;<>?~":\n\
    C:.c .h::::::".,/\`'!|@#%^&*()-=+{}[]"":;<>?~":\n\
    CSS:css::Auto:None:::".,/\`'!|@#%^&*()=+{}[]"":;<>?~":\n\
    Csh:.csh .cshrc .login .logout:"^[ \t]*#[ \t]*![ \t]*/bin/csh"::::::\n\
    Fortran90:.f90 .f03 .f08 .F90 .F03 .F08:::::::\n\
    Fortran:.f .f77 .for :::::::\n\
    Java:.java:::::::\n\
    JavaScript:.js:::::::\n\
    LaTeX:.tex .sty .cls .ltx .ins:::::::\n\
    Lex:.lex:::::::\n\
    Makefile:Makefile makefile .gmk:::None:8:8::\n\
    Matlab:.m .oct .sci:::::::\n\
    NEdit Macro:.nm .neditmacro:::::::\n\
    Pascal:.pas .p .int:::::::\n\
    Perl:.pl .pm .p5 .PL:"^[ \t]*#[ \t]*!.*perl":Auto:None:::".,/\\`'!$@#%^&*()-=+{}[]"":;<>?~|":\n\
    PostScript:.ps .eps .epsf .epsi:"^%!":::::"/%(){}[]<>":\n\
    Python:.py:"^#!.*python":Auto:None:::"!""#$%&'()*+,-./:;<=>?@[\\]^`{|}~":\n\
    Regex:.reg .regex:"\(\?[:#=!iInN].+\)":None:Continuous::::\n\
    SGML HTML:.sgml .sgm .html .htm:"\<[Hh][Tt][Mm][Ll]\>"::::::\n\
    SQL:.sql:::::::\n\
    Sh Ksh Bash:.sh .bash .ksh .profile .bashrc .bash_logout .bash_login .bash_profile:"^[ \t]*#[ \t]*![ \t]*/.*bin/(bash|ksh|sh|zsh)"::::::\n\
    Tcl:.tcl .tk .itcl .itk::Smart:None::::\n\
    VHDL:.vhd .vhdl .vdl:::::::\n\
    Verilog:.v:::::::\n\
    XML:.xml .xsl .dtd:"\<(?i\?xml|!doctype)"::None:::"<>/=""'()+*?|":\n\
    X Resources:.Xresources .Xdefaults .nedit:"^[!#].*([Aa]pp|[Xx]).*[Dd]efaults"::::::\n\
    Yacc:.y::::::".,/\`'!|@#%^&*()-=+{}[]"":;<>?~":
nedit.styles:   Plain:black:Plain\n\
    Comment:gray20:Italic\n\
    Keyword:black:Bold\n\
    Storage Type:brown:Bold\n\
    Storage Type1:saddle brown:Bold\n\
    String:darkGreen:Plain\n\
    String1:SeaGreen:Plain\n\
    String2:darkGreen:Bold\n\
    Preprocessor:RoyalBlue4:Plain\n\
    Preprocessor1:blue:Plain\n\
    Character Const:darkGreen:Plain\n\
    Numeric Const:darkGreen:Plain\n\
    Identifier:brown:Plain\n\
    Identifier1:RoyalBlue4:Plain\n\
    Identifier2:SteelBlue:Plain\n\
    Subroutine:brown:Plain\n\
    Subroutine1:chocolate:Plain\n\
    Ada Attributes:plum:Bold\n\
    Label:red:Italic\n\
    Flag:red:Bold\n\
    Text Comment:SteelBlue4:Italic\n\
    Text Key:VioletRed4:Bold\n\
    Text Key1:VioletRed4:Plain\n\
    Text Arg:RoyalBlue4:Bold\n\
    Text Arg1:SteelBlue4:Bold\n\
    Text Arg2:RoyalBlue4:Plain\n\
    Text Escape:gray30:Bold\n\
    LaTeX Math:darkGreen:Plain\n\
    Pointer:#660000:Bold\n\
    Regex:#009944:Bold\n\
    Warning:brown2:Italic
nedit.smartIndentInit:  C:Default\n\
    C++:Default\n\
    Python:Default\n\
    Matlab:Default
nedit.smartIndentInitCommon: Default
nedit.autoWrap: Newline
nedit.wrapMargin: 0
nedit.autoIndent: Auto
nedit.autoSave: True
nedit.openInTab: True
nedit.saveOldVersion: False
nedit.showMatching: Delimiter
nedit.matchSyntaxBased: True
nedit.highlightSyntax: True
nedit.backlightChars: False
nedit.searchDialogs: False
nedit.beepOnSearchWrap: False
nedit.retainSearchDialogs: False
nedit.searchWraps: True
nedit.stickyCaseSenseButton: True
nedit.repositionDialogs: True
nedit.autoScroll: False
nedit.appendLF: True
nedit.sortOpenPrevMenu: True
nedit.statisticsLine: False
nedit.iSearchLine: False
nedit.sortTabs: False
nedit.tabBar: True
nedit.tabBarHideOne: True
nedit.toolTips: True
nedit.globalTabNavigate: False
nedit.lineNumbers: False
nedit.pathInWindowsMenu: True
nedit.warnFileMods: True
nedit.warnRealFileMods: True
nedit.warnExit: True
nedit.searchMethod: Literal
nedit.textRows: 24
nedit.textCols: 80
nedit.tabDistance: 8
nedit.emulateTabs: 0
nedit.insertTabs: True
nedit.textFont: -*-courier-medium-r-normal--*-120-*-*-*-iso8859-1
nedit.boldHighlightFont: -*-courier-bold-r-normal--*-120-*-*-*-iso8859-1
nedit.italicHighlightFont: -*-courier-medium-o-normal--*-120-*-*-*-iso8859-1
nedit.boldItalicHighlightFont: -*-courier-bold-o-normal--*-120-*-*-*-iso8859-1
nedit.textFgColor: black
nedit.textBgColor: rgb:e5/e5/e5
nedit.selectFgColor: black
nedit.selectBgColor: rgb:cc/cc/cc
nedit.hiliteFgColor: white
nedit.hiliteBgColor: red
nedit.lineNoFgColor: black
nedit.cursorFgColor: black
nedit.smartTags: True
nedit.prefFileRead: True
nedit.titleFormat: {%c} [%s] %f (%S) - %d

因此它需要为小写和 CamelCase 做更多的工作,但它工作得很好。