-
Notifications
You must be signed in to change notification settings - Fork 0
/
yatexhie.el
429 lines (397 loc) · 14.9 KB
/
yatexhie.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
;;; yatexhie.el --- YaTeX hierarchy browser
;;;
;;; (c)1995-2013 by HIROSE Yuuji [[email protected]]
;;; Last modified Mon Apr 1 22:43:34 2013 on firestorm
;;; $Id$
;;; Code:
;; ----- Customizable variables -----
(defvar YaTeX-hierarchy-ignore-heading-regexp
"\\$[A-Z][a-z]+: .* \\$\\|-\\*- .* -\\*-"
"*Regexp of lines to ignore as files' headline.")
;; ----- General variables -----
(defvar YaTeX-default-TeX-extensions "\\.\\(tex\\|sty\\)")
(defvar YaTeX-hierarchy-current-main nil)
(defvar YaTeX-hierarchy-buffer-message
(concat
"n)ext p)rev N)extsame P)revsame u)p K)illbuf RET)select"
(if (and YaTeX-emacs-19 window-system) " Mouse2)select" "")
" ?)help"))
(defvar YaTeX-hierarchy-saved-wc nil "Saved window configuration.")
;; ----- Functions for parsing hierarchy -----
(defun YaTeX-all-included-files (&optional file)
"Return all included files from FILE as a list.
If FILE is nil, use current buffer."
(save-excursion
(let ((include-regex (concat YaTeX-ec-regexp
"\\(\\(input\\)\\|" ;match#2
"\\(include\\)\\)\\b")) ;match#3
list file (cb (current-buffer)))
(if file (set-buffer (YaTeX-switch-to-buffer file t)))
(goto-char (point-min))
(while (YaTeX-re-search-active-forward
include-regex YaTeX-comment-prefix nil t)
(cond
((match-beginning 2) ;\input, {} is optional, 1 argument
(skip-chars-forward " {")
(setq file (buffer-substring
(point)
(progn
(skip-chars-forward
(concat "^ \t\n\r" YaTeX-ec-regexp "{}"))
(point)))))
((and (match-beginning 3) (looking-at "{"))
(skip-chars-forward "{")
(setq file (buffer-substring
(point)
(progn
(forward-char -1) (forward-list 1) (1- (point)))))))
(or (string-match YaTeX-default-TeX-extensions file)
(setq file (concat file ".tex")))
(setq list (cons file list)))
(set-buffer cb)
(nreverse list))))
(defun YaTeX-document-hierarchy (&optional file basedir)
"Return the document hierarchy beginning from FILE as a list.
If FILE is nil, beginning with current buffer's file."
(setq file (or file buffer-file-name))
(and YaTeX-search-file-from-top-directory
(not (file-exists-p file))
(string-match "^[^/].*/" file)
(setq file (expand-file-name file basedir)))
(message "Parsing [%s]..." (file-name-nondirectory file))
(prog1
(save-excursion
(if (or (file-exists-p file) (null file))
(progn
(if file
(let ((parent buffer-file-name))
(YaTeX-switch-to-buffer file t) ;set buffer to file
(or YaTeX-parent-file
(YaTeX-get-builtin "!")
(setq YaTeX-parent-file parent))))
(cons (buffer-file-name (current-buffer))
(mapcar '(lambda (f) ;return value
(YaTeX-document-hierarchy f basedir))
(YaTeX-all-included-files))))))
(message "Parsing [%s]...done" (file-name-nondirectory file))))
;; ----- Functions for displaying hierarchy -----
(defun YaTeX-hierarchy-get-file-heading (file)
"Get a FILE's heading."
(save-excursion
(set-buffer (find-file-noselect file))
(save-excursion
(let (p)
(goto-char (point-min))
(cond
((re-search-forward
(concat YaTeX-ec-regexp YaTeX-sectioning-regexp) nil t)
(search-forward "{")
(forward-char -1)
(setq p (condition-case nil
(progn (forward-list 1) (1- (point)))
(error (point-end-of-line))))
(goto-char (1+ (match-beginning 0)))
(skip-chars-forward " \t\n")
(buffer-substring (point) (min (point-end-of-line) p)))
((catch 'found
(while (re-search-forward "^ *%\\([^#]\\)" nil t)
(or (re-search-forward
YaTeX-hierarchy-ignore-heading-regexp
(point-end-of-line) t)
(throw 'found t))))
(beginning-of-line)
(search-forward "%")
(skip-chars-forward "% \t")
(buffer-substring (point) (point-end-of-line)))
(t ""))))))
(defun YaTeX-display-a-hierachy (hier level)
"Put a HIER of document hierarchy.
LEVEL is including depth."
(message "Formatting hierarchy buffer...")
(let ((lastatomcol 0) list i p)
(cond
((listp hier)
(setq list hier)
(while list
(YaTeX-display-a-hierachy (car list) (1+ level))
(setq list (cdr list))))
((stringp hier) ;is an atom
(insert " ")
(setq i level)
(while (> i 2)
(insert "| ")
(setq i (1- i)))
(if (> level 1) (insert "+---"))
(setq p (point))
(insert (or (buffer-name (get-file-buffer hier))
(file-name-nondirectory hier)))
(if (and window-system YaTeX-emacs-19)
(put-text-property p (point) 'mouse-face 'underline))
(insert " ")
(indent-to-column (1- (/ (window-width) 2)))
(insert "% " (YaTeX-hierarchy-get-file-heading hier))
(insert "\n"))))
(message "Formatting hierarchy buffer..."))
(defun YaTeX-display-hierarchy (file &optional use-default)
"Display document hierarchy that is beginning from FILE."
(interactive "P")
(setq YaTeX-hierarchy-saved-wc
(list (current-window-configuration)
(and (featurep 'windows)
(boundp 'win:current-config)
win:current-config)))
(let*((b-in (YaTeX-get-builtin "!"))
default)
;;$B$`!<$s"-$3$N$X$s$N;EMM$I$&$7$?$i$$$$$+NI$/J,$+$i$s(B...
(if default (setq default (expand-file-name default)))
(YaTeX-visit-main t) ;move to parent file
(setq default buffer-file-name)
(setq file
(or (if use-default default file)
(read-file-name
(format
"Main .tex file%s: "
(if default
(format "(default %s)"(file-name-nondirectory default))
""))
"" default 1))))
(setq file (expand-file-name file))
(setq YaTeX-hierarchy-current-main file)
(let ((dbuf "*document hierarchy*")
(topdir default-directory))
(YaTeX-showup-buffer dbuf nil t)
(set-buffer (get-buffer dbuf))
(setq truncate-lines t)
(let ((buffer-read-only nil))
(erase-buffer)
(YaTeX-display-a-hierachy (YaTeX-document-hierarchy file topdir) 0))
(goto-char (point-min))
(YaTeX-hierarchy-next 0)
(set-buffer-modified-p nil)
(YaTeX-hierarchy-mode)
))
(defun YaTeX-display-hierarchy-directly ()
"Same as YaTeX-display-hierarchy. Call from mouse."
(interactive)
(YaTeX-display-hierarchy nil t))
(defun YaTeX-hierarchy-mode ()
"Major mode to browse and select document hierarchy.
\\[YaTeX-hierarchy-next] next line
\\[YaTeX-hierarchy-prev] previous line
\\[YaTeX-hierarchy-forward] move forward in the same level
\\[YaTeX-hierarchy-backward] move backward in the same level
\\[YaTeX-hierarchy-up-document] move to parent file
\\[delete-other-windows] delete other windows
\\[other-window] other window
\\[shrink-window] shrink window
\\[enlarge-window] enlarge window
\\[YaTeX-hierarchy-show] show file contents in the next window
\\[YaTeX-hierarchy-scroll-up] scroll up file contents buffer
\\[YaTeX-hierarchy-scroll-down] scroll down file contents buffer
\\[YaTeX-hierarchy-top] show the top of file contents
\\[YaTeX-hierarchy-bottom] show the bottom of file contents
\\[YaTeX-hierarchy-lastpos] return to the previous position
\\[YaTeX-hierarchy-select] select file
\\[YaTeX-hierarchy-mouse-select] select
"
(setq major-mode 'YaTeX-hierarchy-mode
mode-name "YaTeX hier")
(use-local-map YaTeX-hierarchy-mode-map)
(setq buffer-read-only t)
(message YaTeX-hierarchy-buffer-message))
;; ----- Subfunctions for interactive functions -----
(defun YaTeX-hierarchy-get-current-file-buffer ()
"Return the buffer associated with current line's file."
(let ((file (buffer-substring
(point)
(save-excursion
(skip-chars-forward "^ \t" (point-end-of-line)) (point))))
(hilit-auto-highlight) buffer)
(set-buffer (find-file-noselect YaTeX-hierarchy-current-main))
(if (get-buffer file) ;buffer is active
(setq buffer (get-buffer file)) ;may contain `<2>'
(if (string-match "<[2-9]>$" file)
(setq file (substring file 0 -3)))
(save-excursion
(setq buffer (YaTeX-switch-to-buffer file t)))))) ; open it!
;; ----- Interactive functions -----
(defun YaTeX-hierarchy-next (arg &optional quiet)
"Move to next line's file in YaTeX document hierarchy buffer."
(interactive "p")
(forward-line arg)
(skip-chars-forward "- +\\|")
(if (and (/= arg 0) (not quiet))
(YaTeX-hierarchy-select t))
(message YaTeX-hierarchy-buffer-message))
(defun YaTeX-hierarchy-prev (arg)
"Move to previous line's file in YaTeX document hierarchy buffer."
(interactive "p")
(YaTeX-hierarchy-next (- arg)))
(defun YaTeX-hierarchy-next-line (arg)
(interactive "p")
(YaTeX-hierarchy-next arg t))
(defun YaTeX-hierarchy-prev-line (arg)
(interactive "p")
(YaTeX-hierarchy-next (- arg) t))
(defun YaTeX-hierarchy-forward (arg)
"Move to forward file in same hierarchy level."
(interactive "p")
(YaTeX-hierarchy-next 0)
(let ((p (point))(column (current-column)) (i (if (> arg 0) arg (- arg))))
(if (= column 0) (error "Not on file line."))
(while (> i 0)
(if (catch 'found
(while (and (not (eobp)) (not (bobp)))
(forward-line (if (> arg 0) 1 -1))
(move-to-column column)
(if (looking-at "[- +\\|]") nil
(YaTeX-hierarchy-next 0)
(if (= (current-column) column) (throw 'found t)))
(beginning-of-line)))
nil
(goto-char p)
(error "No same level file."))
(setq i (1- i)))))
(defun YaTeX-hierarchy-backward (arg)
"Move to backward file in same hierarchy level."
(interactive "p")
(YaTeX-hierarchy-forward (- arg)))
(defun YaTeX-hierarchy-up-document ()
"Up level, that is, move to parent file position."
(interactive)
(YaTeX-hierarchy-next 0) ;adjust column
(let ((p (point)) (line (count-lines (point-min) (point))) column)
(if (or (<= line 1) (< (current-column) 6))
(message "No more parent")
(backward-char 1)
(or (= (char-after (point)) ?-) (error "Unexpected hierarchy buffer"))
(setq column (current-column))
(while (and (> line 1) (looking-at "[- +\\|]"))
(forward-line -1)
(move-to-column column))
(YaTeX-hierarchy-next 0)
(push-mark p t)
(message "Mark set to last position"))))
(defun YaTeX-hierarchy-kill-buffer (arg)
"Kill buffer associated with current line's file."
(interactive "p")
(YaTeX-hierarchy-next 0) ;move to file name column
(if (bolp) (error "Not on file name line"))
(let ((file (buffer-substring
(point)
(progn (skip-chars-forward "^ \t") (point)))))
(YaTeX-hierarchy-next arg)
(cond
((get-buffer file)
(kill-buffer (get-buffer file))
(message "Buffer [%s] was killed" file))
(t (message "Buffer [%s] is not active." file)))))
(defun YaTeX-hierarchy-select (arg)
"Select current line's file in YaTeX document hierarchy buffer.
If ARG is non-nil, show the buffer in the next window."
(interactive "P")
(beginning-of-line)
(skip-chars-forward "- +\\|")
(or (eolp)
(let ((buffer (YaTeX-hierarchy-get-current-file-buffer)))
(if buffer ;if file was found
(if arg
(YaTeX-showup-buffer buffer nil)
(if (and YaTeX-emacs-19 window-system
(get-buffer-window buffer t))
(goto-buffer-window buffer) ;select currently displaying
(YaTeX-switch-to-buffer-other-window buffer)))))))
(defun YaTeX-hierarchy-show ()
"Show current line's file in the next window."
(interactive)
(YaTeX-hierarchy-select t))
(defun YaTeX-hierarchy-mouse-select (event)
(interactive "e")
(mouse-set-point event)
(YaTeX-hierarchy-select nil))
(defun YaTeX-hierarchy-quit ()
"Quit from YaTeX-hierarchy buffer and restore window configuration."
(interactive)
(if (or (not (featurep 'windows))
(car YaTeX-hierarchy-saved-wc)
(and (= (car (cdr YaTeX-hierarchy-saved-wc)) win:current-config)))
(set-window-configuration (car YaTeX-hierarchy-saved-wc))
(bury-buffer nil)))
(defun YaTeX-hierarchy-scroll-up (arg &optional action)
"Scroll up file contents of YaTeX-hierarchy."
(interactive "P")
(YaTeX-hierarchy-next 0 t)
(let*((bufname (buffer-substring
(point)
(save-excursion (skip-chars-forward "^ \t") (point))))
(buf (get-buffer bufname))
(cw (selected-window)))
(cond
((and buf (get-buffer-window buf))
(select-window (get-buffer-window buf)))
((and buf (YaTeX-showup-buffer buf nil t)) t)
(t (YaTeX-hierarchy-select nil)))
(unwind-protect
(cond
((eq action 'down) (scroll-down arg))
((eq action 'top) (beginning-of-buffer))
((eq action 'bottom) (end-of-buffer))
((eq action 'last) (exchange-point-and-mark))
(t (scroll-up arg)))
(select-window cw))))
(defun YaTeX-hierarchy-scroll-down (arg)
"Scroll down file contents of YaTeX-hierarchy."
(interactive "P")
(YaTeX-hierarchy-scroll-up arg 'down))
(defun YaTeX-hierarchy-top ()
"Show the top of YaTeX-hierarchy inspection buffer's."
(interactive)
(YaTeX-hierarchy-scroll-up nil 'top)
)
(defun YaTeX-hierarchy-bottom ()
"Show the top of YaTeX-hierarchy inspection buffer's."
(interactive)
(YaTeX-hierarchy-scroll-up nil 'bottom)
)
(defun YaTeX-hierarchy-lastpos ()
"Go to last position in YaTeX-hierarchy buffer."
(interactive)
(YaTeX-hierarchy-scroll-up nil 'last)
)
;; ----- Setting up keymap -----
(defvar YaTeX-hierarchy-mode-map nil "Keymap used in YaTeX-hierarchy-mode.")
(if YaTeX-hierarchy-mode-map nil
(setq YaTeX-hierarchy-mode-map (make-sparse-keymap))
(define-key YaTeX-hierarchy-mode-map "n" 'YaTeX-hierarchy-next)
(define-key YaTeX-hierarchy-mode-map "p" 'YaTeX-hierarchy-prev)
(define-key YaTeX-hierarchy-mode-map "j" 'YaTeX-hierarchy-next-line)
(define-key YaTeX-hierarchy-mode-map "k" 'YaTeX-hierarchy-prev-line)
(substitute-all-key-definition
'next-line 'YaTeX-hierarchy-next-line YaTeX-hierarchy-mode-map)
(substitute-all-key-definition
'previous-line 'YaTeX-hierarchy-prev-line YaTeX-hierarchy-mode-map)
(define-key YaTeX-hierarchy-mode-map "N" 'YaTeX-hierarchy-forward)
(define-key YaTeX-hierarchy-mode-map "P" 'YaTeX-hierarchy-backward)
(define-key YaTeX-hierarchy-mode-map "u" 'YaTeX-hierarchy-up-document)
(define-key YaTeX-hierarchy-mode-map "K" 'YaTeX-hierarchy-kill-buffer)
(define-key YaTeX-hierarchy-mode-map "1" 'delete-other-windows)
(define-key YaTeX-hierarchy-mode-map "o" 'other-window)
(define-key YaTeX-hierarchy-mode-map "-" 'shrink-window)
(define-key YaTeX-hierarchy-mode-map "+" 'enlarge-window)
(define-key YaTeX-hierarchy-mode-map "." 'YaTeX-hierarchy-show)
(define-key YaTeX-hierarchy-mode-map " " 'YaTeX-hierarchy-scroll-up)
(define-key YaTeX-hierarchy-mode-map "b" 'YaTeX-hierarchy-scroll-down)
(define-key YaTeX-hierarchy-mode-map "\C-?" 'YaTeX-hierarchy-scroll-down)
(define-key YaTeX-hierarchy-mode-map "\C-m" 'YaTeX-hierarchy-select)
(define-key YaTeX-hierarchy-mode-map "<" 'YaTeX-hierarchy-top)
(define-key YaTeX-hierarchy-mode-map ">" 'YaTeX-hierarchy-bottom)
(define-key YaTeX-hierarchy-mode-map "'" 'YaTeX-hierarchy-lastpos)
(define-key YaTeX-hierarchy-mode-map "g" 'YaTeX-hierarchy-select)
(define-key YaTeX-hierarchy-mode-map "q" 'YaTeX-hierarchy-quit)
(define-key YaTeX-hierarchy-mode-map "?" 'describe-mode)
(if (and YaTeX-emacs-19 window-system)
(define-key YaTeX-hierarchy-mode-map
[mouse-2] 'YaTeX-hierarchy-mouse-select))
)
(provide 'yatexhie)
;;end of yatexhie.el