an xemacs func to close parentheses

Pierre Imbaud pierre at saiph.com
Thu Jan 13 20:41:55 EST 2000


I was bored by the number of parentheses (lets rather say
surrounding chars: () [] {}) to close in python. could not the editor
guess the next action? these happen to be funny characters, uneasy
to type...
After looking for an existing xemacs function, with no success, I
designed one. It its specific to python, needs python-mode to be active.
make it called by your .emacs, map it to whatever key seq U like...
What the function does: insert the closing char corresponding to the
unmatched opening char: after (['toto will insert ', then (if called
again) ], then )
On first checks I saw no bug, there cud be some left. Tell me
close-parentheses.el:
;;Pierre Imbaud,  11 Jan 00 17:42 pierre at saiph.com
;;to build the ability to complete parentheses, with one function,
whatever the
;;parenthesis is.
;;algo: look backward for an open parenthesis. if we find a closing one,
;; skip backward the set. When found, insert the corresponding closing
parenthesis.

;; bugs: I hoped to use syntax-table, I could not find a way to retrieve
closing
;; parenthesis, from syntax table: so data used here is langage
dependent: we redefine
;; the mapping chars. But we still use syntax-table, thru the function
backward-sexp:
;; this provides an easy way to jump over existing parenthesis-enclosed
text.
;; as is, the package is dedicated to python langage, with one flaw: it
wont behave
;; if it has to close  a '''string like this one''', """or this one""".
Pain in the
;; ass, but it shud help in most cases. Surprisingly, it manages ok to
jump over these
;; strings.

(require 'python-mode)

;;++++++++++++++++
; customizable variables.
;;++++++++++++++++
; the parenthesis couples list:
(defvar clos-par-alist (mapcar 'l2alist (mapcar 's2l (list "()" "[]"
"{}"))))

(defvar clos-max-back 366)              ;limit for back exploration


;;++++++++++++++++
; induced constants:
(setq closings (mapcar 'cdr par-alist))
(setq openings (mapcar 'car par-alist))

;;++++++++++++++++
; utilities
;;++++++++++++++++
; I guess many of these eiter exist, I didnt find them, or cud have been
; defined as lambda.

(defun s2l (string)
  "string to list. recursive, inefficient"
  (if (equal string "")
      nil
    (cons (elt string 0) (s2l (substring string 1)))
    ))

(defun l2alist (in)
  "returns an alist, from a list of pairs"
  (cons (car in) (cadr in)))

(defun py-in-string ()
  " within a string, returns closing string char (as a lisp string!).
elsewhere nil"
  (let ((close (nth 3 (py-parse-state))))
    (if close (char-to-string close)
           )))

(defun closing-before-point ()
  "t if char before point is a closing parenthese"
  (memq (preceding-char) closings)
  )

(defun opening-before-point ()
  (interactive)
  "t if char before point is an opening parenthese"
  (if (memq (preceding-char) openings) (message "y"))
  )

(defun closing-paren(char)
  "returns the corresponding closing char to an opening char"
  (cdr (assoc char par-alist)))
(char-to-string (closing-paren ?\[))

;;++++++++++++++++
; main function:
;;++++++++++++++++

(defun close-parenthese ()
  (interactive)
  (let ((back clos-max-back)
        (to-insert "")
        (close-string (py-in-string))
        )
    (save-excursion
      (while (< 0 back)
        (setq back (- back 1))
        (if close-string
            (progn
              (setq to-insert close-string)
              (setq back 0)
              )
          ;else
          (if (memq (preceding-char) openings)
            (progn
              (setq to-insert (char-to-string
                               (closing-paren (preceding-char))))
              (setq back 0)
              )
            ;else again
            (if (memq (preceding-char) closings)
                (backward-sexp)
              (backward-char)
              )
            ))))
    ;out of save-excursion, but inside let...
    (insert-string to-insert)
    ))
          

    


-- 
Pierre Imbaud <pierre at saiph.com>
12 Rue des Bosquets 91480 Quincy Sous Sénart France
Tel:  01 69 00 94 57 Fax 79 65



More information about the Python-list mailing list