在Vim中缩进Fortran代码

6

我有一个类似于以下代码的Fortran代码:

   open(2,file=filenm(i),status='unknown')
         do j=1,num_lines
            do k=1,dime
                     read(2,*) z(k)
            enddo
               if( j .ge. 1000 ) then
                     do k=1,dime
                              sumz(k)=sumz(k)+z(k)
                     enddo
                     nsteps=nsteps+1.0
               endif
         enddo
   close(2)

如您所见,缩进并不均匀,我希望有这样的效果:

   open(2,file=filenm(i),status='unknown')
          do j=1,num_lines
                 do k=1,dime
                        read(2,*) z(k)
                 enddo
                 if( j .ge. 1000 ) then
                        do k=1,dime
                               sumz(k)=sumz(k)+z(k)
                        enddo
                        nsteps=nsteps+1.0
                 endif
          enddo
   close(2)

我可以逐行修正缩进,但代码比较大。 感谢任何评论。


2
就我个人而言,我不认为第一个do循环应该缩进。打开/关闭对并不是您应该期望任何自动缩进器识别的结构。此外,Emacs内置的Fortran模式可以很好地完成这项工作。 - agentp
4个回答

5
我曾经尝试过在vim中实现Fortran缩进的类似过程。虽然仍不完美,但我已经取得了一些进展。arutaku发布的脚本(http://www.vim.org/scripts/script.php?script_id=2299)是我的起点,但你需要确保在vimrc中有filetype plugin indent on
我还需要一个脚本来确定我是否使用固定格式或自由格式语法,因为在我的环境中我都使用。这在文档中有推荐(http://vimdoc.sourceforge.net/htmldoc/syntax.html#ft-fortran-syntax)。正如它所指定的,我将此脚本放在~/.vim/ftplugin/fortran.vim中:
let s:extfname = expand("%:e")
if s:extfname ==? "f90"
  let fortran_free_source=1
  unlet! fortran_fixed_source
else
  let fortran_fixed_source=1
  unlet! fortran_free_source
endif

我还使用一个脚本,这样我就可以按F7键自动完成某些结构:http://www.vim.org/scripts/script.php?script_id=2487。我也把它放在~/.vim/ftplugin/中。
我还在我的vimrc中加入了以下内容,以进一步改善:
let fortran_do_enddo=1
let fortran_more_precise=1
let fortran_have_tabs=1

我相信这些脚本应该与第一个脚本互动,以控制其行为,但我不确定它们是否都适用于我。我知道第一个脚本应该正确缩进do/enddo块。问题在于,由于旧式Fortran允许使用没有匹配的enddodo,因此除非您能保证不使用不匹配的“do”语句,否则脚本无法正确缩进它们。 let fortran_do_enddo=1应该是那个保证,但它似乎对我不起作用。最后一个脚本应该允许使用制表符,旧版Fortran认为这很糟糕,因此它会防止它们被标记为错误。那个看起来对我有用。老实说,我不记得中间那个脚本应该做什么或者它是否适用于我。

编辑:

我发现我的vim安装目录中有一个旧版本的第一个脚本(在我的情况下是/usr/share/vim/vim70/indent/),我没有访问权限。您可能拥有这些权限,如果它引起了问题,请覆盖或删除它。像我一样无法编辑它的人可以通过两个步骤来获取$HOME中的版本,以覆盖第一个函数。首先,我必须删除检查函数是否已存在的语句(例如if exists("*FortranGetFixedIndent")),然后我必须更改所有函数声明,通过使用!字符来强制覆盖,即function! SebuFortranGetFreeIndent()。据我所知,现在一切都大致按照我的预期工作!


2
对于在2018年阅读此内容的任何人:我通过设置“let fortran_do_enddo = 1”来解决Fortran格式问题,如上所示,在一个标准的Vim安装中-不需要外部脚本。也许脚本可以修复其他问题或更好地执行任务,只是说如果你像我一样是一个偶尔使用Fortran的程序员,并且想要修复循环缩进行为,那么这个设置可能就是你所需要的。 - Roel

2

尝试:https://sourceforge.net/projects/findent/files/

来自README:

findent:缩进/美化/转换Fortran源代码

  • findent支持Fortran-2008

  • findent可以将固定格式转换为自由格式

  • Unix和Windows的二进制文件(findent和findent.exe)

  • 可用于Unix和Windows的处理一个或多个文件的包装器(wfindent和wfindent.bat)

  • (g)vim用户:findent可以作为插件使用,使用“=”命令格式化您的编辑文件

  • 独立软件包中提供GUI前端:jfindent


仅供记录,这个答案特别好,因为它不依赖于任何其他工具(如vim及其文件)。在我看来,这是迄今为止最好的答案! - TomCho
似乎 findent 是由 Willem Vermin 编写的。这个答案应该提到这一点。 - knia

2

gg=G 能起作用吗?

gg:跳到文件顶部
=:自动缩进...
G:一直缩进到文件末尾


它不能正常工作。例如,“close(2)”停留在行首,而所有其他行都从行首缩进一个制表符。 - armando

1

我把脚本放在$HOME/.vim/after/indent/目录下。结果与gg=G类似。我认为问题可能是因为我没有Ajit J. Thakkar的Fortran Vim脚本。我下载了该脚本用于Fortran缩进,但我不知道要把它放在哪里,也就是路径。你有任何想法吗? - armando
@armando,Vim网页告诉你:安装细节 将fortran.vim文件放置在$HOME/.vim/after/indent/目录中。为了使用此脚本,您必须使用Ajit J. Thakkar的Fortran Vim脚本。它们应该已经是您Vim安装的一部分(在$VIMRUNTIME目录中)。如果没有,您可以在http://www.unb.ca/fredericton/science/chem/ajit/f_vim.htm找到它们。 干杯! - happy coder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接