;; ;; Copyright (c) 2002 by The XFree86 Project, Inc. ;; ;; Permission is hereby granted, free of charge, to any person obtaining a ;; copy of this software and associated documentation files (the "Software"), ;; to deal in the Software without restriction, including without limitation ;; the rights to use, copy, modify, merge, publish, distribute, sublicense, ;; and/or sell copies of the Software, and to permit persons to whom the ;; Software is furnished to do so, subject to the following conditions: ;; ;; The above copyright notice and this permission notice shall be included in ;; all copies or substantial portions of the Software. ;; ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF ;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ;; SOFTWARE. ;; ;; Except as contained in this notice, the name of the XFree86 Project shall ;; not be used in advertising or otherwise to promote the sale, use or other ;; dealings in this Software without prior written authorization from the ;; XFree86 Project. ;; ;; Author: Paulo César Pereira de Andrade ;; ;; ;; $XdotOrg: xc/programs/xedit/lisp/modules/xedit.lsp,v 1.2 2004/04/23 19:54:45 eich Exp $ ;; $XFree86: xc/programs/xedit/lisp/modules/xedit.lsp,v 1.9 2003/01/16 03:50:46 paulo Exp $ ;; (provide "xedit") #+debug (make-package "XEDIT" :use '("LISP" "EXT")) (in-package "XEDIT") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; TODO The user should be able to define *auto-modes* prior to the ;; initialization here in a configuration file, since defvar only binds ;; the variable if it is unbound or doesn't have a value defined. ;; *auto-modes* is a list of conses where every car is compiled ;; to a regexp to match the name of the file being loaded. The caddr is ;; either a string, a pathname, or a syntax-p. ;; When loading a file, if the regexp in the car matches, it will check ;; the caddr value, and if it is a: ;; string: executes (load "progmodes/.lsp") ;; pathname: executes (load ) ;; syntax-p: does nothing, already loaded ;; ;; If it fails to load the file, or the returned value is not a ;; syntax-p, the entry is removed. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar *auto-modes* '( ("\\.(c|cc|C|cxx|cpp|h|hpp|bm|xbm|xpm|l|y|h\\.in)$" "C/C++" "c" . *c-mode*) ("\\.(li?sp|scm)$" "Lisp/Scheme" "lisp" . *lisp-mode*) ("\\.sh$" "Unix shell" "sh" . *sh-mode*) ("\\.(diff|patch)" "Patch file" "patch" . *patch-mode*) ("[Mm]akefile.*|\\.mk$" "Makefile" "make" . *make-mode*) ("\\.spec$" "RPM spec" "rpm" . *rpm-mode*) ("\\.(sgml?|dtd)$" "SGML" "sgml" . *sgml-mode*) ("\\.html?$" "HTML" "html" . *html-mode*) ("\\.(man|\\d)$" "Man page" "man" . *man-mode*) ("app-defaults/\\w+|\\u[A-Za-z0-9_-]+\\.ad" "X resource" "xrdb" . *xrdb-mode*) ("\\<(XF86Config[^/]*|xorg.conf$)" "XF86Config" "xconf" . *xconf-mode*) ("\\<(XFree86|Xorg)\\.\\d+\\.log$" "XFree86 log" "xlog" . *xlog-mode*) ("Imakefile|(\\.(cf|rules|tmpl|def)$)" "X imake" "imake" . *imake-mode*) )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Compile the regexps in the *auto-modes* list. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (dolist (mode *auto-modes*) (rplaca mode (re-comp (car mode) :nosub t)) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Find the progmode associated with the given filename. ;; Returns nil if nothing matches. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun auto-mode (filename &optional symbol &aux syntax) (if (and symbol (symbolp symbol)) (if (boundp symbol) (return-from auto-mode (symbol-value symbol)) (setq syntax (cddr (find symbol *auto-modes* :key #'cdddr))) ) ;; symbol optional argument is not a symbol (do* ( (mode *auto-modes* (cdr mode)) (regex (caar mode) (caar mode)) ) ((endp mode)) ;; only wants to know if the regex match. (when (listp (re-exec regex filename :count 0)) (setq syntax (cddar mode) symbol (cdr syntax)) (return) ) ) ) ;; if file was already loaded (if (and symbol (boundp symbol)) (return-from auto-mode (symbol-value symbol)) ) (when (consp syntax) ;; point to the syntax file specification (setq syntax (car syntax)) ;; try to load the syntax definition file (if (stringp syntax) (load (string-concat (namestring *default-pathname-defaults*) "progmodes/" syntax ".lsp" ) ) (load syntax) ) (and symbol (boundp symbol) (symbol-value symbol)) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data types. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The main syntax structure, normally, only one should exist per ;; syntax highlight module. ;; The structure is defined here so it is not required to load all ;; the extra data associated with syntax-highlight at initialization ;; time, and will never be loaded if no syntax-highlight mode is ;; defined to the files being edited. (defstruct syntax name ;; A unique string to identify the syntax mode. ;; Should be the name of the language/file type. options ;; A hash table of options specified for the ;; language. ;; Field(s) defined at "compile time" labels ;; Not exactly a list of labels, but all syntax ;; tables for the module. quark ;; A XrmQuark associated with the XawTextPropertyList ;; used by this syntax mode. token-count ;; Number of distinct syntoken structures in ;; the syntax table. ) ;; Xlfd description, used when combining properties. ;; Field names are self descriptive. ;; XXX Fields should be initialized as strings, but fields ;; that have an integer value should be allowed to ;; be initialized as such. ;; Combining properties in supported in Xaw, but not yet in the ;; syntax highlight code interface. Combining properties allow easier ;; implementation for markup languages, for example: ;; bolditalic ;; would render "bold" using a bold version of the default font, ;; and "italic" using a bold and italic version of the default font (defstruct xlfd foundry family weight slant setwidth addstyle pixel-size point-size res-x res-y spacing avgwidth registry encoding ) ;; At some time this structure should also hold information for at least: ;; o fontset ;; o foreground pixmap ;; o background pixmap ;; XXX This is also a TODO in Xaw. (defstruct synprop quark ;; XrmQuark identifier of the XawTextProperty ;; structure. This field is filled when "compiling" ;; the syntax-table. name ;; String name of property, must be unique per ;; property list. font ;; Optional font string name of property. foreground ;; Optional string representation of foreground color. background ;; Optional string representation of background color. xlfd ;; Optional xlfd structure, when combining properties. ;; Currently combining properties logic not implemented, ;; but fonts may be specified using the xlfd definition. ;; Boolean properties. underline ;; Draw a line below the text. overstrike ;; Draw a line over the text. ;; XXX Are these working in Xaw? subscript ;; Align text to the bottom of the line. superscript ;; Align text to the top of the line. ;; Note: subscript and superscript only have effect when the text ;; line has different height fonts displayed. ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Utility macro, to create a "special" variable holding ;; a synprop structure. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmacro defsynprop (variable name &key font foreground background xlfd underline overstrike subscript superscript) `(progn (proclaim '(special ,variable)) (setq ,variable (make-synprop :name ,name :font ,font :foreground ,foreground :background ,background :xlfd ,xlfd :underline ,underline :overstrike ,overstrike :subscript ,subscript :superscript ,superscript ) ) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Convert a synprop structure to a string in the format ;; expected by Xaw. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun synprop-to-string (synprop &aux values booleans xlfd) (if (setq xlfd (synprop-xlfd synprop)) (dolist (element `( ("foundry" ,(xlfd-foundry xlfd)) ("family" ,(xlfd-family xlfd)) ("weight" ,(xlfd-weight xlfd)) ("slant" ,(xlfd-slant xlfd)) ("setwidth" ,(xlfd-setwidth xlfd)) ("addstyle" ,(xlfd-addstyle xlfd)) ("pixelsize" ,(xlfd-pixel-size xlfd)) ("pointsize" ,(xlfd-point-size xlfd)) ("resx" ,(xlfd-res-x xlfd)) ("resy" ,(xlfd-res-y xlfd)) ("spacing" ,(xlfd-spacing xlfd)) ("avgwidth" ,(xlfd-avgwidth xlfd)) ("registry" ,(xlfd-registry xlfd)) ("encoding" ,(xlfd-encoding xlfd)) ) ) (if (cadr element) (setq values (append values element)) ) ) ) (dolist (element `( ("font" ,(synprop-font synprop)) ("foreground" ,(synprop-foreground synprop)) ("background" ,(synprop-background synprop)) ) ) (if (cadr element) (setq values (append values element)) ) ) ;; Boolean attributes. These can be specified in the format ;; =, but do a nicer output as the format ;; is accepted. (dolist (element `( ("underline" ,(synprop-underline synprop)) ("overstrike" ,(synprop-overstrike synprop)) ("subscript" ,(synprop-subscript synprop)) ("superscript" ,(synprop-superscript synprop)) ) ) (if (cadr element) (setq booleans (append booleans element)) ) ) ;; Play with format conditionals, list iteration, and goto, to ;; make resulting string. (format nil "~A~:[~;?~]~:[~3*~;~A=~A~{&~A=~A~}~]~:[~;&~]~:[~2*~;~A~{&~A~*~}~]" (synprop-name synprop) ;; ~A (or values booleans) ;; ~:[~;?~] values ;; ~:[ (car values) (cadr values) (cddr values) ;; ~A=~A~{&~A=~A~} (and values booleans) ;; ~:[~;&~] booleans ;; ~:[ (car booleans) (cddr booleans) ;; ~A~{&~A~*~} ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Use xedit protocol to create a XawTextPropertyList with the ;; given arguments. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun compile-syntax-property-list (name properties &aux string-properties quark) ;; Create a string representation of the properties. (dolist (property properties) (setq string-properties (append string-properties (list (synprop-to-string property)) ) ) ) (setq string-properties (case (length string-properties) (0 "") (1 (car string-properties)) (t (format nil "~A~{,~A~}" (car string-properties) (cdr string-properties) ) ) ) ) #+debug (format *output* "~Cconvert-property-list ~S ~S~%" *escape* name string-properties ) (setq quark #-debug (convert-property-list name string-properties) #+debug 0) ;; Store the quark for properties not yet "initialized". ;; XXX This is just a call to Xrm{Perm,}StringToQuark, and should ;; be made available if there were a wrapper/interface to ;; that Xlib function. (dolist (property properties) (unless (integerp (synprop-quark property)) #+debug (format *output* "~Cxrm-string-to-quark ~S~%" *escape* (synprop-name property) ) (setf (synprop-quark property) #-debug (xrm-string-to-quark (synprop-name property)) #+debug 0 ) ) ) quark ) #+debug (progn (defconstant *escape* #\$) (defconstant *output* *standard-output*) ;; Recognized identifiers for wrap mode. (defconstant *wrap-modes* '(:never :line :word)) ;; Recognized identifiers for justification. (defconstant *justifications* '(:left :right :center :full)) ;; XawTextScanType (defconstant *scan-type* '(:positions :white-space :eol :paragraph :all :alpha-numeric)) ;; XawTextScanDirection (defconstant *scan-direction* '(:left :right)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Debugging version of xedit functions. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun clear-entities (left right) (format *output* "~Cclear-entities ~D ~D~%" *escape* left right)) (defun add-entity (offset length identifier) (format *output* "~Cadd-entity ~D ~D ~D~%" *escape* offset length identifier)) (defun background (&optional (value nil specified)) (if specified (format *output* "~Cset-background ~S~%" *escape* value) (format *output* "~Cget-background~%" *escape*))) (defun foreground (&optional (value nil specified)) (if specified (format *output* "~Cset-foreground ~S~%" *escape* value) (format *output* "~Cget-foreground~%" *escape*))) (defun font (&optional (value nil specified)) (if specified (format *output* "~Cset-font ~S~%" *escape* value) (format *output* "~Cget-font~%" *escape*))) (defun point (&optional (value nil specified)) (if specified (format *output* "~Cset-point ~D~%" *escape* value) (format *output* "~Cget-point~%" *escape*))) (defun point-min () (format *output* "~Cpoint-min~%" *escape*)) (defun point-max () (format *output* "~Cpoint-max~%" *escape*)) (defun property-list (&optional (quark nil specified)) (format *output* "~property-list ~D~%" *escape* quark)) (defun insert (string) (format *output* "~Cinsert ~S~%" *escape* string)) (defun read-text (offset length) (format *output* "~Cread-text ~D ~D~%" *escape* offset length)) (defun replace-text (left right string) (format *output* "~Creplace-text ~D ~D ~S~%" *escape* left right string)) (defun scan (offset type direction &key (count 1) include) (unless (setq type (position type *scan-type*)) (error "SCAN: type must be one of ~A, not ~A" *scan-type* type)) (unless (setq direction (position direction *scan-direction*)) (error "SCAN: direction must be one of ~A, not ~A" *scan-direction* direction)) (format *output* "~Cscan ~D ~D ~D ~D ~D~%" *escape* offset type direction count (if include 1 0))) (defun search-forward (string &optional case-sensitive) (format *output* "~Csearch-forward ~S ~D~%" *escape* string (if case-sensitive 1 0))) (defun search-backward (string &optional case-sensitive) (format *output* "~Csearch-backward ~S ~D~%" *escape* string (if case-sensitive 1 0))) (defun wrap-mode (&optional (value nil specified)) (if specified (progn (unless (member value *wrap-modes*) (error "WRAP-MODE: argument must be one of ~A, not ~A" *wrap-modes* value)) (format *output* "~Cset-wrap-mode ~S~%" *escape* (string value))) (format *output* "~Cget-wrap-mode~%" *escape*))) (defun auto-fill (&optional (value nil specified)) (if specified (format *output* "~Cset-auto-fill ~S~%" *escape* (if value "true" "false")) (format *output* "~Cget-auto-fill~%" *escape*))) (defun justification (&optional (value nil specified)) (if specified (progn (unless (member value *justifications*) (error "JUSTIFICATION: argument must be one of ~A, not ~A" *justifications* value)) (format *output* "~Cset-justification ~S~%" *escape* (string value))) (format *output* "~Cget-justification~%" *escape*))) (defun left-column (&optional (value nil specified)) (if specified (format *output* "~Cset-left-column ~D~%" *escape* value) (format *output* "~Cget-left-column~%" *escape*))) (defun right-column (&optional (value nil specified)) (if specified (format *output* "~Cset-right-column ~D~%" *escape* value) (format *output* "~Cget-right-column~%" *escape*))) (defun vertical-scrollbar (&optional (value nil specified)) (if specified (format *output* "~Cset-vert-scrollbar ~S~%" *escape* (if value "always" "never")) (format *output* "~Cget-vert-scrollbar~%" *escape*))) (defun horizontal-scrollbar (&optional (value nil specified)) (if specified (format *output* "~Cset-horiz-scrollbar ~S~%" *escape* (if value "always" "never")) (format *output* "~Cget-horiz-scrollbar~%" *escape*))) #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| (defun create-buffer (name) (format *output* "~Ccreate-buffer ~S~%" *escape* name)) (defun remove-buffer (name) (format *output* "~Cremove-buffer ~S~%" *escape* name)) (defun buffer-name (&optional (value nil specified)) (if specified (format *output* "~Cset-buffer-name ~S~%" *escape* value) (format *output* "~Cget-buffer-name~%" *escape*))) (defun buffer-filename (&optional (value nil specified)) (if specified (format *output* "~Cset-buffer-filename ~S~%" *escape* (namestring value)) (format *output* "~Cget-buffer-filename~%" *escape*))) (defun current-buffer (&optional (value nil specified)) (if specified (format *output* "~Cset-current-buffer ~S~%" *escape* value) (format *output* "~Cget-current-buffer~%" *escape*))) (defun other-buffer (&optional (value nil specified)) (if specified (format *output* "~Cset-other-buffer ~S~%" *escape* value) (format *output* "~Cget-other-buffer~%" *escape*))) |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||# )