XEmacs Tips

Тут я буду пихать всякие фишки связанные с XEmacs и его окружением.

XEmacs Packages  - some packages for XEmacs that I recently wrote.

[1] Показываем менюху мод:
;; displays vertical bar ;; http://www.geocities.com/gchen275/xemacs/ (require 'vvb-mode) (setq vvb-sticky-p t) (define-key global-map '(shift button1) 'vvb-popup-menu) ;; ASCII code display ;; http://www.cpqd.com.br/~vinicius/emacs/Emacs.html (require 'ascii) ;; highlight current line (require 'highline) ;; helpfull modes-menu (setq whitespace-mode nil) (setq flyspell-mode nil) (defvar modes-menu '("Modes" ["ascii-display" ascii-display :active t :style toggle :selected ascii-display] ["flyspell-mode" flyspell-mode :active t :style toggle :selected flyspell-mode] ["vvb-mode" vvb-mode :active t :style toggle :selected vvb-mode] ["highline-mode" highline-local-mode :active t :style toggle :selected highline-local-mode] ["whitespace-mode" whitespace-mode :active t :style toggle :selected whitespace-mode] ["font-lock-mode" font-lock-mode :active t :style toggle :selected font-lock-mode] ) "Popup modes menu") (defun modes-popup-menu (ev) "Popup modes menu `modes-menu'" (interactive "e") (popup-menu modes-menu ev)) (define-key global-map '(control button1) 'modes-popup-menu)
[2] Я люблю что-нибудь компилировать поэтому сделал так:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; compilation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq compile-command "make -k") (setq compilation-scroll-output nil) (setq compilation-window-height 10) (require 'cc-mode) (define-key c-mode-map "\C-cl" (lambda () (interactive) (compile compile-command)))
[3] А еще я люблю переключаться между буфферами с клавиатуры. Очень
часто кстати использую "\C-\M-l":
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; handy buffers switching ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defface buffername-face '((((class color)) (:foreground "blue" :bold t))) "Face for displaying current buffer name." :group 'faces) ;;; Coloring Functions (defun mef-colorize-text (text) "Colorize given text" (let ((face 'buffername-face) (newtext (concat text))) (put-text-property 0 (length text) 'face face newtext) newtext)) (defun mef-display-bufstr (buffs) "Display colorized buffers list" (display-message 'no-log (let ((cbufname (buffer-name (current-buffer))) (rst nil)) ;; reorder elements in buffs so "*scratch*" will be first (while (not (string= (buffer-name (car buffs)) "*scratch*")) (setq buffs (nconc (cdr buffs) (list (car buffs))))) (while buffs (progn (setq cbuf (buffer-name (car buffs))) (if (string= cbufname cbuf) (setq rst (concat rst (when rst " | ") (mef-colorize-text cbuf))) (setq rst (concat rst (when rst " | ") cbuf))) (setq buffs (cdr buffs)))) rst))) ;; my buffer filter .. i don't want buffers like " Warnings*" and " SPEEDBAR" ;; to be in buffers switch list (defun my-select-files (buff) "Exclude uninterested buffers" (let ((bname (buffer-name buff))) (cond ((string= bname " SPEEDBAR") nil) ((string= bname "*scratch*") t) ((string= bname "*info*") t) ((char= (car (reverse (string-to-list bname))) ?*) nil) (t t)))) ;; make list of buffers according predicate (filter) function (defun files-and-scratch-buffers (buff-list &optional predicate) (interactive) (let ((curr (current-buffer)) (buffs buff-list) (nbuffs nil)) (progn (while buffs (let* ((buff (car buffs)) (name (buffer-name buff)) (isadd (if (null name) nil (funcall predicate buff)))) (setq buffs (cdr buffs)) (if (eq isadd t) (add-to-list 'nbuffs buff) nil))) nbuffs))) ;; switch to previous buffer in my filtered buffer list (defun gotoprev-buffer () "Switches to previous buffer in buffers list" (interactive) (let ((buffs (files-and-scratch-buffers (buffer-list) 'my-select-files))) (if (null buffs) (message "No more valid buffers") (let ((buf (car buffs))) (switch-to-buffer buf) (mef-display-bufstr (reverse buffs)))))) ;; switch to next buffer (defun gotonext-buffer () "Switches to next buffer in buffers list" (interactive) (let ((buffs (files-and-scratch-buffers (reverse (buffer-list)) 'my-select-files))) (if (null buffs) (message "No more valid buffers") (let ((buf (car (cdr buffs)))) (bury-buffer) (switch-to-buffer buf) (mef-display-bufstr buffs))))) (define-key global-map "\C-\M-\[" 'gotoprev-buffer) (define-key global-map "\C-\M-\]" 'gotonext-buffer)
[4] А еще я как то пытался сделать что то на php и вот навороты для XEmacs
которые из этого выползли (кстати наверняка очень полезно будет в
данном случае использовать mmm-mode:
(autoload 'php-mode "php-mode" "PHP editing mode" t) (add-to-list 'auto-mode-alist '("\\.php.?\\'" . html-mode)) ;; apache root directory (defvar php-bin "/home/lg/bin/php" "Where php binary is.") (defvar php-apache-root-dir '("www" "data") "Окуда делать truncate пути к файлу") (defvar php-apache-hostname " http://www" "Что писать в начало перед трункатнутым пути к файлу (NOTE: / в конце не неужен)") ;; evaluate region with external process (defun php-eval-region (begin end) "Прогнать данный регион через php.bin и вывести что получилось в другом окне" (interactive "r") (shell-command-on-region begin end php-bin)) (defun php-eval-buffer () "Тоже самое что и php-eval-region тока полностью для buffera" (interactive) (shell-command-on-region (point-min) (point-max) php-bin)) (defun php-make-url (list &optional dir) "Если dir нету то (\"test\" \"test1\" \"test.php\") -> \"/test/test1/test.php\" иначе исключить начало которое в dir. Например list = '(\"www\" \"data\" \"test.php\"), dir = '(\"www\" \"data\") то вернеться \"/test.php\"" (cond ((null list) nil) ((equal (car list) (car dir)) (php-make-url (cdr list) (cdr dir))) (t (concat "/" (car list) (php-make-url (cdr list)))))) ;; start netscape with buffer-file argument (defun php-eval-buffer-file () "Записать current buffer в файл и запустить netscape с ним" (interactive) (require 'browse-url) (let* ((ofil (reverse (cdr (split-string (buffer-file-name (current-buffer)) "/")))) (b (cdr ofil)) (fn (split-string (car ofil) "\\.")) (temp-file (reverse (cons (concat (car fn) "_" (user-login-name) "_netscape." (cadr fn)) b)))) (write-region (point-min) (point-max) (php-make-url temp-file)) (browse-url-netscape (concat php-apache-hostname (php-make-url temp-file php-apache-root-dir)) t))) ;; key-maps .. we use html-mode чтоб едитать php и ети бинды свободны в c-mode (defvar html-mode-map nil) (if html-mode-map () (setq html-mode-map (make-sparse-keymap)) (define-key html-mode-map "\C-cr" 'php-eval-buffer-file) (define-key html-mode-map "\C-c|" 'php-eval-region) (define-key html-mode-map "\C-c\C-l" 'php-eval-string) (define-key html-mode-map "\C-cb" 'php-eval-buffer))
[5] Я так же хочу удалять с помощью Backspace и скроллировать буффера с помощью
колеса:
;; (== C-h Backspace) so help system moved to C-x h (global-set-key "\C-h" 'delete-backward-char) (global-set-key "\C-xh" 'help-command) (global-set-key "\C-x\C-m" 'manual-entry) (if (string-match "XEmacs" emacs-version) (progn (define-key global-map '(button4) 'scroll-down) (define-key global-map '(button5) 'scroll-up)))
[6] А еще мне нравиться lisp поэтому в моем .emacs есть такие строки:
(load-library "inf-lisp") ;; what to run when M-x run-lisp (setq inferior-lisp-program "clisp -I -q") ;; evaluation lisp expration (defun lisp-eval-sexp (&optional and-go) "send next sexp to the inferior lisp proccess" (interactive "P") (lisp-eval-region (point) (save-excursion (forward-sexp) (point)) and-go)) (defun lisp-macroexpand-region (start end &optional and-go) "macroexpand" (interactive "r\nP") (comint-send-string (inferior-lisp-proc) (format "(macroexpand-1 (quote %s))\n" (buffer-substring start end))) (if and-go (switch-to-lisp t))) (defun lisp-macroexpand-sexp (&optional and-go) "macroexpand next sexp to inferior lisp proc" (interactive "P") (lisp-macroexpand-region (point) (save-excursion (forward-sexp) (point)) and-go)) ;; some powerfull binds (inferior-lisp-install-letter-bindings) (define-key lisp-mode-map "\C-x\C-e" 'lisp-eval-sexp) (define-key inferior-lisp-mode-map "\C-x\C-e" 'lisp-eval-sexp) (define-key lisp-mode-map "\C-x\C-m" 'lisp-macroexpand-sexp) (define-key inferior-lisp-mode-map "\C-x\C-m" 'lisp-macroexpand-sexp)
[7] Мне нравиться стиль "bsd" для программирования на C. Этот стиль учит
''правильно'' писать программы в отличии от "gnu" который разбазаривает
последнюю дисциплину:
(add-hook 'c-mode-common-hook (lambda () (c-set-style "bsd")))
[8] Мне не нравиться что этот toolbar и menubar занимают столько много места у меня на
десктопе поэтому:
(set-specifier default-toolbar-visible-p nil) (set-specifier menubar-visible-p nil)
[9] Я так же использую клавишу Kanji в своем window manager а в XEmacs
kanji как бы не при делах по этому у мена сделано вот так:
;; get rid of annoing "kanji not defined (defun my-nil-func (&optional ango) (interactive "P")) (global-set-key 'kanji 'my-nil-func)
[10] Мне так же нравиться офигительная вещь - Xrefactory, и я ее с
большим удовольсвием использую:
;; Xrefactory (load "xrefactory") (define-key c-mode-map "\C-c\C-f" 'xref-pushCxrefs) (define-key c-mode-map "\C-c\C-b" 'xref-popCxrefs) (define-key c-mode-map [(meta tab)] 'xref-completion)
[11] Еще я часто пользуюсь описаловом функций elispa - для этого очень удобно пользовать
elisp reference manual - поэтому я сделал себе такую функцию:
;; more powerfull function describer thrue elisp reference manual ;; XEmacs have his own (Info-elisp-ref (func)) function, but mine is more powerfull :) ;; it will try standard describe-function if not found in elisp reference manual (defun my-find-function-in-elisp-manual (function) (interactive (let ((fn (function-at-point)) (enable-recursive-minibuffers 1)) (setq val (completing-read (format "Describe function: ") obarray nil t (if (boundp fn) nil (symbol-name fn)) nil)) (list (if (equal val "") fn val)))) (Info-goto-node "(lispref)Index") (condition-case nil (progn (search-forward (concat "* "function":")) (backward-char) (Info-follow-nearest-node (point))) (error (progn (switch-to-buffer (other-buffer)) (hyper-describe-function (intern function)))))) (define-key global-map [(f1) f] 'my-find-function-in-elisp-manual)
[12] Еще тут есть такая мулька - ctypes - очень удобно .. прогоняешь
ее через какую нибудь директорию и получаешь список для фонтлока :)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Additional options for fontlocking ;; (defun my-c-mode-hook () (require 'ctypes) (ctypes-auto-parse-mode 1) (turn-on-font-lock)) (add-hook 'c-mode-hook 'my-c-mode-hook) ;;(add-hook 'c++-mode-hook 'my-c-mode-hook) (defun my-ctypes-load-hook () (ctypes-read-file "~/.xemacs/ctypes/ctypes_std_c" nil t t)) (defun my-ctypes-load-x11 () (interactive) (ctypes-read-file "~/.xemacs/ctypes/ctypes_x11_c" nil t t)) (add-hook 'ctypes-load-hook 'my-ctypes-load-hook)
[13] Я люблю что-нибудь побыстрому посчитать - наприимер 1024*7+163
;; usefull mini calculator (require 'calc) (defun mcalc (expr) (interactive "sEnter expression: ") (message (format "Result: [%s] = %s" expr (calc-eval expr))))
[14] Скобки обычно мешают когда пишешь на lispе - так они выглядят менее заметными
(defface paren-face '((((class color)) (:foreground "DimGray"))) "Face for displaying a paren." :group 'faces) (defmacro paren-face-add-support (keywords) "Generate a lambda expression for use in a hook." `(lambda () (let* ((regexp "(\\|)") (match (assoc regexp ,keywords))) (unless (eq (cdr match) paren-face) (setq ,keywords (append (list (cons regexp paren-face)) ,keywords)))))) ;; Keep the compiler quiet. (eval-when-compile (defvar scheme-font-lock-keywords-2 nil) (defvar lisp-font-lock-keywords-2 nil)) (add-hook 'scheme-mode-hook (paren-face-add-support scheme-font-lock-keywords-2)) (add-hook 'lisp-mode-hook (paren-face-add-support lisp-font-lock-keywords-2)) (add-hook 'emacs-lisp-mode-hook (paren-face-add-support lisp-font-lock-keywords-2)) (add-hook 'lisp-interaction-mode-hook (paren-face-add-support lisp-font-lock-keywords-2))
[15] Очень удобно помечать когда ты менял файлик .. если в первых
строках есть что то типа Time-stamp: <> то туда будет записан
time-stamp времени последей записи ..
;; time-stamp files (require 'time-stamp) (setq time-stamp-format "%f - %3a %3b %2d %02H:%02M:%02S %Z %y") (add-hook 'write-file-hooks 'time-stamp)
[16] Если вы достаточно сильно используете ediff для визуализации diff
файлов то вам может быть интересна следующая конфигурация ediffа. Меня
немного запарило то что норльно нельзя контролировать окна которые
ediff перелапачивает чтобы отобразить информацию поэтому я сделал
так. 
;;; Use this powerfull ediff package (autoload 'ediff "ediff") ;; don't use this ugly frames .. display all in one please (setq ediff-window-setup-function 'ediff-setup-windows-plain) (setq ediff-split-window-function 'split-window-horizontally) ;; Some custom configuration to ediff (defvar my-ediff-bwin-config nil "Window configuration before ediff.") (defvar my-ediff-bwin-reg ?b "Register to be setuped to hold `my-ediff-bwin-config' configuration.") (defvar my-ediff-awin-config nil "Window configuration after ediff.") (defvar my-ediff-awin-reg ?e "Register to be used to hold `my-ediff-awin-config' window configuration.") (defun my-ediff-bsh () "Function to be called before any buffers or window setup for ediff." (setq my-ediff-bwin-config (current-window-configuration)) (when (and my-ediff-bwin-reg (characterp my-ediff-bwin-reg)) (set-register my-ediff-bwin-reg (list my-ediff-bwin-config (point-marker))))) (defun my-ediff-ash () "Function to be called after buffers and window setup for ediff." (setq my-ediff-awin-config (current-window-configuration)) (when (and my-ediff-awin-reg (characterp my-ediff-awin-reg)) (set-register my-ediff-awin-reg (list my-ediff-awin-config (point-marker))))) (defun my-ediff-qh () "Function to be called when ediff quits." (when my-ediff-bwin-config (set-window-configuration my-ediff-bwin-config))) (add-hook 'ediff-before-setup-hook 'my-ediff-bsh) (add-hook 'ediff-after-setup-windows-hook 'my-ediff-ash) (add-hook 'ediff-quit-hook 'my-ediff-qh)
[17] Хочеться переключать скорость клавиатуры в течении дня? Hапример
я люблю утром быструю клавиатуру после обеда меделенную в остальное
время среднюю.
;; Installs C-ck Prefix for Keyboard control commands (defun my-set-keyrate (lat rate) (shell-command (format "xset r rate %d %d" lat rate))) (define-key global-map "\C-ckd" (lambda () (interactive) (my-set-keyrate 250 50) (message "Default keyrate intalled."))) ;default keyrate (define-key global-map "\C-ckf" (lambda () (interactive) (my-set-keyrate 250 100) (message "Fast keyrate intalled"))) ;fast (define-key global-map "\C-cks" (lambda () (interactive) (my-set-keyrate 250 25) (message "Slow keyrate installed"))) ;slow

Hosted by uCoz