;;;; bdimych's .emacs for emacs 22 (setq inhibit-splash-screen t) (add-to-list 'load-path (file-name-directory load-file-name)) (add-to-list 'load-path (concat (file-name-directory load-file-name) "ecb-snap")) (add-to-list 'load-path (concat (file-name-directory load-file-name) "cedet-1.0pre4/common")) ;;;; my preferences (setq ring-bell-function 'ignore) (setq messages-buffer-max-lines 500) (setq default-tab-width 4) (set-scroll-bar-mode 'right) (setq scroll-step 1) ;(setq scroll-conservatively 50) (setq scroll-preserve-screen-position t) ;(setq scroll-margin 3) ;; do not break filesystem soft and hard links (setq backup-by-copying t) (setq make-backup-files nil) (mouse-wheel-mode t) (setq mouse-wheel-progressive-speed nil) (setq mouse-wheel-scroll-amount '(2 ((control) . 1) ((shift) . 5))) (show-paren-mode 1) (setq-default cursor-type 'bar) ;(global-hl-line-mode 1) (unless (string= "w32" window-system) (set-default-font "8x13" t)) ;; make kill and yank to use system clipboard (setq x-select-enable-clipboard t) ;; (setq default-buffer-file-coding-system 'unix) ;;;; escape (global-set-key [(escape)] 'my-escape) (defun my-escape () (interactive) (cond (mark-active (setq mark-active nil) (setq this-command nil) ; last-command will get this value ) (f3search-highlight-active (f3search-highlight-remove) (setq this-command nil) ; last-command will get this value ) ((eq major-mode 'moccur-mode) (moccur-quit)) ((get-buffer-window "*Moccur*") (select-window (get-buffer-window "*Moccur*"))) ((get-buffer-window "*Backtrace*") (select-window (get-buffer-window "*Backtrace*")) (top-level) ;; quit debugger window ) ((string-match "^ \\*ECB.+\\*$" (buffer-name)) (ecb-goto-window-edit-last)) ((string-match "^\\*.+\\*$" (buffer-name)) (if (not (eq this-command last-command)) (hide-more-service-window) ;; else (my-history-back) ) ) (t (keyboard-escape-quit)) ; one instead of three ) ) (defun hide-more-service-window () (let ((swlist '( "*Messages*" "*Completions*" "*Warnings*" "*Help*" "*Apropos*" "*Diff*" )) (Ws (window-list)) ) (while Ws (let ((bn (buffer-name (window-buffer (pop Ws))))) (if (and (string-match "^\\*Customize " bn) (not (string= "*Customize Browser*" bn))) (push bn swlist) ) ) ) (catch 'break (while swlist (let ((w (get-buffer-window (pop swlist)))) (when w (select-window w) (bury-buffer) (delete-window) (throw 'break nil)) ) ) ) ) ) ;;;; C-s, C-w, C-S-w, C-TAB ;; control s - save buffer (global-set-key [(control s)] '(lambda () (interactive) (desktop-save-in-desktop-dir) (if (buffer-file-name) (save-buffer) (call-interactively 'write-file) ) (ecb-rebuild-methods-buffer t)(ecb-window-sync) ) ) ;; control w - kill buffer (global-set-key [(control w)] 'kill-buffer) ;; control shift w - kill buffer and delete file (global-set-key [(control shift w)] '(lambda () (interactive) (let ((y (and buffer-file-name (y-or-n-p "Delete file and kill buffer? "))) ) (when y (delete-file buffer-file-name) (message "file \"%s\" has been deleted" buffer-file-name) ) (if y (kill-buffer nil) (when (not buffer-file-name) (call-interactively 'kill-buffer) ) ) ) ) ) ;; control tab - switch buffers (global-set-key [(control tab)] (lambda (bname) (interactive "Bswitch to buffer") (if (not (get-buffer bname)) (if (not (y-or-n-p (format "buffer \"%s\" does not exist, create new ? " bname))) (signal 'quit nil) ;; else (switch-to-buffer bname) (outline-minor-mode 1) ) ;; else (switch-to-buffer bname) ) ) ) ;;;; files: C-n, C-o, C-S-o ;; control n - open empty buffer (global-set-key [(control n)] (lambda () (interactive) (switch-to-buffer (format-time-string "emacs_new_file_%Y-%m-%d-%a-%H-%M-%S")) (outline-minor-mode 1) ) ) ;; control o - open file (global-set-key [(control o)] 'find-file) ;; control shift o - open files matched regular expression recursively within specified directory (global-set-key [(control shift o)] 'recursively-open-files) (defun recursively-open-files () (interactive) (let* ( (first-dir (read-directory-name "recursively-open-files: dir: ")) (dirs (list first-dir)) (regexp (read-string "recursively-open-files: file name regexp: ")) (result-files (list)) ) ;; check input (when (or (= (length regexp) 0) (not (file-directory-p first-dir)) ) (signal 'quit nil) ) ;; find files recursively (while dirs (let ((files (directory-files (pop dirs) t))) (while files (let ((f (pop files))) (message f) (when (and (file-directory-p f) (not (string= (file-name-nondirectory f) ".")) (not (string= (file-name-nondirectory f) "..")) ) (push f dirs) ) (when (and (file-regular-p f) (string-match regexp (file-name-nondirectory f)) ) (push f result-files) ) ) ) ) ) ;; show files found and button which open them (if (not result-files) (message "no files \"%s\" were found in \"%s\"" regexp first-dir) (message "%d files found" (length result-files)) (setq result-files (sort result-files 'string<)) (let ((resbuf (get-buffer-create "*Files found recursively*"))) (pop-to-buffer resbuf) (setq truncate-lines t) (setq truncate-partial-width-windows t) (local-set-key [(escape)] 'kill-buffer-and-window) (erase-buffer) (while result-files (insert (concat (pop result-files) "\n")) ) (insert (format " %d files \"%s\" were found in \"%s\" to open all files push the button if you do not want open certain files then modify or delete corresponding lines " (1- (line-number-at-pos)) regexp first-dir ) ) (insert-button "open files" 'face "custom-button" 'mouse-face "custom-button-mouse" 'help-echo nil 'follow-link t ;; open all files and close results buffer and window 'action (lambda (x) (let ( (cnt 0) (opened-buffers ()) ) (with-current-buffer (current-buffer) (while (not (= (line-number-at-pos) 1)) (forward-line -1) (let ((f (replace-regexp-in-string "\r?\n" "" (thing-at-point 'line)))) (when (and (file-exists-p f) (file-regular-p f)) (push (find-file-noselect f) opened-buffers) (setq cnt (1+ cnt)) ) ) ) (kill-buffer-and-window) ) ;; order them so they will be M-right accessible in the same order they were showed (setq opened-buffers (nreverse opened-buffers)) (while opened-buffers (switch-to-buffer (pop opened-buffers)) (next-buffer) ) (message "%d files opened, use M-right to go to the first found and further" cnt) ) ) ) (backward-char) ) ) ) ) ;;;; customizing mode-line and frame-title ;;;;; show buffer name and file name on the frame title (setq frame-title-format '(:eval (concat invocation-name "@" system-name " - " (encode-coding-string (buffer-name) locale-coding-system) " - " (when (buffer-file-name) (encode-coding-string (buffer-file-name) locale-coding-system) ) ) ) ) ;;;;; show in the mode line: scroll percent, file size, line number, column number, selection length (column-number-mode 1) (line-number-mode 1) (size-indication-mode 1) (setq mode-line-position '( (:eval (propertize (format "%d of %d" (1- (point)) (buffer-size)) 'mouse-face 'mode-line-highlight 'help-echo "click - goto char, control click - copy position" 'local-map '(keymap (mode-line keymap (mouse-1 . mode-line-goto-char) (C-mouse-1 . mode-line-copy-position) ) ) ) ) #(" (%l,%c) sel:" 2 4 (mouse-face mode-line-highlight help-echo "click - goto line, control click - copy line number" local-map (keymap (mode-line keymap (mouse-1 . mode-line-goto-line) (C-mouse-1 . mode-line-copy-line-number) ) ) ) ) (:eval (if mark-active (number-to-string (- (region-end) (region-beginning))) "0")) " scrl:%p" ) ) (defun mode-line-goto-char (event) ; template taken from mode-line-next-buffer (interactive "e") (select-window (posn-window (event-start event))) (call-interactively 'goto-char) ) (defun mode-line-copy-position (event) (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (let ((p (format "%d of %d" (point) (buffer-size)))) (kill-new p) (message (concat "\"" p "\" has been copied")) ) ) ) (defun mode-line-goto-line (event) (interactive "e") (select-window (posn-window (event-start event))) (call-interactively 'goto-line) ) (defun mode-line-copy-line-number (event) (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (let ((ln (number-to-string (line-number-at-pos)))) (kill-new ln) (message (concat "\"" ln "\" has been copied")) ) ) ) ;;;;; show buffer name and file path on the tooltip of the mode line ;; and copy them with mose click on mode line (defun mode-line-copy-buffer-name (event) ; template taken from mode-line-next-buffer (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (let ((n (buffer-name))) (kill-new n) (message (concat "\"" n "\" has been copied")) ) ) ) (defun mode-line-copy-buffer-file-name (event) (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (let ((n (buffer-file-name))) (if (string= "w32" window-system) (setq n (replace-regexp-in-string "/" "\\\\" n))) (kill-new n) (message (concat "\"" n "\" has been copied")) ) ) ) (defun mode-line-rename-buffer (event) (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (let ((new-name (read-string "Rename buffer to: " (buffer-name)))) (if (string= new-name (buffer-name)) (message "Nothing to do") (if (and (get-buffer new-name) (not (eq (get-buffer new-name) (current-buffer))) ) (message "A buffer named '%s' already exists!" new-name) (rename-buffer new-name) (if (get-buffer " *ECB History*") (ecb-add-buffers-to-history)) ) ) ) ) ) (defun mode-line-rename-file-and-buffer (event) (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (call-interactively 'rename-file-and-buffer) ) ) (defun mode-line-my-history-back (event) (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (my-history-back) ) ) (defun mode-line-my-history-forward (event) (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) (my-history-forward) ) ) (setq-default mode-line-buffer-identification '( (:eval (when buffer-file-name #("F " 0 2 (mouse-face mode-line-highlight help-echo (lambda (window object pos) ; http://www.gnu.org/software/emacs/manual/html_node/elisp/Special-Properties.html (let ((f (buffer-file-name (window-buffer window)))) (if (string= "x" window-system) (setq f (encode-coding-string f locale-coding-system))) (concat f " \ncontrol click - copy file path, alt control click - rename file and buffer") ;; !!! space is _required_ for the new line displays correctly in case of non ascii file names ) ) local-map (keymap (mode-line keymap (C-mouse-1 . mode-line-copy-buffer-file-name) (C-M-mouse-1 . mode-line-rename-file-and-buffer)) ) ) ) ) ) #("%12b" 0 4 (face mode-line-buffer-id help-echo "control click - copy buffer name, alt control click - rename buffer left click - previous buffer, right click - next buffer" mouse-face mode-line-highlight local-map (keymap (header-line keymap (mouse-1 . mode-line-next-buffer) (down-mouse-1 . ignore) (mouse-3 . mode-line-previous-buffer) (down-mouse-3 . ignore)) (mode-line keymap (C-mouse-1 . mode-line-copy-buffer-name) (C-M-mouse-1 . mode-line-rename-buffer) (mouse-1 . mode-line-my-history-back) (mouse-3 . mode-line-my-history-forward)) ) ) ) ) ) ;;;; word wrap ;(load-library "longlines") ; (setq truncate-lines nil) seems better ;(setq text-mode-hook '(lambda () ; (longlines-mode) ; (longlines-show-hard-newlines) ; (setq longlines-wrap-follows-window-size 't) ; )) ;; do not truncate and wrap long lines (setq truncate-partial-width-windows nil) (setq truncate-lines nil) ;; except *Moccur* buffer (make-variable-buffer-local 'truncate-partial-width-windows) (defadvice moccur-next (before trancate-lines-in-moccur) (setq truncate-partial-width-windows t)) (ad-activate 'moccur-next) ;; and move up down end begin over the real visible screen lines (setq physical-line-mode t) (load-library "physical-line.el") (global-set-key [(end)] 'end-of-line) (global-set-key [(home)] 'beginning-of-line) ;;;; smart home end like in visual studio ; there is conflict with physical-line.el (load-library "smart-home-end-visual-studio.el") ; my workaround instead of smart-home-end-visual-studio.el (only for "home") (load-library "outline") ; else outline-invisible-p cause error (defadvice beginning-of-line (around smart_home_fixed) (if (and (interactive-p) (> (point) 1) (outline-invisible-p (1- (point))) ) (progn (ad-deactivate 'beginning-of-line) (outline-back-to-heading) (ad-activate 'beginning-of-line) ) (if (and (eq this-command 'beginning-of-line) (or (eq last-command 'beginning-of-line) (= (line-beginning-position) (point)) ) ) (progn (ad-deactivate 'beginning-of-line) (beginning-of-line-text) (ad-activate 'beginning-of-line) (setq this-command 'beginning-of-line-text) ; last-command will get this value after advice will have ended ) ad-do-it ) ) ) (ad-activate 'beginning-of-line) ;;;; cua i.e. copy/paste C-c, C-v ... etc (cua-mode t) (setq mouse-drag-copy-region nil) (setq cua-keep-region-after-copy t) ;; cua in emacs 22 seems not works properly (may be I am wrong, I am not sure) ;; I make my own bindings M-C-Tab shift region, M-C-S-Tab unshift region (global-set-key [(meta control tab)] '(lambda () (interactive) (increase-left-margin (region-beginning) (region-end) nil) ) ) (global-set-key (if (string= "w32" window-system) [(meta control shift tab)] [(meta control shift iso-lefttab)] ) '(lambda () (interactive) (decrease-left-margin (region-beginning) (region-end) nil) ) ) ;; shift + click select region (define-key global-map (kbd "") 'ignore) ; turn off font dialog (define-key global-map (kbd "") 'mouse-set-point) (put 'mouse-set-point 'CUA 'move) ;; C-a - copy whole buffer (global-set-key [(control a)] '(lambda () (interactive) (kill-new (buffer-string)) (message "whole buffer has been copied") ) ) ;;;; search in buffers with color-moccur library ;(require 'grep-buffers) (require 'color-moccur) ;; simpler swicth between emacs windows (global-set-key [(meta up)] 'other-window) (global-set-key [(meta down)] 'other-window) ;; (global-set-key [(control f)] '(lambda () (interactive) (save-excursion (save-restriction (when (and mark-active (string-match "\n" (buffer-substring (region-beginning) (region-end))) ) (cua-cancel) (narrow-to-region (region-beginning) (region-end)) ) (call-interactively 'occur-by-moccur) ) ) ) ) (global-set-key [(control shift f)] 'moccur) ;; case sensitive moccur (global-set-key [(control meta shift f)] '(lambda () (interactive) (kill-local-variable 'case-fold-search) (let ((case-fold-search nil)) ; if buffer-local defined then "let" affects only local value (call-interactively 'moccur) ) ) ) ;; moccur-edit, may be, the only "production stable" method to replace strings in multiple buffers (september 2007, emacs 22) (require 'moccur-edit) ;; before moccur save and after moccur restore the buffer list history order ;; (defvar buffer-list-before-moccur nil) (defadvice moccur (before buffer-list--save-before-moccur) (setq buffer-list-before-moccur (buffer-list)) ) (ad-activate 'moccur) (defadvice occur-by-moccur (before buffer-list--save-before-moccur) (setq buffer-list-before-moccur (buffer-list)) ) (ad-activate 'occur-by-moccur) (defadvice moccur-quit (after buffer-list--restore-after-moccur) (while buffer-list-before-moccur (bury-buffer (car buffer-list-before-moccur)) (setq buffer-list-before-moccur (cdr buffer-list-before-moccur)) ) (bury-buffer "*Moccur*") ) (ad-activate 'moccur-quit) ;;;; simple search with f3 (make-variable-buffer-local 'f3search-highlight-active) (make-variable-buffer-local 'f3search-highlight-prev) (defun f3search-highlight (func w) (let ((do-goto nil) (cnt 0)) (when (and f3search-highlight-active (equal (nth 0 f3search-highlight-prev) w) (equal (nth 1 f3search-highlight-prev) func) ) (setq do-goto t) ) (when (and f3search-highlight-active (not (equal f3search-highlight-prev (list w func (buffer-modified-tick)))) ) (f3search-highlight-remove) ) (when (not f3search-highlight-active) (save-excursion (goto-char 0) (while (funcall func w nil t) ; [re-]search-forward (let ((o (make-overlay (match-beginning 0) (point) nil t nil))) (overlay-put o 'face '(:background "#d0f2ff")) (overlay-put o 'f3search-highlight-overlay t) (overlay-put o 'modification-hooks (list '(lambda (ovr after beg end &optional len) (delete-overlay ovr)))) ) (setq cnt (1+ cnt)) ) ) (if (= cnt 0) (message "\"%s\" not found" w) ;; else (setq f3search-highlight-active t) (setq f3search-highlight-prev (list w func (buffer-modified-tick))) (message "%d occurences of \"%s\" highlighted" cnt w) ) ) do-goto ) ) (defun f3search-highlight-remove () (remove-overlays nil nil 'f3search-highlight-overlay t) (setq f3search-highlight-active nil) (message "f3search highlights of \"%s\" removed" (car f3search-highlight-prev)) ) (defun f3search (M C S) (setq this-command 'f3search) ; last-command will get this value when function will end (let ((w nil) search-ok (mark-was-active mark-active)) (cond (M (setq w (read-string "f3search for: " nil 'regexp-history))) (C (setq w (thing-at-point 'word))) ((and mark-active (not (eq last-command this-command)) (not (eq last-command 'cua-copy-region)) ; do not set search phrase from selected text ) (setq w (buffer-substring (region-beginning) (region-end))) ) (regexp-history (setq w (car regexp-history))) (t (setq w (thing-at-point 'word))) ) (when w (set-text-properties 0 (length w) nil w) (setq mark-active nil) (setq regexp-history (cons w regexp-history)) (when (f3search-highlight 'search-forward w) (if S (save-excursion (when mark-was-active (backward-char)) (setq search-ok (search-backward w nil t)) ) (setq search-ok (search-forward w nil t)) ) (if (not search-ok) (progn (message "search failed: \"%s\"" w) (when mark-was-active (setq mark-active t)) ) (goto-char (match-end 0)) (set-mark (match-beginning 0)) (if (and outline-minor-mode (outline-invisible-p)) (show-subtree)) (if (and hs-minor-mode (hs-already-hidden-p)) (hs-show-block)) (setq mark-active t) ) ) ) ) ) (global-set-key [(f3)] '(lambda () (interactive) (f3search nil nil nil))) (global-set-key [(control f3)] '(lambda () (interactive) (f3search nil t nil))) (global-set-key [(meta f3)] '(lambda () (interactive) (f3search t nil nil))) (global-set-key [(shift f3)] '(lambda () (interactive) (f3search nil nil t))) (global-set-key [(shift control f3)] '(lambda () (interactive) (f3search nil t t))) (global-set-key [(shift meta f3)] '(lambda () (interactive) (f3search t nil t))) ;;;; automatically reload files was modified by external program (global-auto-revert-mode 1) ;; display message box about file has been reverted (defun inform-revert-modified-file (&optional p1 p2) (let ((revert-buffer-function nil) (caller (backtrace-frame 4))) (revert-buffer p1 p2) (when (eq (cadr caller) 'auto-revert-handler) (message-box "emacs: modified file automatically reverted: %s" (buffer-file-name)) ) ) ) (setq revert-buffer-function 'inform-revert-modified-file) ;(setq revert-buffer-function nil) ;;;;; all-types-of-files-auto-checking - for files located on network drives (defvar all-types-of-files-auto-checking t) (defun all-types-of-files-auto-checking-off () (interactive) (setq-default auto-revert-mode nil) (global-auto-revert-mode nil) (setq auto-save-default nil) (deletedfile-timer-stop) (let ((Bs (buffer-list))) (while Bs (with-current-buffer (pop Bs) (when buffer-file-name (setq buffer-auto-save-file-name nil) (kill-local-variable 'auto-revert-mode) ) ) ) ) (setq all-types-of-files-auto-checking nil) (when (interactive-p) (desktop-save-in-desktop-dir)) ) (defun all-types-of-files-auto-checking-on () (interactive) (setq-default auto-revert-mode t) (global-auto-revert-mode 1) (setq auto-save-default t) (deletedfile-timer-start) (let ((Bs (buffer-list))) (while Bs (with-current-buffer (pop Bs) (when buffer-file-name (auto-save-mode 1) ) ) ) ) (setq all-types-of-files-auto-checking t) (when (interactive-p) (desktop-save-in-desktop-dir)) ) (add-hook 'desktop-save-hook (lambda () (when (null all-types-of-files-auto-checking) (insert "\n(all-types-of-files-auto-checking-off)\n")) ) ) ;;;; revert-all-buffers (defun revert-all-buffers () (interactive) (save-some-buffers) (let ((revert-buffer-function nil) (buffers (buffer-list)) (cnt 0) ) (save-current-buffer (while buffers (when (buffer-file-name (car buffers)) (set-buffer (car buffers)) (revert-buffer t t t) (setq cnt (1+ cnt)) ) (message (number-to-string cnt)) (setq buffers (cdr buffers)) ) ) (message (format "%d buffers have been reverted" cnt)) ) ) ;;;; ecb (load-library "cedet") (load-library "ecb") (setq ecb-primary-secondary-mouse-buttons (quote mouse-1--mouse-2)) (ecb-layout-switch "left7") (setq ecb-kill-buffer-clears-history 'auto) (setq ecb-tip-of-the-day nil) (custom-set-variables '(ecb-options-version "2.33beta2")) (setq ecb-auto-expand-tag-tree 'all) (setq ecb-auto-expand-tag-tree-collapse-other 'always) (setq ecb-highlight-tag-with-point 'highlight-scroll) ;;;; dabbrev i.e. autocompletion ??? incomplete (setq dabbrev-upcase-means-case-search t) ;; search and display completion candidates in _all_ buffers (global-set-key [(meta control right)] '(lambda () (interactive) (dabbrev-completion 16) (pop-to-buffer "*Completions*") ) ) ;;;; outline and hide-show (make-variable-buffer-local 'outline-regexp) (add-to-list 'desktop-locals-to-save 'outline-regexp) ;; outline key map (define-prefix-command 'outline-map nil "outline") (define-key outline-map "a" '(lambda () (interactive) (hs-show-all) (show-all))) (global-set-key "\M-o" outline-map) ;;;;; outline ;; expand/collapse outline heading (global-set-key [(C-kp-add)] 'show-entry) (global-set-key [(C-S-kp-add)] 'show-children) (global-set-key [(C-kp-enter)] 'show-branches) (global-set-key [(C-S-kp-enter)] 'show-subtree) (global-set-key [(C-kp-subtract)] 'hide-entry) (global-set-key [(C-S-kp-subtract)] (lambda (arg) (interactive "P") (save-excursion (if arg (outline-up-heading 1)) (hide-subtree) ) ) ) ;; next/previous outline heading (global-set-key [(C-up)] 'outline-previous-visible-heading) (global-set-key [(C-down)] 'outline-next-visible-heading) (global-set-key [(C-S-up)] (lambda () (interactive) (outline-up-heading 1))) (global-set-key [(C-kp-8)] 'outline-backward-same-level) (global-set-key [(C-kp-2)] 'outline-forward-same-level) ;; show headings of certain outline level (global-set-key [(M-kp-0)] (lambda () (interactive) (outline-my-show-headings-of-level 0))) (global-set-key [(M-kp-1)] (lambda () (interactive) (outline-my-show-headings-of-level 1))) (global-set-key [(M-kp-2)] (lambda () (interactive) (outline-my-show-headings-of-level 2))) (global-set-key [(M-kp-3)] (lambda () (interactive) (outline-my-show-headings-of-level 3))) (global-set-key [(M-kp-4)] (lambda () (interactive) (outline-my-show-headings-of-level 4))) (global-set-key [(M-kp-5)] (lambda () (interactive) (outline-my-show-headings-of-level 5))) (global-set-key [(M-kp-6)] (lambda () (interactive) (outline-my-show-headings-of-level 6))) (global-set-key [(M-kp-7)] (lambda () (interactive) (outline-my-show-headings-of-level 7))) (global-set-key [(M-kp-8)] (lambda () (interactive) (outline-my-show-headings-of-level 8))) (global-set-key [(M-kp-9)] (lambda () (interactive) (outline-my-show-headings-of-level 9))) (defun outline-my-show-headings-of-level (n) (interactive) (if (not outline-minor-mode) (outline-minor-mode 1)) (show-all) (let (l) (save-excursion (goto-char 0) (when (outline-on-heading-p) (add-to-list 'l (funcall outline-level)) ) (while (outline-next-heading) (add-to-list 'l (funcall outline-level)) ) (setq l (sort l '<)) (if (>= n (length l)) (message "maximum level exceeded") (hide-sublevels (nth n l)) ) ) ) ) ;;;;; hideshow (load-library "hideshow_my") (setq hs-allow-nesting t) ;; hs-minor-mode i.e. blocks (global-set-key [(M-kp-add)] 'hs-show-block) (global-set-key [(M-kp-subtract)] 'hs-hide-block) (setq my-hidden-region-font '(:box (:line-width 2 :color "ForestGreen" :style released-button) :weight semi-bold :foreground "ForestGreen")) (add-to-list 'text-property-default-nonsticky '(my-hidden-region . t)) (global-set-key [(f7)] '(lambda () (interactive) (let ((bm (buffer-modified-p))) (cond ;; show hidden region ((save-excursion (when (or (get-text-property (point) 'my-hidden-region) (when (> (point) (point-min)) (backward-char) (get-text-property (point) 'my-hidden-region)) ) (let ( (e (goto-char (next-single-property-change (point) 'my-hidden-region nil (point-max)))) (b (previous-single-property-change (point) 'my-hidden-region nil (point-min))) ) (remove-list-of-text-properties b e '(display my-hidden-region)) t ) ) ) ) ;; hide selected region (mark-active (let* ((rb (region-beginning)) (re (region-end)) (str (format " %d " (- re rb))) ) (add-text-properties rb re (list 'display (propertize str 'face my-hidden-region-font) 'my-hidden-region t) ) ) ) ;; hs-mode action (t (hs-toggle-hiding)) ) (set-buffer-modified-p bm) ) ) ) (global-set-key [(C-f7)] '(lambda () (interactive) (font-lock-fontify-buffer) ; else syntax-ppss may work incorrectly on large files (> 100K) (hs-hide-level 1) ) ) ;;;; undo/redo (require 'redo) (global-set-key [(control shift z)] 'redo) ;; select undoed text (define-key cua--cua-keys-keymap [(control z)] (lambda () (interactive) (let* ( (this-eq-last (eq this-command last-command)) (List (if this-eq-last pending-undo-list buffer-undo-list)) (ind (if this-eq-last 0 1)) (Cons (if (eq (type-of List) 'symbol) nil (nth ind List))) (Cons+1 (if (eq (type-of List) 'symbol) nil (nth (1+ ind) List))) (s (car-safe Cons)) (n (cdr-safe Cons)) mark-pos ) (undo) (when (and (eq (type-of s) 'string) (eq (type-of n) 'integer) ) (setq mark-pos (if (> n 0) (length s) (- (length s)))) (setq mark-pos (if (eq (type-of Cons+1) 'integer) (- mark-pos) mark-pos)) ;; after C-x (push-mark (+ (point) mark-pos) nil t) (setq deactivate-mark nil) ) ) ) ) ;;;; switch to buffer under cursor (global-set-key [(control meta return)] '(lambda () (interactive) (let ((th (thing-at-point 'filename)) (th-file nil) ) (if (= (length th) 0) (message "(thing-at-point 'filename) returns empty result") ;; else (let ((Bs (buffer-list))) (while Bs (with-current-buffer (pop Bs) (when buffer-file-name (when (string= th (file-name-nondirectory buffer-file-name)) (setq th-file (current-buffer)) (setq Bs nil) ) ) ) ) ) (when (and (not (get-buffer th)) (not (when th-file (setq th th-file))) (not (y-or-n-p (format "buffer \"%s\" does not exist, create new? " th))) ) (signal 'quit nil) ) (switch-to-buffer th) ) ) ) ) ;;;; rename-file-and-buffer and move-buffer-file ;; http://steve.yegge.googlepages.com/my-dot-emacs-file (defun rename-file-and-buffer (new-name) "Renames both current buffer and file it's visiting to NEW-NAME." (interactive (list (read-string "Rename file and buffer to: " (buffer-name)))) (let ((name (buffer-name)) (filename (buffer-file-name)) (new-filename (concat default-directory new-name)) (modified (buffer-modified-p)) ) (if (= (length new-name) 0) (signal 'quit nil)) (if (not filename) (message "Buffer '%s' is not visiting a file!" name) (if (and (string= name new-name) (string= filename new-filename) ) (message "Nothing to do") (if (and (get-buffer new-name) (not (eq (get-buffer new-name) (current-buffer))) ) (message "A buffer named '%s' already exists!" new-name) (progn (if (string= filename new-filename) (message "Visited file \"%s\" was not changed" filename) (rename-file filename new-name 1) (set-visited-file-name new-name) (set-buffer-modified-p modified) (message "New visited file \"%s\"" new-filename) ) (rename-buffer new-name) ) ) ) ) ) (if (get-buffer " *ECB History*") (ecb-add-buffers-to-history)) ) (defun move-buffer-file (dir) "Moves both current buffer and file it's visiting to DIR." (interactive "DNew directory: ") (let* ((name (buffer-name)) (filename (buffer-file-name)) (dir (if (string-match dir "\\(?:/\\|\\\\)$") (substring dir 0 -1) dir ) ) (newname (concat dir "/" name)) ) (if (not filename) (message "Buffer '%s' is not visiting a file!" name) (progn (copy-file filename newname 1) (delete-file filename) (set-visited-file-name newname) (set-buffer-modified-p nil) t ) ) ) ) ;;;; history back/forward ÍÀÎÁÎÐÎÒ! (defun my-history-back () (interactive) (next-buffer) (while (string-match "^\\*.+\\*$" (buffer-name)) (next-buffer) ) ) (defun my-history-forward () (interactive) (previous-buffer) (while (string-match "^\\*.+\\*$" (buffer-name)) (previous-buffer) ) ) (global-set-key [(meta left)] 'my-history-back) (global-set-key [(meta right)] 'my-history-forward) ;;;; unset read only flag for all buffers i.e. set all buffers writable (global-set-key "\C-x\M-q" '(lambda () (interactive) (let ((buffers (buffer-list))) (save-current-buffer (while buffers (when (string-match "^\\w" (buffer-name (car buffers))) (set-buffer (car buffers)) (setq buffer-read-only nil) (if (buffer-file-name) (set-file-modes buffer-file-name ?\700)) ) (setq buffers (cdr buffers)) ) ) ) ) ) ;;;; check and inform if opened file has been deleted externally (make-variable-buffer-local 'deletedfile-already-informed) (defun deletedfile-check-and-inform () (let ((buffers (buffer-list))) (save-current-buffer (catch 'break (while buffers ;; the loop (when (buffer-file-name (car buffers)) ;; buffer has visited file (set-buffer (car buffers)) (if (file-exists-p buffer-file-name) (setq deletedfile-already-informed nil) (when (not deletedfile-already-informed) (let ((a (x-popup-dialog t (list (concat "emacs: file has been deleted: " (buffer-file-name)) '("Resave" . 1) '("Mark modified" . 2) '("Ignore" . 3) '("Kill buffer" . 4) "" '("Stop checking deleted files" . 5) ) ))) (cond ((= a 1) (set-buffer-modified-p t) (save-buffer)) ((= a 2) (set-buffer-modified-p t)) ((= a 3) ) ((= a 4) (kill-buffer nil)) ((= a 5) (message "checking deleted files has been stopped. to start again use M-x deletedfile-timer-start ") ; (signal 'quit nil) - do the same but with additional "Quit" message (deletedfile-timer-stop) (throw 'break nil) ) ) ) (setq deletedfile-already-informed t) ) ;; end when not deletedfile-already-informed ) ;; end if ) ;(message "endless loop test") (setq buffers (cdr buffers)) ) ;; end of the loop ) ;; end of 'catch ) ) ) (defun deletedfile-clear-already-informed-flag () (setq deletedfile-already-informed nil) ) (add-hook 'after-save-hook 'deletedfile-clear-already-informed-flag) (defvar deletedfile-timer nil) (defun deletedfile-timer-start () (interactive) (when deletedfile-timer (cancel-timer deletedfile-timer)) (setq deletedfile-timer (run-with-timer 5 5 'deletedfile-check-and-inform)) (message "deletedfile timer has been started") ) (defun deletedfile-timer-stop () (interactive) (if deletedfile-timer (progn (cancel-timer deletedfile-timer) (setq deletedfile-timer nil) (message "deletedfile timer has been stopped") ) ;; else (message "deletedfile timer is already inactive") ) ) (deletedfile-timer-start) ;;;; insert date time string (global-set-key [f5] '(lambda () (interactive) (insert (format-time-string "%Y-%m-%d %a %H:%M")) ) ) ;;;; modes ;;;;; info-mode (add-hook 'Info-mode-hook (lambda () (define-key Info-mode-map [M-left] 'Info-history-back) (define-key Info-mode-map [M-right] 'Info-history-forward) (define-key Info-mode-map [M-S-left] (lambda () (interactive ) (while (Info-history-back)))) (define-key Info-mode-map [M-C-left] 'my-history-back) ;; clear info history i.e. set root node (define-key Info-mode-map "\C-b" (lambda () (interactive) (setq Info-history nil) (redraw-display))) ) ) ;;;;; perl-mode ;; cperl-mode is preferred to perl-mode ??? ;; http://www.emacswiki.org/cgi-bin/wiki/CPerlMode ;; "Brevity is the soul of wit" ;(defalias 'perl-mode 'cperl-mode) (setq perl-mode-hook 'my-perl-customizations) (defun my-perl-customizations () (setq outline-regexp "[ \t]*\\(package\\|sub\\)[ \t]+[a-zA-Z0-9_]+\\|=[a-zA-Z0-9_]+") (setq outline-level (lambda () (cond ((string= (match-string 1) "package") 1) ((string= (match-string 1) "sub") 2) (t 3) ) ) ) (outline-minor-mode 1) (hs-minor-mode 1) (abbrev-mode 1) ;; semantic minimal initialization (setq semantic--parse-table t) (semantic-new-buffer-fcn) ;; semantic simplest perl support (semantic-install-function-overrides '( (parse-region . semantic-perl-parse-region-simplest) (parse-changes . (lambda () (semantic-parse-tree-set-needs-rebuild))) ; taken from cedet-1.0pre4\semantic\semantic-html.el ) ) (font-lock-fontify-buffer) ; else syntax-ppss may work incorrectly on large files (> 100K) (ecb-rebuild-methods-buffer t) ) (defun semantic-perl-parse-region-simplest (&rest ignore) (let (prevpos tgfirst tgp p-list tgf f-list (case-fold-search nil) ) (save-excursion (save-restriction (widen) ;; packages (goto-char 0) (while (re-search-forward "^[ \t]*\\(package[ \t]+[a-zA-Z0-9_]+\\)" nil t) (when (not (nth 4 (syntax-ppss))) ; not inside comments (when tgp (semantic-tag-set-bounds tgp prevpos (match-beginning 0))) (setq tgp (semantic-tag-new-type (match-string 1) "class" nil nil)) (push tgp p-list) (setq prevpos (match-beginning 0)) (when (not tgfirst) (setq tgfirst tgp)) ) ) (when tgp (semantic-tag-set-bounds tgp prevpos (1+ (buffer-size)))) (when p-list (setq p-list (nreverse p-list))) ;; package main (setq tgp (semantic-tag-new-type "package main" "class" nil nil)) (if p-list (when (> (semantic-tag-start tgfirst) 1) (semantic-tag-set-bounds tgp 1 (semantic-tag-start tgfirst)) (push tgp p-list) ) ;; else (semantic-tag-set-bounds tgp 1 (1+ (buffer-size))) (push tgp p-list) ) ;; functions (dolist (tgp p-list) (setq tgf nil) (setq f-list nil) (goto-char (semantic-tag-start tgp)) (while (re-search-forward "^.*\\b\\(sub[ \t]+[a-zA-Z0-9_]+\\)" (semantic-tag-end tgp) t) (when (not (nth 4 (syntax-ppss))) ; not inside comments (when tgf (semantic-tag-set-bounds tgf prevpos (match-beginning 0))) (setq tgf (semantic-tag (match-string 1) 'function)) (push tgf f-list) (setq prevpos (match-beginning 0)) ) ) (when tgf (semantic-tag-set-bounds tgf prevpos (semantic-tag-end tgp))) (semantic-tag-put-attribute tgp :members (nreverse f-list)) ) ) ;; save-restriction ) ;; save-excursion p-list ) ) (add-to-list 'ecb-show-tags (list 'perl-mode '(type flattened nil) '(function flattened nil))) ;;;;; c# mode (autoload 'csharp-mode "csharp-mode-0.7.0.el" "Major mode for editing C# code." t) (setq auto-mode-alist (append '(("\\.cs$" . csharp-mode)) auto-mode-alist)) ;;;;; nxhtml - html + php + javascript + css multi mode mode (load-library "EmacsW32/nxml/autostart.el") (setq nxhtml-skip-welcome t) ;; nxhtml redefine these keys to nxml-backward/forward-element - see nxhtml-autoload.el (add-hook 'nxml-mode-hook (lambda () (define-key nxml-mode-map [M-left] 'my-history-back) (define-key nxml-mode-map [M-right] 'my-history-forward) ) t ) ;;;;; php-mode (load-library "semantic-php-simplest-grammar-by.el") (add-hook 'php-mode-hook 'my-php-customizations) (defun my-php-customizations () ;; folding (i.e. outlining) (setq outline-regexp "[ \t]*\\(\\(\\(public\\|private\\)[ \t]+\\)?\\(static[ \t]+\\)?function\\|class\\|#head\\)") (setq outline-level (lambda () (cond ((string-match "#head" (match-string 1)) 1) ((string-match "class" (match-string 1)) 2) (t 3) ) ) ) (outline-minor-mode 1) (hs-minor-mode 1) ;; semantic simplest php support (setq semantic-lex-analyzer #'semantic-lex-php-simplest) (semantic-php-simplest-grammar-by--install-parser) (semantic-new-buffer-fcn) ; I'm not sure why is it needed, but it works (ecb-rebuild-methods-buffer t) ) (add-to-list 'ecb-show-tags (list 'php-mode '(type flattened nil) '(function flattened nil))) ;;;;; lisp-mode (defun my-lisp-customization () (setq outline-regexp ";;;;*\\|(\\w+") (setq outline-level (lambda () (if (eq (char-after (match-beginning 0)) ?\( ) (save-excursion (let ( (s1 (re-search-backward "^;;;;*" nil t)) (s1-len (length (match-string 0))) (s2 (re-search-forward "^;;;;*" nil t 2)) ; first results will be the same place (s2-len (length (match-string 0))) ) (cond ((and s1 s2 (> s2-len s1-len)) s2-len) ((and (not s1) s2) s2-len) (t 100) ) ) ) (length (match-string 0)) ) ) ) (outline-minor-mode 1) (hs-minor-mode 1) (ecb-rebuild-methods-buffer t) ) (add-hook 'lisp-mode-hook 'my-lisp-customization) (add-hook 'emacs-lisp-mode-hook 'my-lisp-customization) (add-hook 'lisp-interaction-mode-hook 'my-lisp-customization) ;;;;; sh-mode (setq ecb-non-semantic-exclude-modes (remq 'sh-mode ecb-non-semantic-exclude-modes)) ;;;; session automatically saved on exit and restored at start (desktop-read) (add-to-list 'desktop-globals-to-save 'minibuffer-history) (add-to-list 'desktop-globals-to-save 'command-history) (add-to-list 'desktop-globals-to-save 'file-name-history) (add-to-list 'desktop-globals-to-save 'extended-command-history) (add-to-list 'desktop-globals-to-save 'revert-buffer-function) (add-to-list 'desktop-globals-to-save 'list-command-history) (add-to-list 'desktop-globals-to-save 'regexp-history) (add-to-list 'desktop-globals-to-save 'set-variable-value-history) (add-to-list 'desktop-globals-to-save 'shell-command-history) (add-to-list 'desktop-globals-to-save 'yes-or-no-p-history) (add-to-list 'desktop-globals-to-save 'read-expression-history) (add-to-list 'desktop-globals-to-save 'read-envvar-name-history) (add-to-list 'desktop-globals-to-save 'buffer-name-history) (add-to-list 'desktop-globals-to-save 'ecb-source-path) (add-to-list 'desktop-globals-to-save 'ecb-layout-name) (add-to-list 'desktop-globals-to-save 'ecb-excluded-directories-regexps) ;; significant options for files located on a network (add-to-list 'desktop-globals-to-save 'auto-revert-stop-on-user-input) (add-to-list 'desktop-globals-to-save 'auto-save-default) (add-to-list 'desktop-globals-to-save 'auto-revert-mode) (add-to-list 'desktop-locals-to-save 'auto-revert-mode) (add-to-list 'desktop-locals-to-save 'buffer-auto-save-file-name) (ecb-activate) (ecb-add-buffers-to-history) (desktop-save-mode 1)