3
votes

I am working on a fortran code. The sources are written in old fashion f77 style but the f90 comment style, with '!' is authorized. I want to edit the emacs behavior when hitting tab on lines with comments. I can distinguish 3 types of comments:

      program helloworld

      integer:: i,j

      do i=1,1
         do j=1,1
* This is a first type of comment
*    another first type comment
            ! second type of comment
            print *,"helloworld" ! third type of comment
         enddo
      enddo ! another third type comment

      end program helloworld

When hitting tab on each line with a comment type, I got

program helloworld

      integer:: i,j

      do i=1,1
         do j=1,1
*     This is a first type of comment
*     another first type comment
! second type of comment
            print *,"helloworld" ! third type of comment
         enddo
      enddo                     ! another third type comment

      end program helloworld

The behavior I would like to have is, as hitting tab on a line with:

  • first type comment: do nothing
  • second type comment: indent the line as an instruction line
  • third type comment: indent the line as an instruction line, without adding spaces between the instruction and the comment that follows

I tried to override some function from fortran.el in my init.el but went crazy with lisp. I would be glad if some lisp/emacs warriors could help me with this.

Thanks

1

1 Answers

4
votes

You can achieve what you want for your 2nd and 3rd type of comments with this:

(setq fortran-comment-indent-style 'relative)
(add-hook 'fortran-mode-hook (lambda () (setq comment-column 0)))

For your 1st type comments, you need a hack like the following:

(defadvice fortran-indent-line (after custom-indentation activate)
  (save-excursion
    (forward-line 0)
    (when (looking-at "*")
      (forward-char 1)
      (just-one-space))))

EDIT

Honoring your last comment requires a more complex and uglier hack. Replace the previous defadvice by this one:

(defadvice fortran-indent-line (around custom-indentation activate)
  (let ((type-* (save-excursion
                  (forward-line 0)
                  (looking-at "\s*\\*")))
        (type-! (save-excursion
                  (forward-line 0)
                  (looking-at "\s*!"))))
    (if type-!
        (progn
          (save-excursion
            (forward-line 0)
            (re-search-forward "!")
            (replace-match "__"))
          ad-do-it
          (save-excursion
            (forward-line 0)
            (re-search-forward "__")
            (replace-match "!"))
          )
      (if (not type-*)
          ad-do-it))))