1;; 2;; Copyright (c) 2002 by The XFree86 Project, Inc. 3;; 4;; Permission is hereby granted, free of charge, to any person obtaining a 5;; copy of this software and associated documentation files (the "Software"), 6;; to deal in the Software without restriction, including without limitation 7;; the rights to use, copy, modify, merge, publish, distribute, sublicense, 8;; and/or sell copies of the Software, and to permit persons to whom the 9;; Software is furnished to do so, subject to the following conditions: 10;; 11;; The above copyright notice and this permission notice shall be included in 12;; all copies or substantial portions of the Software. 13;; 14;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20;; SOFTWARE. 21;; 22;; Except as contained in this notice, the name of the XFree86 Project shall 23;; not be used in advertising or otherwise to promote the sale, use or other 24;; dealings in this Software without prior written authorization from the 25;; XFree86 Project. 26;; 27;; Author: Paulo César Pereira de Andrade 28;; 29;; 30;; $XdotOrg: xc/programs/xedit/lisp/modules/xedit.lsp,v 1.2 2004/04/23 19:54:45 eich Exp $ 31;; $XFree86: xc/programs/xedit/lisp/modules/xedit.lsp,v 1.9 2003/01/16 03:50:46 paulo Exp $ 32;; 33 34(provide "xedit") 35 36#+debug (make-package "XEDIT" :use '("LISP" "EXT")) 37(in-package "XEDIT") 38 39 40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 41;; TODO The user should be able to define *auto-modes* prior to the 42;; initialization here in a configuration file, since defvar only binds 43;; the variable if it is unbound or doesn't have a value defined. 44;; *auto-modes* is a list of conses where every car is compiled 45;; to a regexp to match the name of the file being loaded. The caddr is 46;; either a string, a pathname, or a syntax-p. 47;; When loading a file, if the regexp in the car matches, it will check 48;; the caddr value, and if it is a: 49;; string: executes (load "progmodes/<the-string>.lsp") 50;; pathname: executes (load <the-pathhame>) 51;; syntax-p: does nothing, already loaded 52;; 53;; If it fails to load the file, or the returned value is not a 54;; syntax-p, the entry is removed. 55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 56(defvar *auto-modes* '( 57 ("\\.(c|cc|C|cxx|cpp|h|hpp|bm|xbm|xpm|y|h\\.in)$" 58 "C/C++" "c" . *c-mode*) 59 ("\\.(l|li?sp|scm)$" 60 "Lisp/Scheme" "lisp" . *lisp-mode*) 61 ("\\.sh$" 62 "Unix shell" "sh" . *sh-mode*) 63 ("\\.(diff|patch)" 64 "Patch file" "patch" . *patch-mode*) 65 ("/[Mm]akefile.*|\\.mk$" 66 "Makefile" "make" . *make-mode*) 67 ("\\.(ac|in|m4)$" 68 "Autotools" "auto" . *auto-mode*) 69 ("\\.spec$" 70 "RPM spec" "rpm" . *rpm-mode*) 71 ("\\.(pl|pm|ph)$" 72 "Perl" "perl" . *perl-mode*) 73 ("\\.(py)$" 74 "Python" "python". *python-mode*) 75 ("\\.(sgml?|dtd)$" 76 "SGML" "sgml" . *sgml-mode*) 77 ("\\.html?$" 78 "HTML" "html" . *html-mode*) 79 ("\\.(man|\\d)$" 80 "Man page" "man" . *man-mode*) 81 ("app-defaults/\\w+|\\u[A-Za-z0-9_-]+\\.ad" 82 "X resource" "xrdb" . *xrdb-mode*) 83 ("\\<(XF86Config|xorg.conf)[^/]*" 84 "XF86Config" "xconf" . *xconf-mode*) 85 ("\\<(XFree86|Xorg)\\.\\d+\\.log(\\..*|$)" 86 "XFree86 log" "xlog" . *xlog-mode*) 87 ("Imakefile|(\\.(cf|rules|tmpl|def)$)" 88 "X imake" "imake" . *imake-mode*) 89)) 90 91 92;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 93;; Compile the regexps in the *auto-modes* list. 94;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 95(dolist (mode *auto-modes*) 96 (rplaca mode (re-comp (car mode) :nosub t)) 97) 98 99 100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 101;; Find the progmode associated with the given filename. 102;; Returns nil if nothing matches. 103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 104(defun auto-mode (filename &optional symbol &aux syntax) 105 (if (and symbol (symbolp symbol)) 106 (if (boundp symbol) 107 (return-from auto-mode (symbol-value symbol)) 108 (setq syntax (cddr (find symbol *auto-modes* :key #'cdddr))) 109 ) 110 ;; symbol optional argument is not a symbol 111 (do* 112 ( 113 (mode *auto-modes* (cdr mode)) 114 (regex (caar mode) (caar mode)) 115 ) 116 ((endp mode)) 117 118 ;; only wants to know if the regex match. 119 (when (listp (re-exec regex filename :count 0)) 120 (setq syntax (cddar mode) symbol (cdr syntax)) 121 (return) 122 ) 123 ) 124 ) 125 126 ;; if file was already loaded 127 (if (and symbol (boundp symbol)) 128 (return-from auto-mode (symbol-value symbol)) 129 ) 130 131 (when (consp syntax) 132 ;; point to the syntax file specification 133 (setq syntax (car syntax)) 134 135 ;; try to load the syntax definition file 136 (if (stringp syntax) 137 (load 138 (string-concat 139 (namestring *default-pathname-defaults*) 140 "progmodes/" 141 syntax 142 ".lsp" 143 ) 144 ) 145 (load syntax) 146 ) 147 148 (and symbol (boundp symbol) (symbol-value symbol)) 149 ) 150) 151 152 153;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 154;; Data types. 155;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 156;; The main syntax structure, normally, only one should exist per 157;; syntax highlight module. 158;; The structure is defined here so it is not required to load all 159;; the extra data associated with syntax-highlight at initialization 160;; time, and will never be loaded if no syntax-highlight mode is 161;; defined to the files being edited. 162(defstruct syntax 163 name ;; A unique string to identify the syntax mode. 164 ;; Should be the name of the language/file type. 165 options ;; A hash table of options specified for the 166 ;; language. 167 168 ;; Field(s) defined at "compile time" 169 labels ;; Not exactly a list of labels, but all syntax 170 ;; tables for the module. 171 quark ;; A XrmQuark associated with the XawTextPropertyList 172 ;; used by this syntax mode. 173 token-count ;; Number of distinct syntoken structures in 174 ;; the syntax table. 175) 176 177;; Xlfd description, used when combining properties. 178;; Field names are self descriptive. 179;; XXX Fields should be initialized as strings, but fields 180;; that have an integer value should be allowed to 181;; be initialized as such. 182;; Combining properties in supported in Xaw, but not yet in the 183;; syntax highlight code interface. Combining properties allow easier 184;; implementation for markup languages, for example: 185;; <b>bold<i>italic</i></b> 186;; would render "bold" using a bold version of the default font, 187;; and "italic" using a bold and italic version of the default font 188(defstruct xlfd 189 foundry 190 family 191 weight 192 slant 193 setwidth 194 addstyle 195 pixel-size 196 point-size 197 res-x 198 res-y 199 spacing 200 avgwidth 201 registry 202 encoding 203) 204 205 206;; At some time this structure should also hold information for at least: 207;; o fontset 208;; o foreground pixmap 209;; o background pixmap 210;; XXX This is also a TODO in Xaw. 211(defstruct synprop 212 quark ;; XrmQuark identifier of the XawTextProperty 213 ;; structure. This field is filled when "compiling" 214 ;; the syntax-table. 215 216 name ;; String name of property, must be unique per 217 ;; property list. 218 font ;; Optional font string name of property. 219 foreground ;; Optional string representation of foreground color. 220 background ;; Optional string representation of background color. 221 xlfd ;; Optional xlfd structure, when combining properties. 222 ;; Currently combining properties logic not implemented, 223 ;; but fonts may be specified using the xlfd definition. 224 225 ;; Boolean properties. 226 underline ;; Draw a line below the text. 227 overstrike ;; Draw a line over the text. 228 229 ;; XXX Are these working in Xaw? 230 subscript ;; Align text to the bottom of the line. 231 superscript ;; Align text to the top of the line. 232 ;; Note: subscript and superscript only have effect when the text 233 ;; line has different height fonts displayed. 234) 235 236 237;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 238;; Utility macro, to create a "special" variable holding 239;; a synprop structure. 240;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 241(defmacro defsynprop (variable name 242 &key font foreground background xlfd underline 243 overstrike subscript superscript) 244 `(progn 245 (proclaim '(special ,variable)) 246 (setq ,variable 247 (make-synprop 248 :name ,name 249 :font ,font 250 :foreground ,foreground 251 :background ,background 252 :xlfd ,xlfd 253 :underline ,underline 254 :overstrike ,overstrike 255 :subscript ,subscript 256 :superscript ,superscript 257 ) 258 ) 259 ) 260) 261 262 263;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 264;; Convert a synprop structure to a string in the format 265;; expected by Xaw. 266;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 267(defun synprop-to-string (synprop &aux values booleans xlfd) 268 (if (setq xlfd (synprop-xlfd synprop)) 269 (dolist 270 (element 271 `( 272 ("foundry" ,(xlfd-foundry xlfd)) 273 ("family" ,(xlfd-family xlfd)) 274 ("weight" ,(xlfd-weight xlfd)) 275 ("slant" ,(xlfd-slant xlfd)) 276 ("setwidth" ,(xlfd-setwidth xlfd)) 277 ("addstyle" ,(xlfd-addstyle xlfd)) 278 ("pixelsize" ,(xlfd-pixel-size xlfd)) 279 ("pointsize" ,(xlfd-point-size xlfd)) 280 ("resx" ,(xlfd-res-x xlfd)) 281 ("resy" ,(xlfd-res-y xlfd)) 282 ("spacing" ,(xlfd-spacing xlfd)) 283 ("avgwidth" ,(xlfd-avgwidth xlfd)) 284 ("registry" ,(xlfd-registry xlfd)) 285 ("encoding" ,(xlfd-encoding xlfd)) 286 ) 287 ) 288 (if (cadr element) 289 (setq values (append values element)) 290 ) 291 ) 292 ) 293 (dolist 294 (element 295 `( 296 ("font" ,(synprop-font synprop)) 297 ("foreground" ,(synprop-foreground synprop)) 298 ("background" ,(synprop-background synprop)) 299 ) 300 ) 301 (if (cadr element) 302 (setq values (append values element)) 303 ) 304 ) 305 306 ;; Boolean attributes. These can be specified in the format 307 ;; <name>=<anything>, but do a nicer output as the format 308 ;; <name> is accepted. 309 (dolist 310 (element 311 `( 312 ("underline" ,(synprop-underline synprop)) 313 ("overstrike" ,(synprop-overstrike synprop)) 314 ("subscript" ,(synprop-subscript synprop)) 315 ("superscript" ,(synprop-superscript synprop)) 316 ) 317 ) 318 (if (cadr element) 319 (setq booleans (append booleans element)) 320 ) 321 ) 322 323 ;; Play with format conditionals, list iteration, and goto, to 324 ;; make resulting string. 325 (format 326 nil 327 "~A~:[~;?~]~:[~3*~;~A=~A~{&~A=~A~}~]~:[~;&~]~:[~2*~;~A~{&~A~*~}~]" 328 329 (synprop-name synprop) ;; ~A 330 (or values booleans) ;; ~:[~;?~] 331 values ;; ~:[ 332 (car values) (cadr values) (cddr values) ;; ~A=~A~{&~A=~A~} 333 (and values booleans) ;; ~:[~;&~] 334 booleans ;; ~:[ 335 (car booleans) (cddr booleans) ;; ~A~{&~A~*~} 336 ) 337) 338 339 340;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 341;; Use xedit protocol to create a XawTextPropertyList with the 342;; given arguments. 343;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 344(defun compile-syntax-property-list (name properties 345 &aux string-properties quark) 346 347 ;; Create a string representation of the properties. 348 (dolist (property properties) 349 (setq 350 string-properties 351 (append 352 string-properties 353 (list (synprop-to-string property)) 354 ) 355 ) 356 ) 357 358 (setq 359 string-properties 360 (case (length string-properties) 361 (0 "") 362 (1 (car string-properties)) 363 (t (format nil "~A~{,~A~}" 364 (car string-properties) 365 (cdr string-properties) 366 ) 367 ) 368 ) 369 ) 370 371#+debug 372 (format *output* "~Cconvert-property-list ~S ~S~%" 373 *escape* 374 name 375 string-properties 376 ) 377 (setq quark #-debug (convert-property-list name string-properties) 378 #+debug 0) 379 380 ;; Store the quark for properties not yet "initialized". 381 ;; XXX This is just a call to Xrm{Perm,}StringToQuark, and should 382 ;; be made available if there were a wrapper/interface to 383 ;; that Xlib function. 384 (dolist (property properties) 385 (unless (integerp (synprop-quark property)) 386#+debug 387 (format *output* "~Cxrm-string-to-quark ~S~%" 388 *escape* 389 (synprop-name property) 390 ) 391 (setf 392 (synprop-quark property) 393#-debug (xrm-string-to-quark (synprop-name property)) 394#+debug 0 395 ) 396 ) 397 ) 398 399 quark 400) 401 402 403 404 405#+debug 406(progn 407 (defconstant *escape* #\$) 408 409 (defconstant *output* *standard-output*) 410 411 ;; Recognized identifiers for wrap mode. 412 (defconstant *wrap-modes* '(:never :line :word)) 413 414 ;; Recognized identifiers for justification. 415 (defconstant *justifications* '(:left :right :center :full)) 416 417 ;; XawTextScanType 418 (defconstant *scan-type* 419 '(:positions :white-space :eol :paragraph :all :alpha-numeric)) 420 421 ;; XawTextScanDirection 422 (defconstant *scan-direction* '(:left :right)) 423 424 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 425 ;; Debugging version of xedit functions. 426 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 427 (defun clear-entities (left right) 428 (format *output* "~Cclear-entities ~D ~D~%" 429 *escape* left right)) 430 431 (defun add-entity (offset length identifier) 432 (format *output* "~Cadd-entity ~D ~D ~D~%" 433 *escape* offset length identifier)) 434 435 (defun background (&optional (value nil specified)) 436 (if specified 437 (format *output* "~Cset-background ~S~%" *escape* value) 438 (format *output* "~Cget-background~%" *escape*))) 439 440 (defun foreground (&optional (value nil specified)) 441 (if specified 442 (format *output* "~Cset-foreground ~S~%" *escape* value) 443 (format *output* "~Cget-foreground~%" *escape*))) 444 445 (defun font (&optional (value nil specified)) 446 (if specified 447 (format *output* "~Cset-font ~S~%" *escape* value) 448 (format *output* "~Cget-font~%" *escape*))) 449 450 (defun point (&optional (value nil specified)) 451 (if specified 452 (format *output* "~Cset-point ~D~%" *escape* value) 453 (format *output* "~Cget-point~%" *escape*))) 454 455 (defun point-min () 456 (format *output* "~Cpoint-min~%" *escape*)) 457 458 (defun point-max () 459 (format *output* "~Cpoint-max~%" *escape*)) 460 461 (defun property-list (&optional (quark nil specified)) 462 (format *output* "~property-list ~D~%" *escape* quark)) 463 464 (defun insert (string) 465 (format *output* "~Cinsert ~S~%" *escape* string)) 466 467 (defun read-text (offset length) 468 (format *output* "~Cread-text ~D ~D~%" 469 *escape* offset length)) 470 471 (defun replace-text (left right string) 472 (format *output* "~Creplace-text ~D ~D ~S~%" 473 *escape* left right string)) 474 475 (defun scan (offset type direction &key (count 1) include) 476 (unless (setq type (position type *scan-type*)) 477 (error "SCAN: type must be one of ~A, not ~A" 478 *scan-type* type)) 479 (unless (setq direction (position direction *scan-direction*)) 480 (error "SCAN: direction must be one of ~A, not ~A" 481 *scan-direction* direction)) 482 (format *output* "~Cscan ~D ~D ~D ~D ~D~%" 483 *escape* offset type direction count (if include 1 0))) 484 485 (defun search-forward (string &optional case-sensitive) 486 (format *output* "~Csearch-forward ~S ~D~%" 487 *escape* string (if case-sensitive 1 0))) 488 489 (defun search-backward (string &optional case-sensitive) 490 (format *output* "~Csearch-backward ~S ~D~%" 491 *escape* string (if case-sensitive 1 0))) 492 493 (defun wrap-mode (&optional (value nil specified)) 494 (if specified 495 (progn 496 (unless (member value *wrap-modes*) 497 (error "WRAP-MODE: argument must be one of ~A, not ~A" 498 *wrap-modes* value)) 499 (format *output* "~Cset-wrap-mode ~S~%" 500 *escape* (string value))) 501 (format *output* "~Cget-wrap-mode~%" *escape*))) 502 503 (defun auto-fill (&optional (value nil specified)) 504 (if specified 505 (format *output* "~Cset-auto-fill ~S~%" 506 *escape* (if value "true" "false")) 507 (format *output* "~Cget-auto-fill~%" *escape*))) 508 509 (defun justification (&optional (value nil specified)) 510 (if specified 511 (progn 512 (unless (member value *justifications*) 513 (error "JUSTIFICATION: argument must be one of ~A, not ~A" 514 *justifications* value)) 515 (format *output* "~Cset-justification ~S~%" 516 *escape* (string value))) 517 (format *output* "~Cget-justification~%" *escape*))) 518 519 (defun left-column (&optional (value nil specified)) 520 (if specified 521 (format *output* "~Cset-left-column ~D~%" *escape* value) 522 (format *output* "~Cget-left-column~%" *escape*))) 523 524 (defun right-column (&optional (value nil specified)) 525 (if specified 526 (format *output* "~Cset-right-column ~D~%" *escape* value) 527 (format *output* "~Cget-right-column~%" *escape*))) 528 529 (defun vertical-scrollbar (&optional (value nil specified)) 530 (if specified 531 (format *output* "~Cset-vert-scrollbar ~S~%" 532 *escape* (if value "always" "never")) 533 (format *output* "~Cget-vert-scrollbar~%" *escape*))) 534 535 (defun horizontal-scrollbar (&optional (value nil specified)) 536 (if specified 537 (format *output* "~Cset-horiz-scrollbar ~S~%" 538 *escape* (if value "always" "never")) 539 (format *output* "~Cget-horiz-scrollbar~%" *escape*))) 540 541 #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 542 (defun create-buffer (name) 543 (format *output* "~Ccreate-buffer ~S~%" *escape* name)) 544 545 (defun remove-buffer (name) 546 (format *output* "~Cremove-buffer ~S~%" *escape* name)) 547 548 (defun buffer-name (&optional (value nil specified)) 549 (if specified 550 (format *output* "~Cset-buffer-name ~S~%" *escape* value) 551 (format *output* "~Cget-buffer-name~%" *escape*))) 552 553 (defun buffer-filename (&optional (value nil specified)) 554 (if specified 555 (format *output* "~Cset-buffer-filename ~S~%" 556 *escape* (namestring value)) 557 (format *output* "~Cget-buffer-filename~%" *escape*))) 558 559 (defun current-buffer (&optional (value nil specified)) 560 (if specified 561 (format *output* "~Cset-current-buffer ~S~%" *escape* value) 562 (format *output* "~Cget-current-buffer~%" *escape*))) 563 564 (defun other-buffer (&optional (value nil specified)) 565 (if specified 566 (format *output* "~Cset-other-buffer ~S~%" *escape* value) 567 (format *output* "~Cget-other-buffer~%" *escape*))) 568 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||# 569) 570