~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to gcl-tk/tinfo.lsp

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;; Copyright (C) 1994 W. Schelter
 
2
 
 
3
;; This file is part of GNU Common Lisp, herein referred to as GCL
 
4
;;
 
5
;; GCL is free software; you can redistribute it and/or modify it under
 
6
;;  the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
 
7
;; the Free Software Foundation; either version 2, or (at your option)
 
8
;; any later version.
 
9
;; 
 
10
;; GCL is distributed in the hope that it will be useful, but WITHOUT
 
11
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
12
;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
 
13
;; License for more details.
 
14
;; 
 
15
 
 
16
(in-package "TK")
 
17
 
 
18
 
 
19
 
 
20
(eval-when (compile eval)
 
21
(defmacro f (op x y)
 
22
   `(the ,(if  (get op 'compiler::predicate)  't 'fixnum)
 
23
         (,op (the fixnum ,x) (the fixnum ,y))))
 
24
(defmacro while (test &body body)
 
25
  `(sloop while ,test do ,@ body))
 
26
 
 
27
(or (boundp '*info-window*)
 
28
    (si::aload "info"))
 
29
)
 
30
(defun simple-listbox (w)
 
31
  (let ((listbox (conc w '.frame.list))
 
32
        (scrollbar(conc w '.frame.scroll)))
 
33
    (frame (conc w '.frame))
 
34
    (scrollbar scrollbar :relief "sunken" :command
 
35
               (tk-conc w ".frame.list yview"))
 
36
    (listbox listbox :yscroll (tk-conc w ".frame.scroll set")
 
37
             :relief "sunken"
 
38
             :setgrid 1)
 
39
    (pack scrollbar :side "right" :fill "y")
 
40
    (pack listbox :side "left" :expand "yes" :fill "both"))
 
41
  (conc w '.frame))
 
42
  
 
43
  
 
44
(defun insert-standard-listbox (w lis &aux print-entry)
 
45
  (funcall w :delete 0 'end)
 
46
  (setf (get w 'list) lis)
 
47
  (setq print-entry (get w 'print-entry))
 
48
  (dolist (v lis)
 
49
          (funcall w :insert 'end
 
50
                   (if print-entry (funcall print-entry v) v))))
 
51
 
 
52
(defun listbox-move (win key |%y|)
 
53
  |%y|
 
54
  (let ((amt (cdr (assoc key '(("Up" . -1)
 
55
                          ("Down" . 1)
 
56
                          ("Next" . 10)
 
57
                          ("Prior" . -10))
 
58
                         :test 'equal))))
 
59
    (cond (amt
 
60
           (funcall win :yview
 
61
                    (+ (funcall win :nearest 0 :return 'number) amt))))))
 
62
 
 
63
(defun new-window (name &aux tem)
 
64
  (cond ((not  (fboundp name)) name)
 
65
        ((winfo :exists name :return 'boolean)
 
66
         (let ((i 2))
 
67
           (while (winfo :exists (setq tem (conc name i )) :return 'boolean)
 
68
             (setq i (+ i 1)))
 
69
           tem))
 
70
        (t name)))
 
71
 
 
72
 
 
73
(defun insert-info-choices (listbox list &aux file position-pattern prev)
 
74
  (funcall listbox :delete 0 'end)
 
75
    (sloop for i from 0 for name in list 
 
76
                 do  (setq file nil position-pattern nil)
 
77
                 (progn ;decode name
 
78
                   (cond ((and (consp name) (consp (cdr name)))
 
79
                          (setq file (cadr name)
 
80
                                name (car name))))
 
81
                   (cond ((consp name)
 
82
                          (setq position-pattern (car name) name (cdr name)))))
 
83
                 (funcall listbox :insert 'end
 
84
                 (format nil "~@[~a :~]~@[(~a)~]~a." 
 
85
                         position-pattern
 
86
                         (if (eq file prev) nil (setq prev file)) name)))
 
87
  (setf (get listbox 'list)list))
 
88
 
 
89
(defun offer-choices (list info-dirs &optional (w (new-window '.info))
 
90
                           &aux listbox)
 
91
  (toplevel w)
 
92
  (simple-listbox w)
 
93
  (setq listbox (conc w '.frame.list))
 
94
  (insert-info-choices listbox list)
 
95
  (bind listbox "<Double-1>"
 
96
        #'(lambda ()
 
97
            (show-info
 
98
          (nth (atoi (funcall listbox :curselection :return 'string)
 
99
                     0)
 
100
               (get listbox 'list)))))
 
101
  (button (conc w '.ok)  :text "Quit " :command `(destroy ',w))
 
102
  (frame (conc w '.apro))
 
103
  (label(conc w '.apro.label) :text "Apropos: ")
 
104
  (entry (conc w '.apro.entry) :relief "sunken")
 
105
  (pack  (conc w '.apro.label) (conc w '.apro.entry) :side "left"
 
106
        :expand "yes")
 
107
  (pack
 
108
      (conc w '.frame) (conc w '.ok)
 
109
      (conc w '.apro) :side "top" :fill "both")
 
110
  (bind (conc w '.apro.entry) "<KeyPress-Return>"
 
111
        #'(lambda()
 
112
            (insert-info-choices
 
113
             listbox
 
114
             (info-aux  (funcall (conc w '.apro.entry)
 
115
                                 :get :return 'string)
 
116
                         info-dirs)
 
117
             )))
 
118
  (bind  w "<Enter>" `(focus ',(conc w '.apro.entry)))
 
119
  w
 
120
)
 
121
 
 
122
 
 
123
(defun get-info-apropos (win file type)
 
124
  (cond ((and win
 
125
              (winfo :exists win :return 'boolean))
 
126
         (let ((old (get win 'info-data)))
 
127
           (unless (eq old *current-info-data*)
 
128
                   (setf (get win 'info-data) *current-info-data*)
 
129
                   (funcall (conc win '.frame.list) :delete 0 'end))
 
130
           (raise win)
 
131
           (focus win)
 
132
           win))
 
133
        (t (offer-choices file type nil))))
 
134
(defun show-info-key (win key)
 
135
  (let ((node (get win 'node)) name)
 
136
    (or node (info-error "No Node?"))
 
137
    (setq name  (if
 
138
      (f >= (string-match 
 
139
             (si::string-concatenate key
 
140
                                 #u":[ \t]+([^\n\t,]+)[\n\t,]")
 
141
             (node string node)
 
142
             (node header node)
 
143
             (node begin node))
 
144
         0)
 
145
      (get-match (node string node) 1)))
 
146
    (if name (show-info name nil))))
 
147
(defun mkinfo (&optional (w '.info_text) &aux textwin menu 
 
148
                         )
 
149
  (if (winfo :exists w :return 'boolean) (destroy w))
 
150
  (toplevel w)
 
151
  (wm :title w "Info Text Window")
 
152
  (wm :iconname w "Info")
 
153
  (frame (setq menu (conc w '.menu )):relief "raised" :borderwidth 1)
 
154
  (setq textwin (conc w '.t))
 
155
  (pack  menu  :side "top" :fill "x")
 
156
  (button (conc menu '.quit) :text "Quit" :command
 
157
          `(destroy ',w))
 
158
  
 
159
  (menubutton (conc menu '.file) :text "File" :relief 'raised
 
160
              :menu (conc menu '.File '.m) :underline 0)
 
161
  (menu (conc menu '.file '.m))
 
162
  (funcall (conc menu '.file '.m)
 
163
           :add 'command
 
164
           :label "Hotlist"
 
165
           :command '(show-info (tk-conc "("(default-info-hotlist)
 
166
                                         ")")
 
167
                                nil))
 
168
  (funcall (conc menu '.file '.m)
 
169
           :add 'command
 
170
           :label "Add to Hotlist"
 
171
           :command `(add-to-hotlist ',textwin))
 
172
  (funcall (conc menu '.file '.m)
 
173
           :add 'command
 
174
           :label "Top Dir"
 
175
           :command `(show-info "(dir)" nil))
 
176
 
 
177
  (button (conc menu '.next) :text "Next" :relief 'raised
 
178
          :command `(show-info-key ',textwin "Next"))
 
179
  (button (conc menu '.prev) :text "Previous" :relief 'raised
 
180
          :command `(show-info-key ',textwin "Prev"))
 
181
  (button (conc menu '.up) :text "Up" :relief 'raised
 
182
          :command `(show-info-key ',textwin "Up"))
 
183
  (button (conc menu '.info) :text "Info" :relief 'raised
 
184
          :command `(if (winfo :exists ".info")
 
185
                        (raise '.info)
 
186
                      (offer-choices nil si::*default-info-files*)
 
187
                      ))
 
188
  (button (conc menu '.last) :text "Last" :relief 'raised
 
189
          :command `(info-show-history ',textwin 'last))
 
190
  (button (conc menu '.history) :text "History" :relief 'raised
 
191
          :command `(info-show-history ',textwin 'history))
 
192
 
 
193
  (pack  (conc menu '.file)
 
194
         (conc menu '.quit)  (conc menu '.next)  (conc menu '.prev)
 
195
          (conc menu '.up)  (conc menu '.prev)  
 
196
          (conc menu '.last)      (conc menu '.history) (conc menu '.info)
 
197
          :side "left")
 
198
;  (entry (conc menu '.entry) :relief "sunken")
 
199
;  (pack (conc menu '.entry) :expand "yes" :fill "x")
 
200
 
 
201
;  (pack    (conc menu '.next) 
 
202
;         :side "left")
 
203
  
 
204
  
 
205
  (bind  w "<Enter>" `(focus ',menu))
 
206
  
 
207
;  (tk-menu-bar menu (conc menu '.next) )
 
208
;  (bind menu "<Any-M-KeyPress>" "tk_traverseToMenu %W %A")
 
209
  (scrollbar (conc w '.s) :relief "flat" :command (tk-conc w ".t yview"))
 
210
  (text textwin :relief "raised" :bd 2
 
211
                 :setgrid "true"
 
212
         :state 'disabled)
 
213
  (funcall textwin  :configure 
 
214
         :yscrollcommand
 
215
         (scroll-set-fix-xref-closure
 
216
          textwin
 
217
          (conc w '.s))
 
218
         )
 
219
  
 
220
  (bind menu "<KeyPress-n>" `(show-info-key ',textwin "Next"))
 
221
  (bind menu "<KeyPress-u>" `(show-info-key ',textwin "Up"))
 
222
  (bind menu "<KeyPress-p>" `(show-info-key ',textwin "Prev"))
 
223
  (bind menu "<KeyPress-l>"  (nth 4(funcall (conc menu '.last)
 
224
                                     :configure :command :return
 
225
                                     'list-strings)))
 
226
 
 
227
;; SEARCHING: this needs to be speeded up and fixed.
 
228
;  (bind (conc menu '.entry) "<KeyPress>"
 
229
;       `(info-text-search ',textwin ',menu %W %A %K))
 
230
;  (bind (conc menu '.entry) "<Control-KeyPress>"
 
231
;       `(info-text-search ',textwin ',menu %W %A %K))
 
232
            
 
233
;  (bind menu "<KeyPress-s>" #'(lambda () (focus (menu '.entry))))
 
234
            
 
235
            
 
236
        
 
237
 
 
238
  (pack (conc w '.s) :side 'right :fill "y")
 
239
  (pack textwin :expand 'yes :fill 'both)
 
240
  (funcall textwin :mark 'set 'insert 0.0)
 
241
  (funcall textwin :tag :configure 'bold
 
242
           :font :Adobe-Courier-Bold-O-Normal-*-120-*)
 
243
  (funcall textwin :tag :configure 'big :font
 
244
           :Adobe-Courier-Bold-R-Normal-*-140-*)
 
245
  (funcall textwin :tag :configure 'verybig :font
 
246
           :Adobe-Helvetica-Bold-R-Normal-*-240-*)
 
247
  (funcall textwin :tag :configure 'xref
 
248
           :font :Adobe-Courier-Bold-O-Normal-*-120-* )
 
249
  (funcall textwin :tag :configure 'current_xref
 
250
           :underline 1 )
 
251
  (funcall textwin :tag :bind 'xref "<Enter>"
 
252
  "eval [concat %W { tag add current_xref } [get_tag_range %W xref @%x,%y]]")
 
253
 
 
254
  (funcall textwin :tag :bind 'xref "<Leave>"
 
255
        "%W tag remove current_xref 0.0 end")   
 
256
  (funcall textwin :tag :bind 'xref "<3>" 
 
257
           `(show-this-node ',textwin |%x| |%y|))
 
258
  (focus menu)
 
259
;;    (bind w "<Any-Enter>" (tk-conc "focus " w ".t"))
 
260
  )
 
261
 
 
262
 
 
263
(defun info-text-search (textwin menu entry a k &aux again
 
264
                                 (node (get textwin 'node)))
 
265
  (or node (tk-error "cant find node index"))
 
266
;  (print (list entry a k ))
 
267
  (cond ((equal k "Delete")
 
268
         (let ((n (funcall entry :index 'insert :return 'number)))
 
269
           (funcall entry :delete  (- n 1))))
 
270
        ((>= (string-match "Control" k) 0))
 
271
        ((equal a "") (setq again 1))
 
272
        ((>= (string-match "[^-]" a) 0)
 
273
         (funcall entry :insert 'insert a) (setq again 0))
 
274
        (t (focus menu) ))
 
275
  (or again (return-from info-text-search nil))
 
276
  (print (list 'begin-search  entry a k ))
 
277
  
 
278
  (let* (
 
279
         (ind (funcall textwin :index 'current :return 'string))
 
280
         (pos (index-to-position ind
 
281
                                 (node string node)
 
282
                                 (node  begin node)
 
283
                                 (node  end node)
 
284
                                 
 
285
                                 ))
 
286
         (where 
 
287
          (info-search (funcall entry :get :return 'string)
 
288
                       (+ again (node-offset node) pos))))
 
289
    ;; to do mark region in reverse video...
 
290
    (cond ((>= where 0)
 
291
           (let ((node (info-node-from-position where)))
 
292
             (print-node node (- where (node-offset node)))))
 
293
          (t (funcall entry :flash )))))
 
294
 
 
295
(defvar *last-history* nil)
 
296
(defun print-node (node initial-offset &aux last)
 
297
;  "print text from node possibly positioning window at initial-offset
 
298
;from beginning of node"
 
299
 
 
300
  (setq last (list node  initial-offset))
 
301
  (let ((text '.info_text) textwin tem)
 
302
    (or (winfo :exists text :return 'boolean)
 
303
        (mkinfo text))
 
304
    (setq 
 
305
          textwin (conc text '.t))
 
306
    (funcall textwin :configure :state 'normal)
 
307
    (cond ((get textwin 'no-record-history)
 
308
           (remprop textwin 'no-record-history))
 
309
          ((setq tem (get textwin 'node))
 
310
           (setq *last-history* nil)
 
311
           (push 
 
312
            (format nil #u"* ~a:\t(~a)~a.\tat:~a"
 
313
                  (node name tem)
 
314
                      (node file tem)
 
315
                      (node name tem)
 
316
                       (funcall textwin :index "@0,0" :return 'string)
 
317
                       )
 
318
                 (get textwin 'history))))
 
319
    (setf (get textwin 'node) node)
 
320
    (funcall textwin :delete 0.0 'end)
 
321
    (funcall textwin :mark :set 'insert "1.0")
 
322
    (cond ((> initial-offset 0)
 
323
           ;; insert something to separate the beginning of what
 
324
           ;; we want to show and what goes before.
 
325
           (funcall textwin :insert "0.0" #u"\n")
 
326
           (funcall textwin :mark :set 'display_at 'end)
 
327
           (funcall textwin :mark :set 'insert  'end)
 
328
           (funcall textwin :yview 'display_at)
 
329
           (insert-fontified textwin (node string node)
 
330
                             (+  (node begin node) initial-offset)
 
331
                             (node end node))
 
332
           (funcall textwin :mark :set 'insert "0.0")
 
333
           (insert-fontified textwin (node string node)
 
334
                             (node begin node)
 
335
                             (+     (node begin node) initial-offset))
 
336
)
 
337
          (t
 
338
           (insert-fontified textwin (node string node)
 
339
                             (node begin node)
 
340
                             (node end node))))
 
341
    (funcall textwin :configure :state 'disabled)
 
342
    (raise text)
 
343
    textwin
 
344
    ))
 
345
 
 
346
 
 
347
 
 
348
(defun info-show-history (win type)
 
349
  (let ((his (get win 'history)))
 
350
    (cond ((stringp type)
 
351
           (if (f >= (string-match #u":\t([^\t]+)[.]\tat:([0-9.]+)" type) 0)
 
352
               (let ((pos (get-match type 2))
 
353
                     (w (show-info (get-match type 1) nil)))
 
354
                 (setf (get win 'no-record-history) t)
 
355
                 (or (equal "1.0" pos)
 
356
                     (funcall w :yview pos)))))
 
357
          ((eq type 'last)
 
358
           (info-show-history win (if *last-history*
 
359
                                      (pop *last-history*)
 
360
                                    (progn (setq *last-history*
 
361
                                                 (get win 'history))
 
362
                                           (pop *last-history*)))))
 
363
          ((eq type 'history)
 
364
           (let* ((w '.info_history)
 
365
                  (listbox (conc w '.frame.list)))
 
366
             (cond ((winfo :exists w :return 'boolean))
 
367
                   (t
 
368
                    (toplevel w)
 
369
                    (simple-listbox w)
 
370
                    (button (conc w '.quit) :text "Quit" :command
 
371
                            `(destroy ',w))
 
372
                    (pack (conc w '.frame) (conc w '.quit)
 
373
                          :expand "yes" :fill 'both)
 
374
                          ))
 
375
             (insert-standard-listbox listbox  his)
 
376
             (raise w)
 
377
             (bind listbox "<Double-1>" `(info-show-history
 
378
                                          ',listbox
 
379
                                          (car (selection :get
 
380
                                                          :return
 
381
                                                          'list-strings)))))))))
 
382
 
 
383
 
 
384
 
 
385
(defun show-this-node (textwin x y)
 
386
 (let ((inds (get_tag_range  textwin  'xref "@": x :",": y  :return
 
387
                      'list-strings)))
 
388
   (cond ((and inds (listp inds) (eql (length inds) 2))
 
389
          (show-info (nsubstitute #\space #\newline
 
390
                             (apply textwin :get :return 'string  inds))
 
391
                     nil))
 
392
         (t (print inds)))))
 
393
 
 
394
(defun scroll-set-fix-xref-closure (wint wins &aux prev)
 
395
  #'(lambda (&rest l)
 
396
      (or (equal l prev)
 
397
          (progn (setq prev l)
 
398
                 (fix-xref wint)
 
399
                 (apply wins :set l)))))
 
400
 
 
401
 
 
402
(defvar *recursive* nil)
 
403
 
 
404
;(defun fix-xref-faster (win &aux   (all'(" ")) tem)
 
405
;  (unless
 
406
;   *recursive*
 
407
;   (let* ((*recursive* t) s
 
408
;         (pat #u"\n\\* ([^:\n]+)::|\n\\* [^:\n]+:[ \t]*(\\([^,\n\t]+\\)[^,.\n\t]*)[^\n]?|\n\\* [^:\n]+:[ \t]*([^,(.\n\t]+)[^\n]?")
 
409
;         (beg (funcall win :index "@0,0 linestart -1 char" :return 'string))
 
410
;         (end (funcall win :index "@0,1000 lineend" :return 'string)))
 
411
;     (cond ((or (f >= (string-match "possible_xref"
 
412
;                   (funcall win :tag :names beg :return 'string)) 0)
 
413
;               (not (equal ""
 
414
;                           (setq tem (funcall win :tag :nextrange "possible_xref" beg end
 
415
;                                       :return 'string)))))
 
416
;           (if tem (setq beg (car (list-string tem))))
 
417
;           (let ((s (funcall win :get beg end :return 'string))
 
418
;                 (j 0) i)
 
419
;             (with-tk-command
 
420
;              (pp "MultipleTagAdd" no_quote)
 
421
;              (pp win normal)
 
422
;              (pp "xref" normal)
 
423
;              (pp beg normal)
 
424
;              (pp "{" no_quote)
 
425
;              (while (f >= (string-match pat s j) 0)
 
426
;                (setq i (if (f >= (match-beginning 1) 0) 1 2))
 
427
;                (pp (match-beginning i) no_quote)
 
428
;                (pp (match-end i) no_quote)
 
429
;                (setq j (match-end 0))
 
430
;                )
 
431
;              (pp "}" no_quote)
 
432
;              (send-tcl-cmd *tk-connection* tk-command nil)))
 
433
;           (funcall win :tag :remove "possible_xref" beg end)
 
434
;           )))))
 
435
 
 
436
(defun fix-xref (win &aux    tem)
 
437
  (unless
 
438
   *recursive*
 
439
   (let* ((*recursive* t) 
 
440
          (pat #u"\n\\* ([^:\n]+)::|\n\\* [^:\n]+:[ \t]*(\\([^,\n\t]+\\)[^,.\n\t]*)[^\n]?|\n\\* [^:\n]+:[ \t]*([^,(.\n\t]+)[^\n]?")
 
441
          (beg (funcall win :index "@0,0 linestart -1 char" :return 'string))
 
442
          (end (funcall win :index "@0,1000 lineend" :return 'string)))
 
443
     (cond ((or (f >= (string-match "possible_xref"
 
444
                    (funcall win :tag :names beg :return 'string)) 0)
 
445
                (not (equal ""
 
446
                            (setq tem (funcall win :tag :nextrange
 
447
                                               "possible_xref" beg end
 
448
                                        :return 'string)))))
 
449
            (if tem (setq beg (car (list-string tem))))
 
450
            (let ((s (funcall win :get beg end :return 'string))
 
451
                  (j 0) i)
 
452
              (while (f >= (string-match pat s j) 0)
 
453
                (setq i
 
454
                      (if (f >= (match-beginning 1) 0) 1
 
455
                         (if (f >= (match-beginning 2) 0) 2
 
456
                           3)))
 
457
                (funcall win :tag :add "xref"
 
458
                         beg : "+" : (match-beginning i) : " chars"
 
459
                         beg : "+" : (match-end i) : " chars")
 
460
                (setq j (match-end 0))))
 
461
            (funcall win :tag :remove "possible_xref" beg end)
 
462
            )))))
 
463
 
 
464
(defun insert-fontified (window string beg end)
 
465
  "set fonts in WINDOW for string with "
 
466
;  (waiting window)
 
467
;  (print (list beg end))
 
468
  (insert-string-with-regexp
 
469
   window string beg end
 
470
   #u"\n([^\n]+)\n[.=_*-][.=*_-]+\n|\\*Note ([^:]+)::"
 
471
   '((1 section-header)
 
472
     (2 "xref")
 
473
     ))
 
474
  (funcall window :tag :add "possible_xref" "0.0" "end")
 
475
  (fix-xref window)
 
476
  (end-waiting window)
 
477
   )
 
478
 
 
479
(defun section-header (win string lis &aux (i (car lis)))
 
480
  (let ((mark 'insert))
 
481
    (insert-string win  string (match-beginning 0)
 
482
                   (match-end i))
 
483
    (funcall win :insert mark #u"\n")
 
484
    (funcall win :tag :add
 
485
             (cdr (assoc (aref string (f + (match-end i) 2))
 
486
                         '((#\= . "verybig")
 
487
                           (#\_ . "big")
 
488
                           (#\- . "big")
 
489
                           (#\. . "bold")
 
490
                           (#\* . "bold")
 
491
                           )))  
 
492
             "insert - " : (f - (match-end i) (f + (match-beginning i ) -1 ))
 
493
             : " chars"
 
494
             "insert -1 chars")
 
495
    ;;make index count be same..
 
496
    (let ((n (f - (f - (match-end 0)
 
497
                     (match-end i)) 1)))
 
498
      (declare (fixnum n))
 
499
      (if (>= n 0)
 
500
          (funcall win :insert mark (make-string n )))
 
501
      )))
 
502
 
 
503
 
 
504
(defun insert-string (win string beg end)
 
505
  (and (> end beg)
 
506
  (let ((ar (make-array  (- end beg) :element-type 'string-char
 
507
                        :displaced-to string :displaced-index-offset beg)))
 
508
    (funcall win :insert 'insert ar))))
 
509
 
 
510
(defun insert-string-with-regexp (win string beg  end regexp reg-actions
 
511
                                      &aux (i 0) temi 
 
512
                                      (*window* win) *match-data*)
 
513
  (declare (special *window* *match-data*))
 
514
  (declare (fixnum beg end i))
 
515
  (while (f >= (string-match regexp string beg end) 0)
 
516
    (setq i 1)
 
517
    (setq temi nil)
 
518
    (loop (or (< i 10) (return nil))
 
519
      (cond ((f >= (match-beginning i) 0)
 
520
             (setq temi (assoc i reg-actions))
 
521
             (return nil)))
 
522
      (setq i (+ i 1)))
 
523
    (cond ;(t nil)
 
524
          ((functionp (second temi))
 
525
           (insert-string win string beg (match-beginning 0))
 
526
           (funcall (second temi) win string temi))
 
527
          ((stringp (second temi))
 
528
           (insert-string win string beg (match-end 0))
 
529
           (dolist
 
530
            (v (cdr temi))
 
531
            (funcall win :tag :add v
 
532
                     "insert -" : (f - (match-end 0) (match-beginning i)) : " chars"
 
533
                     "insert -" :(f - (match-end 0) (match-end i)): " chars"
 
534
 
 
535
                     )
 
536
            ))
 
537
          (t (info-error "bad regexp prop")))
 
538
    (setq beg (match-end 0))
 
539
    (or (<= beg end) (error "hi")) 
 
540
    )
 
541
  (insert-string win string beg end))
 
542
 
 
543
(defun count-char (ch string beg end &aux (count 0))
 
544
;  "Count the occurrences of CH in STRING from BEG to END"
 
545
  (declare (character ch))
 
546
  (declare (string string))
 
547
  (declare (fixnum beg end count))
 
548
  (while (< beg end)
 
549
    (if (eql (aref string beg) ch) (incf count))
 
550
    (incf beg))
 
551
  count)
 
552
 
 
553
(defun start-of-ith-line (count string beg &optional (end -1))
 
554
  (declare (string string))
 
555
  (declare (fixnum beg end count))
 
556
  (if (< end 0) (setq end (length string)))
 
557
  (cond ((eql count 1) beg)
 
558
        (t (decf count)
 
559
         (while (< beg end)
 
560
           (if (eql (aref string beg) #\newline)
 
561
               (progn (decf count)
 
562
                      (incf beg)
 
563
                      (if (<= count 0) (return-from start-of-ith-line beg)))
 
564
             (incf beg)))
 
565
         beg)))
 
566
  
 
567
(defun index-to-position (index string beg &optional (end -1) &aux (count 0))
 
568
; "Find INDEX of form \"line.char\" in STRING with 0.0 at BEG  and
 
569
;   up to END.  Result is a fixnum string index"
 
570
  (declare (string string index))
 
571
  (declare (fixnum beg end count))
 
572
  (if (< end 0) (setq end (length string)))
 
573
  (let* ((line (atoi index 0))
 
574
         (charpos (atoi index (+ 1 (position #\. index)))))
 
575
    (declare (fixnum line charpos))
 
576
    (setq count (start-of-ith-line line string beg end))
 
577
    (print (list count charpos))
 
578
    (+ count charpos)))
 
579
 
 
580
 
 
581
 
 
582
;;; Local Variables: ***
 
583
;;; mode:lisp ***
 
584
;;; version-control:t ***
 
585
;;; comment-column:0 ***
 
586
;;; comment-start: ";;; " ***
 
587
;;; End: ***
 
588