Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indenting Fortran code in Vim

I have a fortran code which looks like this:

   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)

as you can see the indentation is not even, I would like to have something like this:

   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)

I can go line by line fixing the indentation but the code is kind of big. I appreciate any comment.

like image 883
armando Avatar asked Feb 06 '13 19:02

armando


People also ask

How do I indent code in Vim editor?

To indent the current line, or a visual block: ctrl-t, ctrl-d - indent current line forward, backwards (insert mode) visual > or < - indent block by sw (repeat with . ) then try hitting the F5 key while in insert mode (or just :set paste ).

Does indenting matter in Fortran?

Fortran programs are made up of the main program and modules, each can contain subroutines and functions. Indentation is not required, but is recommended. The name of the program must start with a letter, and can otherwise contain letters, numbers, and the _ (underscore) character.

Does Vim have auto indentation?

To automatically indent when editing a file in Vim, enable the auto indenting feature using the :set autoindent flag in command mode: Press Enter, and this will auto-indent the file you are currently editing. If you set the auto-indent feature in Vim in command mode, it does not persist upon closing the editor.

How do I indent multiple lines in Linux?

To tab or add the indentation at multiple lines, try “shift+dot” i.e., “.” Shortcut once. You will see it will add an indentation of one character at each selected line from the start. If you want to add indentation without stopping, then you have to try the “.” Key from the keyword after using “shift+.”.


2 Answers

I've gone through a very similar process of trying to get Fortran indenting to work in vim. I still don't have it great, but I've made some progress. The script that arutaku posted (http://www.vim.org/scripts/script.php?script_id=2299) is where I started, but you need to make sure that filetype plugin indent on is in your vimrc.

I also needed a script for determining if I was using fixed-form or free-form syntax, since in my environment I use both. This is recommended in the documentation (http://vimdoc.sourceforge.net/htmldoc/syntax.html#ft-fortran-syntax). As it specifies, I put this script in ~/.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

I also use a script so that I can press F7 to automatically complete certain constructs: http://www.vim.org/scripts/script.php?script_id=2487. I also put that in ~/.vim/ftplugin/.

I also have these in my vimrc to try to improve things further:

let fortran_do_enddo=1
let fortran_more_precise=1
let fortran_have_tabs=1

I believe those are supposed to interact with the first script to control its behavior, but I'm not convinced that they all work for me. I know the first is supposed to properly indent do/enddo blocks. The issue there is that since old-style Fortran allows a do without a matching enddo, the script can't indent them properly unless you can guarantee that you won't use unmatched 'do' statements. The let fortran_do_enddo=1 is supposed to be that guarantee, but it doesn't seem to work for me. The last one is supposed to allow usage of the tab character, which old Fortran considered bad, so it prevents them from being marked as errors. That one appears to work for me. And to be honest, I don't remember what the middle one is supposed to do nor if it works for me.

Edit:

I discovered that there was an older version of the the first script in my vim installation directory (/usr/share/vim/vim70/indent/ in my case) to which I do not have access rights. You might have those rights, and if it's causing you problems, overwrite or delete it. If, like me, you can't edit it, you can get the version in your $HOME to overwrite the functions from the first. I did this by doing two things. First I had to remove the checks to see if the functions already exist (the statements like if exists("*FortranGetFixedIndent")) and then I had to change all the function declarations to force overwriting by using the ! character, i.e. function! SebuFortranGetFreeIndent(). As far as I can tell, everything now works roughly as I would expect!

like image 148
pattivacek Avatar answered Sep 28 '22 09:09

pattivacek


Does gg=G work?

gg: go to top
=: indent...
G: ... until the end

like image 45
sjas Avatar answered Sep 28 '22 09:09

sjas