yuuji@23: ;;; -*- Emacs-Lisp -*- yuuji@23: ;;; YaTeX library of general functions. yuuji@23: ;;; yatexlib.el yuuji@52: ;;; (c )1994-1995 by HIROSE Yuuji.[yuuji@ae.keio.ac.jp] yuuji@59: ;;; Last modified Fri Apr 5 17:56:43 1996 on supra yuuji@23: ;;; $Id$ yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-search-active-forward (string cmntrx &optional bound err cnt func) yuuji@23: "Search STRING which is not commented out by CMNTRX. yuuji@23: Optional arguments after BOUND, ERR, CNT are passed literally to search-forward yuuji@23: or search-backward. yuuji@23: Optional sixth argument FUNC changes search-function." yuuji@49: (let ((sfunc (or func 'search-forward)) found md) yuuji@23: (while (and (prog1 yuuji@23: (setq found (funcall sfunc string bound err cnt)) yuuji@23: (setq md (match-data))) yuuji@23: (or yuuji@23: (YaTeX-in-verb-p (match-beginning 0)) yuuji@23: (save-excursion yuuji@23: (beginning-of-line) yuuji@23: (re-search-forward cmntrx (match-beginning 0) t))))) yuuji@23: (store-match-data md) yuuji@23: found) yuuji@23: ) yuuji@23: yuuji@23: (defun YaTeX-re-search-active-forward (regexp cmntrx &optional bound err cnt) yuuji@23: "Search REGEXP backward which is not commented out by regexp CMNTRX. yuuji@23: See also YaTeX-search-active-forward." yuuji@23: (YaTeX-search-active-forward regexp cmntrx bound err cnt 're-search-forward) yuuji@23: ) yuuji@23: (defun YaTeX-search-active-backward (string cmntrx &optional bound err cnt) yuuji@23: "Search STRING backward which is not commented out by regexp CMNTRX. yuuji@23: See also YaTeX-search-active-forward." yuuji@23: (YaTeX-search-active-forward string cmntrx bound err cnt 'search-backward) yuuji@23: ) yuuji@23: (defun YaTeX-re-search-active-backward (regexp cmntrx &optional bound err cnt) yuuji@23: "Search REGEXP backward which is not commented out by regexp CMNTRX. yuuji@23: See also YaTeX-search-active-forward." yuuji@23: (YaTeX-search-active-forward regexp cmntrx bound err cnt 're-search-backward) yuuji@23: ) yuuji@23: yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-switch-to-buffer (file &optional setbuf) yuuji@23: "Switch to buffer if buffer exists, find file if not. yuuji@23: Optional second arg SETBUF t make use set-buffer instead of switch-to-buffer." yuuji@23: (interactive "Fswitch to file: ") yuuji@52: (if (bufferp file) (setq file (buffer-file-name file))) yuuji@52: (let (buf (hilit-auto-highlight (not setbuf))) yuuji@52: (cond yuuji@52: ((setq buf (get-file-buffer file)) yuuji@52: (funcall (if setbuf 'set-buffer 'switch-to-buffer) yuuji@52: (get-file-buffer file)) yuuji@52: buf) yuuji@52: ((or YaTeX-create-file-prefix-g (file-exists-p file)) yuuji@52: (or ;find-file returns nil but set current-buffer... yuuji@52: (if setbuf (set-buffer (find-file-noselect file)) yuuji@52: (find-file file)) yuuji@52: (current-buffer))) yuuji@52: (t (message "%s was not found in this directory." file) yuuji@23: nil))) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-switch-to-buffer-other-window (file) yuuji@23: "Switch to buffer if buffer exists, find file if not." yuuji@23: (interactive "Fswitch to file: ") yuuji@52: (if (bufferp file) (setq file (buffer-file-name file))) yuuji@52: (cond yuuji@52: ((get-file-buffer file) yuuji@52: (switch-to-buffer-other-window (get-file-buffer file)) yuuji@52: t) yuuji@52: ((or YaTeX-create-file-prefix-g (file-exists-p file)) yuuji@52: (find-file-other-window file) t) yuuji@52: (t (message "%s was not found in this directory." file) yuuji@23: nil)) yuuji@23: ) yuuji@23: yuuji@23: (defun YaTeX-replace-format-sub (string format repl) yuuji@23: (let ((beg (or (string-match (concat "^\\(%" format "\\)") string) yuuji@23: (string-match (concat "[^%]\\(%" format "\\)") string))) yuuji@23: (len (length format))) yuuji@23: (if (null beg) string ;no conversion yuuji@23: (concat yuuji@23: (substring string 0 (match-beginning 1)) repl yuuji@23: (substring string (match-end 1))))) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-replace-format (string format repl) yuuji@23: "In STRING, replace first appearance of FORMAT to REPL as if yuuji@23: function `format' does. FORMAT does not contain `%'" yuuji@23: (let ((ans string)) yuuji@23: (while (not (string= yuuji@23: ans (setq string (YaTeX-replace-format-sub ans format repl)))) yuuji@23: (setq ans string)) yuuji@23: string) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-replace-format-args (string &rest args) yuuji@23: "Translate the argument mark #1, #2, ... #n in the STRING into the yuuji@23: corresponding real arguments ARGS." yuuji@23: (let ((argp 1)) yuuji@23: (while args yuuji@23: (setq string yuuji@23: (YaTeX-replace-format string (int-to-string argp) (car args))) yuuji@23: (setq args (cdr args) argp (1+ argp)))) yuuji@23: string yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun rindex (string char) yuuji@23: (let ((pos (1- (length string)))(index -1)) yuuji@23: (while (>= pos 0) yuuji@23: (cond yuuji@23: ((= (aref string pos) char) yuuji@23: (setq index pos) (setq pos -1)) yuuji@23: (t (setq pos (1- pos)))) yuuji@23: ) yuuji@23: index) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-showup-buffer (buffer &optional func select) yuuji@23: "Make BUFFER show up in certain window (but current window) yuuji@23: that gives the maximum value by the FUNC. FUNC should take an argument yuuji@23: of its window object. Non-nil for optional third argument SELECT selects yuuji@49: that window. This function never selects minibuffer window." yuuji@53: (or (and (if (and YaTeX-emacs-19 select) yuuji@47: (get-buffer-window buffer t) yuuji@47: (get-buffer-window buffer)) yuuji@47: (progn yuuji@47: (if select yuuji@51: (goto-buffer-window buffer)) yuuji@47: t)) yuuji@23: (let ((window (selected-window)) yuuji@23: (wlist (YaTeX-window-list)) win w (x 0)) yuuji@23: (cond yuuji@23: ((> (length wlist) 2) yuuji@23: (if func yuuji@23: (while wlist yuuji@23: (setq w (car wlist)) yuuji@23: (if (and (not (eq window w)) yuuji@23: (> (funcall func w) x)) yuuji@23: (setq win w x (funcall func w))) yuuji@23: (setq wlist (cdr wlist))) yuuji@23: (setq win (get-lru-window))) yuuji@23: (select-window win) yuuji@23: (switch-to-buffer buffer) yuuji@23: (or select (select-window window))) yuuji@23: ((= (length wlist) 2) yuuji@49: ;(other-window 1);This does not work properly on Emacs-19 yuuji@49: (select-window (get-lru-window)) yuuji@23: (switch-to-buffer buffer) yuuji@23: (or select (select-window window))) yuuji@23: (t ;if one-window yuuji@23: (cond yuuji@47: ((and YaTeX-emacs-19 (get-buffer-window buffer t)) yuuji@47: nil) ;if found in other frame yuuji@23: (YaTeX-default-pop-window-height yuuji@51: (split-window-calculate-height YaTeX-default-pop-window-height) yuuji@59: ;;(pop-to-buffer buffer) ;damn! emacs-19.30 yuuji@59: (select-window (next-window nil 1)) yuuji@59: (switch-to-buffer (get-buffer-create buffer)) yuuji@23: (or select (select-window window))) yuuji@23: (t nil))) yuuji@23: ))) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@51: (defun split-window-calculate-height (height) yuuji@51: "Split current window wight specified HEIGHT. yuuji@59: If HEIGHT is number, make a new window that has HEIGHT lines. yuuji@59: If HEIGHT is string, make a new window that occupies HEIGT % of screen height. yuuji@51: Otherwise split window conventionally." yuuji@59: (if (one-window-p t) yuuji@51: (split-window yuuji@51: (selected-window) yuuji@51: (max yuuji@51: (min yuuji@51: (- (screen-height) yuuji@59: (if (numberp height) yuuji@59: (+ height 2) yuuji@51: (/ (* (screen-height) yuuji@59: (string-to-int height)) yuuji@51: 100))) yuuji@51: (- (screen-height) window-min-height 1)) yuuji@51: window-min-height))) yuuji@51: ) yuuji@51: yuuji@51: ;;;###autoload yuuji@23: (defun YaTeX-window-list () yuuji@23: (let*((curw (selected-window)) (win curw) (wlist (list curw))) yuuji@23: (while (not (eq curw (setq win (next-window win)))) yuuji@23: (or (eq win (minibuffer-window)) yuuji@23: (setq wlist (cons win wlist)))) yuuji@23: wlist) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun substitute-all-key-definition (olddef newdef keymap) yuuji@23: "Replace recursively OLDDEF with NEWDEF for any keys in KEYMAP now yuuji@23: defined as OLDDEF. In other words, OLDDEF is replaced with NEWDEF yuuji@23: where ever it appears." yuuji@23: (mapcar yuuji@23: (function (lambda (key) (define-key keymap key newdef))) yuuji@47: (where-is-internal olddef keymap)) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-match-string (n &optional m) yuuji@23: "Return (buffer-substring (match-beginning n) (match-beginning m))." yuuji@23: (if (match-beginning n) yuuji@23: (buffer-substring (match-beginning n) yuuji@49: (match-end (or m n)))) yuuji@23: ) yuuji@23: yuuji@23: ;;;###autoload yuuji@23: (defun YaTeX-minibuffer-complete () yuuji@49: "Complete in minibuffer. yuuji@51: If the symbol 'delim is bound and is string, its value is assumed to be yuuji@49: the character class of delimiters. Completion will be performed on yuuji@51: the last field separated by those delimiters. yuuji@51: If the symbol 'quick is bound and is 't, when the try-completion results yuuji@51: in t, exit minibuffer immediately." yuuji@23: (interactive) yuuji@51: (let ((md (match-data)) beg word compl yuuji@51: (quick (and (boundp 'quick) (eq quick t))) yuuji@51: (displist ;function to display completion-list yuuji@51: (function yuuji@51: (lambda () yuuji@51: (with-output-to-temp-buffer "*Completions*" yuuji@51: (display-completion-list yuuji@51: (all-completions word minibuffer-completion-table))))))) yuuji@49: (setq beg (if (and (boundp 'delim) (stringp delim)) yuuji@23: (save-excursion yuuji@23: (skip-chars-backward (concat "^" delim)) yuuji@49: (point)) yuuji@23: (point-min)) yuuji@23: word (buffer-substring beg (point-max)) yuuji@23: compl (try-completion word minibuffer-completion-table)) yuuji@23: (cond yuuji@49: ((eq compl t) yuuji@51: (if quick (exit-minibuffer) yuuji@51: (let ((p (point)) (max (point-max))) yuuji@51: (unwind-protect yuuji@51: (progn yuuji@51: (goto-char max) yuuji@51: (insert " [Sole completion]") yuuji@51: (goto-char p) yuuji@51: (sit-for 1)) yuuji@51: (delete-region max (point-max)) yuuji@51: (goto-char p))))) yuuji@23: ((eq compl nil) yuuji@23: (ding) yuuji@23: (save-excursion yuuji@23: (let (p) yuuji@51: (unwind-protect yuuji@51: (progn yuuji@51: (goto-char (setq p (point-max))) yuuji@51: (insert " [No match]") yuuji@51: (goto-char p) yuuji@51: (sit-for 2)) yuuji@51: (delete-region p (point-max)))))) yuuji@23: ((string= compl word) yuuji@51: (funcall displist)) yuuji@23: (t (delete-region beg (point-max)) yuuji@51: (insert compl) yuuji@51: (if quick yuuji@51: (if (eq (try-completion compl minibuffer-completion-table) t) yuuji@51: (exit-minibuffer) yuuji@51: (funcall displist))))) yuuji@49: (store-match-data md)) yuuji@23: ) yuuji@23: yuuji@51: (defun YaTeX-minibuffer-quick-complete () yuuji@51: "Set 'quick to 't and call YaTeX-minibuffer-complete. yuuji@51: See documentation of YaTeX-minibuffer-complete." yuuji@51: (interactive) yuuji@51: (let ((quick t)) yuuji@51: (self-insert-command 1) yuuji@51: (YaTeX-minibuffer-complete))) yuuji@51: yuuji@51: (defun foreach-buffers (pattern job) yuuji@51: "For each buffer which matches with PATTERN, do JOB." yuuji@51: (let ((list (buffer-list))) yuuji@51: (save-excursion yuuji@51: (while list yuuji@51: (set-buffer (car list)) yuuji@51: (if (or (and (stringp pattern) yuuji@51: (buffer-file-name) yuuji@51: (string-match pattern (buffer-file-name))) yuuji@51: (and (symbolp pattern) major-mode (eq major-mode pattern))) yuuji@51: (eval job)) yuuji@51: (setq list (cdr list))))) yuuji@51: ) yuuji@51: yuuji@51: (defun goto-buffer-window (buffer) yuuji@51: "Select window which is bound to BUFFER. yuuji@51: If no such window exist, switch to buffer BUFFER." yuuji@52: (interactive "BGoto buffer: ") yuuji@51: (if (stringp buffer) yuuji@51: (setq buffer (or (get-file-buffer buffer) (get-buffer buffer)))) yuuji@51: (if (get-buffer buffer) yuuji@51: (cond yuuji@51: ((get-buffer-window buffer) yuuji@51: (select-window (get-buffer-window buffer))) yuuji@51: ((and YaTeX-emacs-19 (get-buffer-window buffer t)) yuuji@51: (let*((win (get-buffer-window buffer t)) yuuji@51: (frame (window-frame win))) yuuji@51: (select-frame frame) yuuji@51: (raise-frame frame) yuuji@51: (focus-frame frame) yuuji@51: (select-window win) yuuji@51: (set-mouse-position frame 0 0) yuuji@51: (and (featurep 'windows) (fboundp 'win:adjust-window) yuuji@51: (win:adjust-window)))) yuuji@54: ((and (featurep 'windows) (fboundp 'win:get-buffer-window) yuuji@56: (let ((w (win:get-buffer-window buffer))) yuuji@56: (and w (win:switch-window w)))) yuuji@54: (select-window (get-buffer-window buffer))) yuuji@51: (t (switch-to-buffer buffer)))) yuuji@51: ) yuuji@51: yuuji@51: ;; Here starts the functions which support gmhist-vs-Emacs19 compatible yuuji@51: ;; reading with history. yuuji@51: ;;;###autoload yuuji@51: (defun completing-read-with-history yuuji@51: (prompt table &optional predicate must-match initial hsym) yuuji@51: "Completing read with general history: gmhist, Emacs-19." yuuji@51: (let ((minibuffer-history yuuji@51: (or (symbol-value hsym) yuuji@51: (and (boundp 'minibuffer-history) minibuffer-history))) yuuji@51: (minibuffer-history-symbol (or hsym 'minibuffer-history))) yuuji@51: (prog1 yuuji@51: (if (fboundp 'completing-read-with-history-in) yuuji@51: (completing-read-with-history-in yuuji@51: minibuffer-history-symbol prompt table predicate must-match initial) yuuji@51: (completing-read prompt table predicate must-match initial)) yuuji@51: (if (and YaTeX-emacs-19 hsym) (set hsym minibuffer-history))))) yuuji@51: yuuji@51: ;;;###autoload yuuji@51: (defun read-from-minibuffer-with-history (prompt &optional init map read hsym) yuuji@51: "Read from minibuffer with general history: gmhist, Emacs-19." yuuji@51: (cond yuuji@51: (YaTeX-emacs-19 yuuji@51: (read-from-minibuffer prompt init map read hsym)) yuuji@51: (t yuuji@51: (let ((minibuffer-history-symbol hsym)) yuuji@51: (read-from-minibuffer prompt init map read))))) yuuji@51: yuuji@51: ;;;###autoload yuuji@51: (defun read-string-with-history (prompt &optional init hsym) yuuji@51: "Read string with history: gmhist(Emacs-18) and Emacs-19." yuuji@51: (cond yuuji@51: (YaTeX-emacs-19 yuuji@51: (read-from-minibuffer prompt init minibuffer-local-map nil hsym)) yuuji@51: ((featurep 'gmhist-mh) yuuji@51: (read-with-history-in hsym prompt init)) yuuji@51: (t (read-string prompt init)))) yuuji@23: yuuji@53: ;;; yuuji@53: ;; Interface function for windows.el yuuji@53: ;;; yuuji@53: ;;;###autoload yuuji@53: (defun YaTeX-switch-to-window () yuuji@53: "Switch to windows.el's window decided by last pressed key." yuuji@53: (interactive) yuuji@53: (or (featurep 'windows) (error "Why don't you use `windows.el'?")) yuuji@53: (win-switch-to-window 1 (- last-command-char win:base-key))) yuuji@53: yuuji@58: (defun bcf-and-exit () yuuji@58: "Byte compile rest of argument and kill-emacs." yuuji@58: (if command-line-args-left yuuji@58: (progn yuuji@58: (mapcar 'byte-compile-file command-line-args-left) yuuji@58: (kill-emacs)))) yuuji@58: yuuji@23: (provide 'yatexlib)