% % Fortran mode for jed % % Loading this file, then executing 'fortran' will start fortran mode % on the current buffer. The only keys that get remapped are: % ^M (return) which runs the fortan newline command % ^I (tab) which indents the current line % ^[; (escape semicolon) runs the fortran comment command % ^[: (escape colon) runs fortran uncomment command % ^[^M : start a continuation line !if (is_defined ("Fortran_Continue_Char")) { variable Fortran_Continue_Char = "&"; % default continuation char } !if (is_defined ("Fortran_Comment_String")) { variable Fortran_Comment_String = "C "; } !if (is_defined ("Fortran_Indent_Amount")) { variable Fortran_Indent_Amount = 2; } % gotobeginning of line and skip past continuation char define fortran_skip_label () { bol (); skip_chars ("0-9 \t"); if (looking_at(Fortran_Continue_Char)) go_right(1); skip_white (); } % computes fortran indent define fortran_get_indent () { variable col = 7; %/* at top of buffer it should be 7 n'est pas? */ variable case = CASE_SEARCH; CASE_SEARCH = 0; push_spot (); while (up(1)) { bol (); skip_white(); if (eolp() or looking_at(Fortran_Continue_Char)) continue; fortran_skip_label (); col = what_column (); if (col == 1) continue; if (looking_at("do ") or looking_at("else")) col += Fortran_Indent_Amount; else if (looking_at("if ") or looking_at("if(")) { if (ffind ("then")) col += Fortran_Indent_Amount; } break; } % now check current line pop_spot (); push_spot (); fortran_skip_label (); if (looking_at("end") or looking_at("continue") or looking_at("else")) col -= Fortran_Indent_Amount; if (col < 7) col = 7; pop_spot (); CASE_SEARCH = case; col; } % used below-- skips range % assumes we are after the label or continuation char % and indents the rest to goal define fortran_tough_indent (goal) { skip_chars ("0-9"); trim (); if (looking_at (Fortran_Continue_Char)) { insert_spaces (6 - what_column()); go_right(1); trim(); goal += Fortran_Indent_Amount; } insert_spaces (goal - what_column()); } % fortran indent routine define fortran_indent () { variable col, ch, n, goal; push_spot (); goal = fortran_get_indent (); bol (); skip_white (); col = what_column (); switch (char(what_char())) { isdigit (()) : % label if (col >= 6) { bol (); trim (); insert_single_space (); } fortran_tough_indent (goal); } { not(strcmp(Fortran_Continue_Char, ())) : % continuation character bol (); trim (); insert (" "); fortran_tough_indent (goal); } { pop (); not (bolp()) or eolp (): % general case bol (); trim (); goal--; insert_spaces (goal); } pop_spot (); skip_white (); } define fortran_newline () { variable p, cont; fortran_indent (); push_spot (); bskip_chars (" \t"); trim(); if (what_column () > 72) { push_spot (); bol(); skip_white(); !if (bolp()) message ("Line exceeds 72 columns."); pop_spot (); } p = POINT; bskip_chars("-+*=/,.("); cont = (p != POINT); pop_spot (); newline (); insert_single_space (); if (cont) insert(Fortran_Continue_Char); fortran_indent (); } define fortran_continue_newline () { fortran_newline (); push_spot (); bol (); skip_white (); if (looking_at(Fortran_Continue_Char)) pop_spot (); else { insert (Fortran_Continue_Char); pop_spot (); fortran_indent (); go_right(1); skip_white (); } } % % electric labels % define fortran_electric_label () { variable ch, col; insert_char (LAST_CHAR); push_spot (); bol (); skip_white (); % test for comment if (bolp ()) pop_spot (); else { skip_chars ("0-9"); trim (); pop_spot (); fortran_indent (); } } % fortran comment/uncomment functions define fortran_is_comment () { bol (); skip_chars (" \t0-9"); bolp () and not (eolp()); } define fortran_uncomment () { push_spot (); if (fortran_is_comment ()) { bol (); if (looking_at (Fortran_Comment_String)) deln (strlen (Fortran_Comment_String)); else del (); } fortran_indent (); pop_spot (); go_down (1); } define fortran_comment () { !if (fortran_is_comment ()) { push_spot (); bol (); insert (Fortran_Comment_String); } pop_spot (); go_down(1); } % % main entry point into the fortran mode % !if (is_defined("Fortran_Mode")) { variable Fortran_Mode = "Fortran"; make_keymap (Fortran_Mode); definekey ("fortran_newline", "^M", Fortran_Mode); definekey ("fortran_indent", "^I", Fortran_Mode); definekey ("fortran_comment", "^[;", Fortran_Mode); definekey ("fortran_uncomment", "^[:", Fortran_Mode); definekey ("fortran_continue_newline", "^[^M", Fortran_Mode); definekey ("self_insert_cmd", "'", Fortran_Mode); definekey ("self_insert_cmd", "\"", Fortran_Mode); _for (0, 9, 1,) { =$1; definekey ("fortran_electric_label", string($1), Fortran_Mode); } } %!% Mode designed for the purpose of editing FORTRAN files. %!% After the mode is loaded, the hook 'fortran_hook' is called. %!% Useful functions include %!% %!% Function: Default Binding: %!% fortran_indent TAB %!% fortran_newline RETURN %!% indents current line, inserts newline and indents it. %!% fortran_continue_newline ESC RETURN %!% indents current line, and creates a continuation line on next line. %!% fortran_comment ESC ; %!% comments out current line %!% fortran_uncomment ESC : %!% uncomments current line %!% fortran_electric_label 0-9 %!% Generates a label for current line or simply inserts a digit. %!% %!% Variables include: %!% Fortran_Continue_Char --- character used as a continuation character. %!% By default, its value is "&" %!% Fortran_Comment_String --- string used by 'fortran_comment' to %!% comment out a line. The default string is "C "; %!% Fortran_Indent_Amount --- number of spaces to indent statements in %!% a block. The default is 2. define fortran () { use_keymap (Fortran_Mode); setmode (Fortran_Mode, 4); runhooks ("fortran_hook"); }