help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Can F90-mode blink at an "else"?


From: Glenn Morris
Subject: Re: Can F90-mode blink at an "else"?
Date: Sun, 11 Dec 2005 03:37:11 +0000
User-agent: Gnus (www.gnus.org), GNU Emacs (www.gnu.org/software/emacs/)

Glenn Morris wrote:

> Svend Tollak Munkejord wrote:
>
>> In F90-mode, when I use (setq f90-smart-end 'blink), Emacs only
>> indicates the matching if when the cursor is at the "end if", but not
>> when it is at the "else". 
>>
>> Does anybody know how I can make Emacs always show me the matching if?
>
> Sorry, I don't think there is any simple way to do this without
> re-writing parts of the f90-indent-line and f90-match-end functions.
> I'll try to add it as a feature for some future version.


Here's a briefly tested patch against the current CVS.


*** f90.el      04 Dec 2005 22:56:07 -0800      1.88
--- f90.el      10 Dec 2005 19:33:07 -0800      
***************
*** 991,996 ****
--- 991,1006 ----
                          "?\\([ \t]+\\(\\sw+\\)\\)?\\>"))
        (list (match-string 1) (match-string 3))))
  
+ (defsubst f90-looking-at-else-like ()
+   "Return KIND if an ELSE or CASE statement starts after point.
+ Returns \"selectcase\", \"elseif\", \"elsewhere\", \"else\", or nil."
+   (when (looking-at f90-else-like-re)
+     (cond ((looking-at "case[ \t]*\\(default\\|\(\\)")
+            "selectcase")
+           ((or (looking-at "else[ \t]*\\(if\\)\\>")
+                (looking-at "else\\(where\\)?\\>"))
+            (concat "else" (match-string 1))))))
+ 
  (defsubst f90-comment-indent ()
    "Return the indentation to be used for a comment starting at point.
  Used for `comment-indent-function' by F90 mode.
***************
*** 1430,1436 ****
        (skip-chars-forward " \t"))
      (if (looking-at "!")
        (setq indent (f90-comment-indent))
!       (and f90-smart-end (looking-at "end")
             (f90-match-end))
        (setq indent (f90-calculate-indent)))
      (or (= indent (current-column))
--- 1440,1446 ----
        (skip-chars-forward " \t"))
      (if (looking-at "!")
        (setq indent (f90-comment-indent))
!       (and f90-smart-end (looking-at (concat "end\\|" f90-else-like-re))
             (f90-match-end))
        (setq indent (f90-calculate-indent)))
      (or (= indent (current-column))
***************
*** 1719,1724 ****
--- 1729,1757 ----
               (replace-match ""))))
      (or (looking-at "[ \t]*!") (delete-horizontal-space))))
  
+ (defun f90-else-like-match (beg-block else-block)
+   "Match else-struct with beg-struct and complete else-struct if possible.
+ BEG-BLOCK is the type of block as indicated at the start (e.g., if).
+ ELSE-BLOCK is the type of block as indicated at the else (may be nil)."
+   (if (not (member beg-block '("if" "where" "select")))
+       (if beg-block
+           (message "`%s' block cannot have an ELSE/CASE." beg-block)
+         (message "No beginning for ELSE/CASE."))
+     (let ((else-type (cond
+                       ((string-equal else-block "selectcase") "select")
+                       ((string-match "else\\(if\\|where\\)" else-block)
+                        (match-string 1 else-block)))))
+       (unless (f90-equal-symbols beg-block else-type)
+         (if (or else-type
+                 (f90-equal-symbols beg-block "select"))
+             (progn
+               (message "%s does not match %s." else-block beg-block)
+               (end-of-line))
+           (cond ((string-equal beg-block "where")
+                  (message "Inserting %s." beg-block)
+                  (search-forward "else" (line-end-position))
+                  (insert beg-block))))))))
+ 
  (defun f90-match-end ()
    "From an end block statement, find the corresponding block and name."
    (interactive)
***************
*** 1726,1736 ****
          (top-of-window (window-start))
        (end-point (point))
          (case-fold-search t)
!       matching-beg beg-name end-name beg-block end-block end-struct)
      (when (save-excursion (beginning-of-line) (skip-chars-forward " \t0-9")
!                           (setq end-struct 
(f90-looking-at-program-block-end)))
!       (setq end-block (car end-struct)
!             end-name  (car (cdr end-struct)))
        (save-excursion
          (beginning-of-line)
          (while (and (> count 0)
--- 1759,1769 ----
          (top-of-window (window-start))
        (end-point (point))
          (case-fold-search t)
!       matching-beg beg-name beg-block end-struct else-struct)
      (when (save-excursion (beginning-of-line) (skip-chars-forward " \t0-9")
!                           (or (setq end-struct
!                                     (f90-looking-at-program-block-end))
!                               (setq else-struct (f90-looking-at-else-like))))
        (save-excursion
          (beginning-of-line)
          (while (and (> count 0)
***************
*** 1773,1779 ****
                  beg-name (car (cdr matching-beg)))
            (goto-char end-point)
            (beginning-of-line)
!           (f90-block-match beg-block beg-name end-block end-name))))))
  
  (defun f90-insert-end ()
    "Insert a complete end statement matching beginning of present block."
--- 1806,1815 ----
                  beg-name (car (cdr matching-beg)))
            (goto-char end-point)
            (beginning-of-line)
!           (if else-struct
!               (f90-else-like-match beg-block else-struct)
!             (f90-block-match beg-block beg-name
!                              (car end-struct) (cadr end-struct))))))))
  
  (defun f90-insert-end ()
    "Insert a complete end statement matching beginning of present block."


reply via email to

[Prev in Thread] Current Thread [Next in Thread]