an xemacs func to close parentheses

Pierre Imbaud pierre at saiph.com
Wed Jan 19 13:49:22 EST 2000


New posting, I had slight mistakes in the first one:
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)

;;++++++++++++++++
; key binding; modify as wished. I wanted something handy, with one
keystroke
; ] has these qualities, and is a good reminder of the function too. In
the
; seldom cases the function wont work properly, self insert is possible
; thru "ctrl-q ]"
;;++++++++++++++++

(define-key py-mode-map "]" 'close-parenthese)


;;++++++++++++++++
; customizable variables.
;;++++++++++++++++
; the parenthesis couples list:
(defvar clos-par-alist (mapcar (lambda (in) "returns an alist, from a
list of pairs"
                                 (cons (car in) (cadr in)))
                               (mapcar 's2l (list "()" "[]" "{}"))))

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


;;++++++++++++++++
; induced constants:
(setq closings (mapcar 'cdr clos-par-alist))
(setq openings (mapcar 'car clos-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 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 clos-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