; .EnTete "Le-Lisp (c) version 15.2" " " "Me'me'" ; .EnPied "meme.ll" "%" " " ; .SuperTitre "L'e'diteur me'me'" ; ; .Auteur "Bernard Serpette" ; ; .Centre "*****************************************************************" ; .Centre " (c) Le-Lisp est une marque de'pose'e de l'INRIA " ; .Centre "*****************************************************************" ; ; .Centre "$Header: meme.ll,v 4.1 88/01/13 12:35:37 kuczynsk Rel $" (unless (>= (version) 15.2) (error 'load 'erricf 'meme)) ; .Section "L'e'diteur Me'me'" ; .SSection "Contenu." ; On de'finit ici un petit e'diteur a` la Emacs. Il est multi-e'cran, ; chaque e'cran posse`de sa ligne propre ligne d'information (wholine), ; tous les e'crans partagent la me↑me ligne de dialogue (qui est lui me↑me ; un e'diteur) et il est possible d'e'valuer une expression dans un e'cran. ; .SSection "De'clarations" (defvar #:sys-package:colon '#:edit:editor:meme) (add-feature 'meme) (defstruct #.#:sys-package:colon (wholine) (wholinemap) (locx 0) (locy 0) ) ; .SSection "Les variables globales" ; La liste des e'crans. (defvar :list-editor ()) ; .SSection "Fonction de lancement" (defun meme f (let ( (e ()) ) (if (and (null f) :list-editor) (setq e (car :list-editor)) (setq :list-editor (ncons (setq e (:make-meme-editor 0 0 (tyxmax) (tyymax)))) ) (when (setq f (car f)) (let ( (rf (probepathf f)) ) (ifn rf (:file e f) (FILE-READ e rf) (:file e rf) )))) (:rdpscreen e) (edit-command-redisplay e ()) (untilexit meme (tag no-redisplay (edit-command-redisplay e (tyi))) (setq e (car :list-editor)) ) (tycursor 0 (tyymax)) 'meme )) (dmc ↑E () (if (eq (peekcn) 13) '(meme) `(meme ',(concat (readstring))) )) ; .SSection "Interface avec le re'affichage" (defun :edit-drawcursor (e x y f) (when f (let ( (who (:wholine e)) (whomap (:wholinemap e)) ) (fillstring who 7 #\SP) (when (ge (#:buffer:modif (:pbuffer e)) 4) (sset who 8 #/*)) (if (le (#:buffer:modif (:pbuffer e)) 1) (bltstring who 10 "(RO)" 0) (bltstring who 10 "(RW)" 0) ) (bltstring who 15 (:file e) 0) (unless (eqstring who whomap) (bltstring whomap 0 who 0) (tycursor (:locx e) (add (:locy e) (:h e))) (with ((tyattrib t)) (tyo whomap)) ) (tycursor (add x (:locx e)) (add y (:locy e))) ))) (defun :edit-redisplaystring (e x y s pos n) (tycursor (add x (:locx e)) (add y (:locy e))) (repeat n (tyo (sref s pos)) (setq pos (add1 pos)) )) (defun :edit-redisplaycleol (e x y n) (tycursor (add x (:locx e)) (add y (:locy e))) (tycleol) ) (defun :rdpscreen (ne) (tycls) (mapc (lambda (e) (WIN-CLEAR e) (fillstring (:wholinemap e) 0 #\SP) (unless (eq e ne) (edit-command-redisplay e ()) )) :list-editor )) (defun :tycls (e) (let ( (y (:locy e)) (x (:locx e)) ) (repeat (:h e) (tycursor x y) (tycleol) (setq y (add1 y)) ))) ; .SSection "Fonction de cre'ation et nouvelles cle's" (defun :make-meme-editor (x y w h) (let ( (e (:make)) (who (makestring w #\SP)) ) (init-editor e e w (sub1 h)) (:drawcursor e ':edit-drawcursor) (:redisplaystring e ':edit-redisplaystring) (:redisplaycleol e ':edit-redisplaycleol) (:query e ':edit-query) (:locx e x) (:locy e y) (bltstring who 0 "Editor:" 0) (:wholine e who) (:wholinemap e (makestring w #\SP)) (local-bind-to-ekey e #/c '(trap-meme . 0)) (local-bind-to-key e #↑L '(trap-meme . 1)) (local-bind-to-xkey e #/1 '(trap-meme . 2)) (local-bind-to-xkey e #/2 '(trap-meme . 3)) (local-bind-to-xkey e #/n '(trap-meme . 4)) (local-bind-to-xkey e #/p '(trap-meme . 5)) (local-bind-to-xkey e #↑V '(trap-meme . 6)) e )) (defun trap-meme (e n) (selectq n (0 (:state e 0) (exit meme)) (1 (:rdpscreen e)) (2 (:unsplit-editor e)) (3 (:split-editor e)) (4 (:next-editor e)) (5 (:previous-editor e)) (6 (:visit-file e (:edit-query e "Visit File: " t))) )) (defun :visit-file (e f) (when f (:split-editor e) (BUF-UNLINK e) (:file e (or (probepathf f) f)) (FILE-READ e (probepathf f)) (:tycls e) )) (defun :previous-editor (e) (let ( (l (nreverse :list-editor)) ) (setq :list-editor (cons (setq e (car l)) (nreverse (cdr l)))) (edit-command-redisplay e ()) (exit no-redisplay) )) (defun :next-editor (e) (setq :list-editor (nreverse (cons (car :list-editor) (nreverse (cdr :list-editor)))) ) (setq e (car :list-editor)) (edit-command-redisplay e ()) (exit no-redisplay) ) (defun :unsplit-editor (e) (init-editor e e (tyxmax) (sub1 (tyymax))) (:locx e 0) (:locy e 0) (setq :list-editor (ncons e)) (:rdpscreen e) (exit no-redisplay (edit-command-redisplay e ())) ) (defun :split-editor (e) (if (le (:h e) 2) (exit eoc "Your window is too small") (let ( ne (h (:h e)) (w (:w e)) nh ) (setq nh (div (add1 h) 2) h (sub h nh)) (init-editor e e w h) (setq ne (:make-meme-editor (:locx e) (add1 (add h (:locy e))) w nh) ) (BUF-LINK ne e) (:file ne (:file e)) (rplacd :list-editor (cons ne (cdr :list-editor))) (fillstring (:wholinemap e) 0 #\SP) (:tycls ne) (edit-command-redisplay ne ()) ))) ; .SSection "Interface avec un simple editeur de ligne." ; Sachant qu'a` chaque commande on demande d'effacer l'e'diteur de ligne ; on optimise en gardant l'e'tat courant de l'e'diteur de ligne (i.e. ; contient un message ou pas) (defvar :clean-query? t) (defun :edit-query (e msg fg) (if fg (let ( (ne (:make)) (n (slen msg)) ) (init-editor ne ne (tyxmax) 1) (:drawcursor ne ':query-drawcursor) (:redisplaystring ne ':edit-redisplaystring) (:redisplaycleol ne ':edit-redisplaycleol) (:locx ne n) (:locy ne (tyymax)) (local-bind-to-key ne #↑G '(:trap-query . 0)) (local-bind-to-key ne #↑M '(:trap-query . 1)) (tycursor 0 (tyymax)) (tyo msg) (tycleol) (setq :clean-query? ()) (prog1 (untilexit query (edit-command-redisplay ne (tyi))) (:xcursor e -1) )) (unless (and (null msg) :clean-query?) (tycursor 0 (tyymax)) (tycleol) (ifn msg (setq :clean-query? t) (tyo msg) (setq :clean-query? ()) ) (:xcursor e -1) ))) (defun :query-drawcursor (e x y f) (when f (tycursor (add x (:locx e)) (add y (:locy e)))) ) (defun :trap-query (e n) (selectq n (0 (exit query ())) (1 (exit query (LINE-GET e))) ))