用 vim 写 fortran 程序

写 C/C++ 的编辑器或 IDE 非常多,能较好支持 Fortran 的编辑器则少了很多。一方面,Fortran 主要是一种科学计算语言,受众较窄,另一方面,其语法和格式有些特殊性,比如格式就有固定格式 (F77) 和自由格式 (F90/F95) 两种。

Windows 下,CVF,IVF 和 PGI 都是集成到 Microsoft Visual Stdio 中编辑和编译,Linux 下则没有现成的可视的编译环境。无论是 CVF 还是 MVS,编辑 Fortran 的能力都比较弱,高亮显示,自动匹配,自动缩进等都不能令人满意。因此,写 Fortran 程序的第一步,寻找和配置一个高效的编辑器,然后再在已有编译环境或者是配置的编译环境里进行编译,调试和运行。

Vim 和 Emacs 都自带 Fortran 的高亮和自动缩进功能,其中 Emacs 缩进功能更加完善,规范排版的效果更好,而 Vim 则存在一些小问题,如 program 和 subroutine 内没有缩进,没有环境的自动补全等。熟悉 Emacs 的可直接用 Emacs,喜欢 Vim 的需要做一点准备工作。

1、_vimrc 里加上格式匹配和语法高亮的语句

Vim配置: _vimrc
01 "fortran
02 let s:extfname = expand( "%:e")
03 if s:extfname == ? "f90"
04 let fortran_free_source = 1
05 unlet ! fortran_fixed_source
06 else
07 let fortran_fixed_source = 1
08 unlet ! fortran_free_source
09 endif
10 let fortran_more_precise = 1
11 let fortran_do_enddo = 1
12 "去掉固定格式每行开头的红色填充
13 let fortran_have_tabs = 1
14 "允许折叠
15 let fortran_fold = 1
16 let fortran_fold_conditionals = 1
17 "折叠方式
18 set foldmethod = syntax

02-09 行是根据文件后缀名匹配格式,10-11 是进行语法的缩进和高亮匹配,15-18 是允许折叠和折叠格式。这些都可以在 Vim 的帮助文件中找到。

2、安装 fortran_codecomplete.vim : Complete fortran constructs with <F7>
http://www.vim.org/scripts/script.php?script_id=2487
下载后扔到 vimfiles/ftplugin 。

3、安装
fortran.vim : Additional indentation rules for Fortran 95 and Fortran 90
http://www.vim.org/scripts/script.php?script_id=2299
下载后扔到 vimfiles/after/indent/ ,不存在文件夹的话可以自己建立。

4、修改 fortran.vim
打开第三步下载的 fortran.vim 文件,看开头部分的说明,就可以知道这个插件提供的加强缩进功能是针对 subroutine、function 和 forall 的,没有 program 和 module,只能手动添加了。看不懂代码不要紧,搜索 subroutine 所在行,照格式加上就成了。

Vim配置: fortran.vim
01 " Vim indent file
02 " Language: Fortran 95, Fortran 90 (free source form)
03 " Description: Indentation rules for continued statements and preprocessor
04 " instructions
05 " Indentation rules for subroutine, function and forall
06 " statements
07 " Installation: Place this script in the $HOME/.vim/after/indent/ directory
08 " and use it with Vim 7.1 and Ajit J. Thakkar's Vim scripts
09 " for Fortran (http://www.unb.ca/chem/ajit/)
10 " Maintainer: Sébastien Burton <sebastien.burton@gmail.com>
11 " License: Public domain
12 " Version: 0.3.1
13 " Last Change: 2008 Sep 22
14
15 " Modified indentation rules are used if the Fortran source code is free
16 " source form, else nothing is done
17 if (b :fortran_fixed_source != 1)
18 setlocal indentexpr = SebuFortranGetFreeIndent()
19 setlocal indentkeys +==~ subroutine ,=~ function ,=~ forall ,=~ program ,=~ module
20 setlocal indentkeys +==~ endsubroutine ,=~ endfunction ,=~ endforall ,=~ endprogram ,=~ endmodule
21 " Only define the functions once
22 if exists( "*SebuFortranGetFreeIndent")
23 finish
24 endif
25 else
26 finish
27 endif
28
29
30 " SebuFortranGetFreeIndent() is modified FortranGetFreeIndent():
31 " Returns the indentation of the current line
32 function SebuFortranGetFreeIndent()
33 " No indentation for preprocessor instructions
34 if getline( v:lnum) =~ '^\s*#'
35 return 0
36 endif
37 " Previous non-blank non-preprocessor line
38 let lnum = SebuPrevNonBlankNonCPP( v:lnum -1)
39 " No indentation at the top of the file
40 if lnum == 0
41 return 0
42 endif
43 " Original indentation rules
44 let ind = FortranGetIndent( lnum)
45 " Continued statement indentation rule
46 " Truth table (kind of)
47 " Symbol '&' | Result
48 " No 0 0 | 0 No change
49 " Appearing 0 1 | 1 Indent
50 " Disappering 1 0 | -1 Unindent
51 " Continued 1 1 | 0 No change
52 let result = - SebuIsFortranContStat( lnum -1 )+ SebuIsFortranContStat( lnum)
53 " One shiftwidth indentation for continued statements
54 let ind += result*& sw
55 " One shiftwidth indentation for subroutine, function and forall's bodies
56 let line = getline( lnum)
57 if line =~ ? '^\s*\(pure\|elemental\)\=\s*\(subroutine\|function\|program\|module\)' ||
58 \ line =~ ? '^\s*\(forall\)'
59 let ind += & sw
60 endif
61 if getline( v:lnum) =~ ? '^\s*end\s*\(subroutine\|function\|forall\|program\|module\)'
62 let ind -= & sw
63 endif
64 " You shouldn't use variable names begining with 'puresubroutine',
65 " 'function', 'endforall', etc. as these would make the indentation
66 " collapse: it's easier to pay attention than to implement the exceptions
67 return ind
68 endfunction
69
70 " SebuPrevNonBlankNonCPP(lnum) is modified prevnonblank(lnum):
71 " Returns the line number of the first line at or above 'lnum' that is
72 " neither blank nor preprocessor instruction.
73 function SebuPrevNonBlankNonCPP( lnum)
74 let lnum = prevnonblank( a:lnum)
75 while getline( lnum) =~ '^#'
76 let lnum = prevnonblank( lnum -1)
77 endwhile
78 return lnum
79 endfunction
80
81 " SebuIsFortranContStat(lnum):
82 " Returns 1 if the 'lnum' statement ends with the Fortran continue mark '&'
83 " and 0 else.
84 function SebuIsFortranContStat( lnum)
85 let line = getline( a:lnum)
86 return substitute( line , '!.*$' , '' , '') =~ '&\s*$'
87 endfunction

如上面的代码所示,分别在 19,20,57,61 行添加了 program 和 module。

大功告成,可以编辑一个 .f90 文件试试,插入模式下<F7>自动补全 end (end program, end subroutine, enddo等) 语句,命令行模式下,gg=G,可对程序进行规范排版,方便看其他人写的 fortran 程序。

下一步就是搭建基于 Vim 的 Fortran 编译环境了,不过 Windows 下似乎没有需求,用 CVF 或 IVF+MVS 调试比较方便。


原文地址:http://hi.baidu.com/%C8%CB%BC%E4%CA%C0%E5%D0%D2%A3%D3%CE/blog/item/3acb8f142df7660d4a90a7da.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值