Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; GNU Emacs init file
- (message "loading jpkotta's init.el")
- (defun make-tictoc ()
- (current-time))
- (defmacro tic (tt)
- `(setq ,tt (current-time)))
- (defun toc (tt)
- (- (time-to-seconds (current-time))
- (time-to-seconds tt)))
- ;; profile this file's evaluation time
- (setq init-el-time (make-tictoc))
- ;; this init file uses principles from:
- ;; http://a-nickels-worth.blogspot.com/2007/11/effective-emacs.html
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Paths
- ;; add my elisp files to the load path
- (add-to-list 'load-path user-emacs-directory)
- ;; info directory
- (eval-after-load "info"
- '(add-to-list 'Info-additional-directory-list "~/.info")
- )
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Custom
- ;; store settings from customization system in a separate file
- (setq custom-file (concat user-emacs-directory "custom.el"))
- (message "loading customizations from %s" custom-file)
- (let ((custom-el-time (make-tictoc)))
- (load custom-file 'noerror)
- (message "custom.el loaded in %f s" (toc custom-el-time)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Miscellaneous
- (defmacro with-library (feature &rest body)
- "Evaluate BODY only if FEATURE is provided. (require FEATURE) will be attempted."
- (declare (indent defun))
- `(when (require ,feature nil 'noerror)
- ,@body))
- (defun setup-RAIDE-file ()
- "View RAIDE files from Eagle."
- (interactive)
- (recode-region (point-min) (point-max)
- 'cp437-dos 'iso-latin-1-dos)
- (buffer-face-set 'fixed-pitch)
- (view-mode))
- (defun defadvice-list (funclist class name lambda-expr)
- "A convenience function to define the same advice on several
- functions at once. FUNCLIST is a list of functions. CLASS is
- one of `before', `after', or `around'. NAME is a name for the
- advice. LAMBDA-EXPR is a lambda expression that is the body of
- the advice. The advice is not protected, is put at the
- beginning of the functions' advice lists, and is activated
- immediately."
- (dolist (func funclist)
- (ad-add-advice func
- `(,name
- nil ;; protect
- t ;; activate
- (advice . ,lambda-expr))
- class
- 'first) ;; position
- (ad-activate func)))
- ;; suspend-frame is annoying in X, but useful in terminals.
- (global-set-key (kbd "C-x C-z")
- (lambda () (interactive)
- (if (display-graphic-p)
- (message "Use `M-x suspend-frame' instead.")
- (suspend-frame))))
- (defun pl-tr (STRING FROM TO)
- "perlish transpose: similar to STRING =~ tr/FROM/TO/"
- (replace-regexp-in-string
- (concat "\[" FROM "\]")
- (lambda (s)
- (string (elt TO (search s FROM))))
- STRING))
- ;; ;; http://emacs.wordpress.com/2007/01/17/eval-and-replace-anywhere/
- ;; (defun eval-and-replace-last-sexp ()
- ;; "Replace the preceding sexp with its value."
- ;; (interactive "*")
- ;; (save-excursion
- ;; (with-syntax-table emacs-lisp-mode-syntax-table
- ;; (backward-kill-sexp)))
- ;; (condition-case nil
- ;; (prin1 (eval (read (current-kill 0)))
- ;; (current-buffer))
- ;; (error (message "Invalid expression")
- ;; (insert (current-kill 0)))))
- ;; (global-set-key (kbd "C-c C-e") 'eval-and-replace-last-sexp)
- (global-set-key (kbd "C-c e") 'eval-print-last-sexp)
- ;; locking is dumb sometimes
- ;; this effectively disables it by always silently stealing the file
- (defun ask-user-about-lock (file other-user)
- t)
- ;; enable with M-x sticky-buffer-mode
- (define-minor-mode sticky-buffer-mode
- "Make the current window always display this buffer."
- nil " sticky" nil
- (set-window-dedicated-p (selected-window) sticky-buffer-mode))
- ;; from http://svn.red-bean.com/repos/kfogel/trunk/.emacs
- (defmacro do-on-lines (start end &rest body)
- "Run BODY at each line start of every line from START to END."
- (declare (indent defun))
- `(save-excursion
- (save-restriction
- (save-match-data
- (goto-char ,start)
- (while (< (point) ,end)
- (beginning-of-line)
- ,@body
- (forward-line 1))))))
- ;; not used anywhere but interesting
- (defun permutations (bag)
- "Return a list of all the permutations of the input."
- ;; If the input is nil, there is only one permutation:
- ;; nil itself
- (if (null bag)
- '(())
- ;; Otherwise, take an element, e, out of the bag.
- ;; Generate all permutations of the remaining elements,
- ;; And add e to the front of each of these.
- ;; Do this for all possible e to generate all permutations.
- (mapcan (lambda (e)
- (mapcar (lambda (p) (cons e p))
- (permutations
- (remove* e bag :count 1))))
- bag)))
- (defun filter (condp lst)
- "The filter higher-order function. Returns a list containing
- all elements of LST for which CONDP is not nil."
- (delq nil (mapcar (lambda (x) (and (funcall condp x) x)) lst)))
- ;; narrowing makes a region effectively the entire buffer
- ;; useful for not mangling the entire buffer
- ;; disable with widen
- (put 'narrow-to-region 'disabled nil)
- ;; I hit this by accident sometimes, and don't find the default
- ;; binding compose-mail useful.
- (global-unset-key (kbd "C-x m"))
- (defun minibuffer-refocus ()
- "Refocus the minibuffer if it is waiting for input."
- (interactive)
- (when (active-minibuffer-window)
- (message "") ;; clear the echo area, in case it overwrote the minibuffer
- (select-window (minibuffer-window))))
- (defadvice mouse-set-point (around no-mouse-select-window-if-minibuffer-active activate)
- (unless (minibuffer-window-active-p (selected-window))
- ad-do-it))
- ;; cancel everything, including active minibuffers and recursive edits
- (global-set-key (kbd "C-M-g") 'top-level)
- (defun remove-from-list (symbol element)
- "Inverse of `add-to-list'. TODO: add compare-fn."
- (set symbol (delete element (eval symbol))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Org Mode
- (defun jpk/org-mode-hook ()
- (interactive)
- (local-unset-key (kbd "C-<tab>"))
- (local-unset-key (kbd "C-S-<iso-lefttab>"))
- (local-unset-key (kbd "<backtab>"))
- (local-unset-key (kbd "<S-iso-lefttab>"))
- (local-unset-key (kbd "M-<up>"))
- (local-unset-key (kbd "M-<down>"))
- (local-unset-key (kbd "S-<left>"))
- (local-unset-key (kbd "S-<right>"))
- (local-unset-key (kbd "C-S-<left>"))
- (local-unset-key (kbd "C-S-<right>"))
- (local-set-key (kbd "C-<down>") 'outline-forward-same-level)
- (local-set-key (kbd "C-<up>") 'outline-backward-same-level)
- (when (featurep 'filladapt)
- (filladapt-mode 0))
- (visual-line-mode 1)
- (with-library 'flyspell
- (flyspell-mode 1)))
- (eval-after-load "org"
- '(progn
- (setq-default org-hide-leading-stars t)
- (add-to-list 'org-mode-hook 'jpk/org-mode-hook)
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; misc insertions
- ;; insert placeholder text
- (defun insert-lorem-ipsum ()
- (interactive "*")
- (insert "Lorem ipsum dolor sit amet, consectetur adipisicing "
- "elit, sed do eiusmod tempor incididunt ut labore et "
- "dolore magna aliqua. Ut enim ad minim veniam, quis "
- "nostrud exercitation ullamco laboris nisi ut aliquip "
- "ex ea commodo consequat. Duis aute irure dolor in "
- "reprehenderit in voluptate velit esse cillum dolore "
- "eu fugiat nulla pariatur. Excepteur sint occaecat "
- "cupidatat non proident, sunt in culpa qui officia "
- "deserunt mollit anim id est laborum."))
- (defun insert-look-of-disapproval (arg)
- (interactive "*P")
- (if (not arg)
- ;;(mapconcat 'ucs-insert '(3232 95 3232) "")
- (insert "ಠ_ಠ")
- (insert " _____) _____)\n"
- " / \\ / \\\n"
- "( O ) ( O )\n"
- " \\___/ \\___/\n"
- " ======= \n")
- ))
- (global-set-key (kbd "C-c w t f") 'insert-look-of-disapproval)
- (defun insert-awesome-face (arg)
- (interactive "*P")
- (if (not arg)
- ;;(ucs-insert 9787)
- (insert "☻")
- (insert " __ __ \n"
- " / o / o \n"
- "|____| |____| \n"
- " \n"
- "------------- \n"
- "| )\n"
- " \\ ,-----, \n"
- " '-./____-' \n")
- ))
- (defun insert-look-of-worry ()
- (interactive "*")
- (insert "٩( ͡๏̯͡๏)۶"))
- (defun list-unicode-display (&optional regexp)
- "Display a list of unicode characters and their names in a buffer."
- (interactive "sRegexp (default \".*\"): ")
- (let* ((regexp (or regexp ".*"))
- (case-fold-search t)
- ;;(cmp (lambda (x y) (string< (car x) (car y))))
- (cmp (lambda (x y) (< (cdr x) (cdr y))))
- ;; alist like ("name" . code-point)
- (char-alist (sort (filter (lambda (x) (string-match regexp (car x)))
- (ucs-names))
- cmp)))
- (with-help-window "*Unicode characters*"
- (with-current-buffer standard-output
- (dolist (c char-alist)
- (insert (format "0x%06X\t" (cdr c)))
- (insert (cdr c))
- (insert (format "\t%s\n" (car c))))))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Date and Time
- (defvar insert-time-format "%H:%M:%S"
- "*Format for `insert-time', see `format-time-string' for syntax.")
- (defvar insert-date-format "%Y-%m-%d"
- "*Format for `insert-date', see `format-time-string' for syntax.")
- (defun insert-time-str (fmt)
- "Insert a formatted timestamp string in the buffer. See
- `format-time-string' for syntax of FMT."
- (insert (format-time-string fmt (current-time))))
- (defun insert-time ()
- "Insert the current time in the buffer."
- (interactive "*")
- (insert-time-str insert-time-format))
- (defun insert-date ()
- "Insert the current date in the buffer."
- (interactive "*")
- (insert-time-str insert-date-format))
- (defun insert-date-and-time ()
- "Insert the current date and time in the buffer."
- (interactive "*")
- (insert-time-str (concat insert-date-format " " insert-time-format)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ssh
- ;; keychain is a way to manage ssh-agents. In particular, it looks
- ;; for a running ssh-agent and stores it's env vars in a file, any
- ;; program that knows how to read the file can use the agent.
- (with-library 'keychain-environment
- (refresh-keychain-environment))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; C SubWordMode
- ;; FindSubWordsInCamelCase
- ;; the old name is c-subword-mode, and it did not define a global mode
- ;; (with-library 'c-subword-mode
- ;; (define-global-minor-mode global-subword-mode
- ;; c-subword-mode
- ;; (lambda () (c-subword-mode 1))))
- ;; (with-library 'subword
- ;; (global-subword-mode 1)
- ;; )
- (with-library 'syntax-subword
- (global-syntax-subword-mode 1)
- )
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Diminish
- ;; Hide some minor mode indicators in the modeline.
- (eval-after-load "eldoc" '(diminish 'eldoc-mode ""))
- (eval-after-load "filladapt" '(diminish 'filladapt-mode ""))
- (eval-after-load "doxymacs" '(diminish 'doxymacs-mode ""))
- (eval-after-load "auto-complete" '(diminish 'auto-complete-mode ""))
- (eval-after-load "face-remap" '(diminish 'buffer-face-mode ""))
- (eval-after-load "highlight-parentheses" '(diminish 'highlight-parentheses-mode ""))
- (eval-after-load "wrap-region" '(diminish 'wrap-region-mode ""))
- (eval-after-load "abbrev" '(diminish 'abbrev-mode ""))
- (eval-after-load "fixme-mode" '(diminish 'fixme-mode ""))
- (eval-after-load "yasnippet" '(diminish 'yas/minor-mode ""))
- (eval-after-load "flyspell" '(diminish 'flyspell-mode ""))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Help
- (autoload 'apropos-toc "apropos-toc.el"
- "A nicer apropos buffer." t)
- (global-set-key (kbd "C-h a") 'apropos-toc)
- (setq message-log-max 1000)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; numbers and strings
- ;; make it a bit easier to do hex sequences
- ;; could replace string-to-number in most cases
- (defun str2num (str &optional base)
- "Like string-to-number, but with 'normal' (C-style) prefixes
- for non-decimal strings."
- (let ((case-fold-search nil))
- (cond
- ((string-match "0x[0-9A-F]+" str)
- (string-to-number (replace-regexp-in-string "0x" "" str)
- 16))
- ((string-match "0o[0-7]+" str)
- (string-to-number (replace-regexp-in-string "0o" "" str)
- 8))
- ((string-match "0d[0-9]+" str)
- (string-to-number (replace-regexp-in-string "0d" "" str)
- 10))
- ((string-match "0b[01]+" str)
- (string-to-number (replace-regexp-in-string "0b" "" str)
- 2))
- (t
- (string-to-number str base)))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; CUA mode
- ;; Provides CUA-type ("Common User Access") keybindings, usable
- ;; rectangles, and other goodies. Most things are set through custom.
- ;; CUA mode takes over C-z, C-x, C-c, and C-v completely. This will
- ;; enable us to turn those bindings off in certain buffers.
- (make-variable-buffer-local 'cua--ena-cua-keys-keymap)
- ;; (cua-mode t) ;; enable with C-x, C-c, C-v
- (cua-selection-mode t) ;; enable without C-x, C-c, C-v
- (eval-after-load "cua-rect"
- '(progn
- (defun cua-sequence-rectangle (first incr format)
- "Resequence each line of CUA rectangle starting from FIRST.
- The numbers are formatted according to the FORMAT string."
- (interactive
- (list (if current-prefix-arg
- (prefix-numeric-value current-prefix-arg)
- (str2num
- (read-string "Start value: (0) " nil nil "0")))
- (str2num
- (read-string "Increment: (1) " nil nil "1"))
- (read-string (concat "Format: (" cua--rectangle-seq-format ") "))))
- (if (= (length format) 0)
- (setq format cua--rectangle-seq-format)
- (setq cua--rectangle-seq-format format))
- (cua--rectangle-operation 'clear nil t 1 nil
- '(lambda (s e l r)
- (delete-region s e)
- (insert (format format first))
- (setq first (+ first incr)))))
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; revert
- (global-auto-revert-mode 1)
- (setq auto-revert-verbose nil)
- (global-set-key (kbd "<f5>") 'revert-buffer)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; clipboard
- (setq x-select-enable-clipboard t
- x-select-enable-primary nil
- x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)
- select-active-regions t)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; unicode
- ;; tip - use ucs-insert to insert unicode characters by name
- ;; from Jonathan Arkell (http://stackoverflow.com/questions/154097/whats-in-your-emacs/154980#154980)
- (prefer-coding-system 'utf-8)
- (set-default-coding-systems 'utf-8)
- (set-terminal-coding-system 'utf-8)
- (set-keyboard-coding-system 'utf-8)
- (setq default-buffer-file-coding-system 'utf-8)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Daemon/Server
- ;; from http://emacs-fu.blogspot.com/2009/05/getting-your-ip-address.html
- ;; does not work on Windows
- (defun get-ip-address (&optional dev)
- "get the IP-address for device DEV (default: eth0)"
- (let ((dev (if dev dev "eth0")))
- (format-network-address (car (network-interface-info dev)) t)))
- (setq host-ip-address
- (or (get-ip-address "eth0")
- (get-ip-address "eth1")
- (get-ip-address "eth2")
- (get-ip-address "wlan0")
- (get-ip-address "wlan1")
- (get-ip-address "lo")))
- ;; use network rather than local sockets
- ;; (setq server-use-tcp t
- ;; server-host host-ip-address)
- ;; daemonp tests for daemon-ness, but is not available in emacs22
- (unless (fboundp 'daemonp)
- (defun daemonp () nil))
- (defadvice server-start (after remove-kill-buffer-hook activate)
- ;; don't ask if it's OK to kill a buffer if some client has it open
- (remove-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function))
- ;; confirm killing emacsclients
- ;; can't advise server-delete-client, it's used elsewhere
- (eval-after-load "server"
- '(progn
- (defun server-save-buffers-kill-terminal (arg)
- ;; Called from save-buffers-kill-terminal in files.el.
- "Offer to save each buffer, then kill the current client.
- With ARG non-nil, silently save all file-visiting buffers, then kill.
- If emacsclient was started with a list of filenames to edit, then
- only these files will be asked to be saved."
- (let ((proc (frame-parameter (selected-frame) 'client)))
- (cond ((eq proc 'nowait)
- ;; Nowait frames have no client buffer list.
- (if (cdr (frame-list))
- (progn (save-some-buffers arg)
- (delete-frame))
- ;; If we're the last frame standing, kill Emacs.
- (save-buffers-kill-emacs arg)))
- ((processp proc)
- (let ((buffers (process-get proc 'buffers)))
- ;; If client is bufferless, emulate a normal Emacs exit
- ;; and offer to save all buffers. Otherwise, offer to
- ;; save only the buffers belonging to the client.
- (save-some-buffers
- arg (if buffers
- (lambda () (memq (current-buffer) buffers))
- t))
- (when (y-or-n-p "Kill this emacsclient? ") ;; XXX my change
- (server-delete-client proc))))
- (t (error "Invalid client frame")))))
- (defalias 'kill-emacs-server 'client-save-kill-emacs)
- (defun client-save-kill-emacs (&optional display)
- " This is a function that can bu used to shutdown save buffers and
- shutdown the emacs daemon. It should be called using
- emacsclient -e '(client-save-kill-emacs)'. This function will
- check to see if there are any modified buffers or active clients
- or frame. If so an x window will be opened and the user will
- be prompted."
- (interactive)
- (let (new-frame modified-buffers active-clients-or-frames)
- ;; Check if there are modified buffers or active clients or frames.
- (setq modified-buffers (modified-buffers-exist))
- (setq active-clients-or-frames (or (> (length server-clients) 1)
- (> (length (frame-list)) 1)))
- ;; Create a new frame if prompts are needed.
- (when (or modified-buffers active-clients-or-frames)
- (when (not (eq window-system 'x))
- (message "Initializing x windows system.")
- (x-initialize-window-system))
- (when (not display) (setq display (getenv "DISPLAY")))
- (message "Opening frame on display: %s" display)
- (select-frame (make-frame-on-display display '((window-system . x)))))
- ;; Save the current frame.
- (setq new-frame (selected-frame))
- ;; When displaying the number of clients and frames:
- ;; subtract 1 from the clients for this client.
- ;; subtract 2 from the frames this frame (that we just created) and the default frame.
- (when (or (not active-clients-or-frames)
- (yes-or-no-p
- (format "There are currently %d clients and %d frames. Exit anyway? "
- (- (length server-clients) 1)
- (- (length (frame-list)) 2))))
- ;; If the user quits during the save dialog then don't exit emacs.
- ;; Still close the terminal though.
- (let ((inhibit-quit t))
- ;; Save buffers
- (with-local-quit
- (save-some-buffers))
- (if quit-flag
- (setq quit-flag nil)
- ;; Kill all remaining clients
- (progn
- (dolist (client server-clients)
- (server-delete-client client))
- ;; Exit emacs
- (kill-emacs)))))
- ;; If we made a frame then kill it.
- (when (or modified-buffers active-clients-or-frames)
- (delete-frame new-frame))))
- (defun modified-buffers-exist ()
- "This function will check to see if there are any buffers
- that have been modified. It will return true if there are
- and nil otherwise. Buffers that have buffer-offer-save set to
- nil are ignored."
- (let (modified-found)
- (dolist (buffer (buffer-list))
- (when (and (buffer-live-p buffer)
- (buffer-modified-p buffer)
- (not (buffer-base-buffer buffer))
- (or (buffer-file-name buffer)
- (progn
- (set-buffer buffer)
- (and buffer-offer-save
- (> (buffer-size) 0)))))
- (setq modified-found t)))
- modified-found))
- ))
- (defun delete-frame-or-kill-emacs ()
- (interactive)
- (condition-case err
- (delete-frame)
- (error
- (if (daemonp)
- (if (string= "y" (downcase (read-from-minibuffer
- "Kill emacs (y/n)? " "n")))
- (save-buffers-kill-emacs)
- (message "Cancelled."))
- (save-buffers-kill-emacs)))))
- (global-set-key (kbd "C-x C-c") 'delete-frame-or-kill-emacs)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Web Browser
- (defcustom browse-url-opera-arguments '()
- "A list of strings passed to the Opera browser as arguments."
- :version "21.1"
- :type '(repeat (string :tag "Argument"))
- :group 'browse-url)
- (defun browse-url-opera (url &optional new-window)
- "Ask Opera to load URL. Default to the URL around or before
- point. The strings in variable `browse-url-opera-arguments'
- are also passed.
- When called interactively, if variable `browse-url-new-window-flag' is
- non-nil, load the document in a new browser window, otherwise use an
- existing one. A non-nil interactive prefix argument reverses the
- effect of `browse-url-new-window-flag'.
- When called non-interactively, optional second argument NEW-WINDOW is
- used instead of `browse-url-new-window-flag'."
- (interactive (browse-url-interactive-arg "URL: "))
- (apply 'start-process (concat "opera " url)
- nil
- "opera"
- (append
- browse-url-gnome-moz-arguments
- (if (browse-url-maybe-new-window new-window)
- '("-newwindow"))
- (list url))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; auto-complete
- ;; TAB completion with a nice UI
- (add-to-list 'load-path (concat user-emacs-directory "auto-complete"))
- (with-library 'auto-complete-config
- (ac-config-default)
- (add-to-list 'ac-dictionary-directories
- (concat user-emacs-directory "auto-complete/dict")))
- (eval-after-load "auto-complete"
- '(progn
- ;; make expanding work when moving forwards or backwards through
- ;; the candidate list
- (defun ac-expand-1 (forward?)
- "Main implementation of `ac-expand' and `ac-expand-previous'."
- (interactive)
- (unless (ac-expand-common)
- (let ((string (ac-selected-candidate)))
- (when string
- (when (equal ac-prefix string)
- (if forward?
- (ac-next)
- (ac-previous))
- (setq string (ac-selected-candidate)))
- (ac-expand-string string t) (or (eq last-command 'ac-expand)
- (eq last-command 'ac-expand-previous)))
- ;; Do reposition if menu at long line
- (if (and (> (popup-direction ac-menu) 0)
- (ac-menu-at-wrapper-line-p))
- (ac-reposition))
- (setq ac-show-menu t)
- string)))
- (defun ac-expand ()
- "Try expand, and if expanded twice, select next candidate."
- (interactive)
- (ac-expand-1 t))
- (defun ac-expand-previous ()
- "Try expand, and if expanded twice, select previous candidate."
- (interactive)
- (ac-expand-1 nil))
- ;; redefine this so it doesn't expand on C++ comments
- (defun ac-prefix-valid-file ()
- "Existed (or to be existed) file prefix."
- (let* ((line-beg (line-beginning-position))
- (end (point))
- (start (or (let ((point (re-search-backward "[\"<>'= \t\r\n]" line-beg t)))
- (if point (1+ point)))
- line-beg))
- (file (buffer-substring start end)))
- (when (and file
- (not (string-match "//+" file)) ;; C++ comments
- (or (string-match "^/" file)
- (and (setq file (and (string-match "^[^/]*/" file)
- (match-string 0 file)))
- (file-directory-p file))))
- start)))
- ;; ;; extra sources
- ;; (with-library 'ac-dabbrev
- ;; (add-to-list 'ac-sources 'ac-source-dabbrev))
- ;; (setq-default ac-sources ac-sources)
- ;; keybinds
- (define-key ac-complete-mode-map (kbd "C-n") 'ac-next)
- (define-key ac-complete-mode-map (kbd "C-p") 'ac-previous)
- (define-key ac-complete-mode-map (kbd "M-k") 'ac-next)
- (define-key ac-complete-mode-map (kbd "M-i") 'ac-previous)
- (define-key ac-complete-mode-map (kbd "<backtab>") 'ac-expand-previous)
- ;; (define-key ac-complete-mode-map (kbd "<backtab>") 'ac-previous)
- ;; (define-key ac-complete-mode-map (kbd "<tab>") 'ac-next)
- ;; (define-key ac-complete-mode-map (kbd "M-/") 'ac-expand)
- ;; workaround for flyspell-mode
- (ac-flyspell-workaround)
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Flyspell
- (eval-after-load "flyspell"
- '(define-key flyspell-mode-map (kbd "M-TAB") nil))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Remember.el remembers things
- (add-to-list 'load-path (concat user-emacs-directory "remember-2.0/"))
- (autoload 'remember "remember.el" nil t)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Bookmarks
- ;; bm.el is a visible bookmark package. Bookmarks are indicated with
- ;; highlighting in the text and/or the fringe. They are optionally
- ;; (per-buffer) persistent.
- (autoload 'bm-toggle "bm" "Toggle bookmark in current buffer." t)
- (autoload 'bm-next "bm" "Goto next bookmark." t)
- (autoload 'bm-previous "bm" "Goto previous bookmark." t)
- (autoload 'bm-toggle-mouse "bm" "Toggle bookmark with mouse." t)
- (autoload 'bm-next-mouse "bm" "Goto next bookmark with mouse." t)
- (autoload 'bm-previous-mouse "bm" "Goto previous bookmark with mouse." t)
- (setq bm-marker 'bm-marker-right)
- (global-set-key (kbd "C-c m m") 'bm-toggle)
- (global-set-key (kbd "C-c m n") 'bm-next)
- (global-set-key (kbd "C-c m p") 'bm-previous)
- (global-set-key (kbd "<right-fringe> <mouse-5>") 'bm-next-mouse)
- (global-set-key (kbd "<right-fringe> <mouse-4>") 'bm-previous-mouse)
- (global-set-key (kbd "<right-fringe> <mouse-1>") 'bm-toggle-mouse)
- ;; breadcrumb.el is similar to bm.el, but global across all buffers
- ;; and without the visual indicators. Also, provides an interactive
- ;; buffer for showing all breadcrumbs.
- (dolist (func '(bc-set bc-previous bc-next bc-local-previous bc-local-next
- bc-goto-current bc-list bc-clear))
- (autoload func "breadcrumb.el" "Breadcrumbs for Emacs." t))
- ;; bindings are via 123-menu
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; re-builder
- (setq reb-re-syntax 'string)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; hide-lines
- (autoload 'hide-non-matching-lines "hide-lines"
- "Hide all lines not matching a regexp." t)
- (autoload 'hide-matching-lines "hide-lines"
- "Hide all lines matching a regexp." t)
- (autoload 'show-all-invisible "hide-lines"
- "Show all lines hidden by hide-lines." t)
- (global-set-key (kbd "C-c s a") 'show-all-invisible)
- (global-set-key (kbd "C-c s s") 'hide-non-matching-lines)
- (global-set-key (kbd "C-c s d") 'hide-matching-lines)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Hideshow (code folding)
- (autoload 'hideshowvis-minor-mode "hideshowvis.el"
- "Code folding indicators in the left fringe." t)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; ido - Interactive Do
- (ido-mode 'both) ;; both buffers and files
- (ido-everywhere t)
- (setq ido-confirm-unique-completion t)
- (setq ido-default-buffer-method 'selected-window)
- (setq ido-default-file-method 'selected-window)
- (setq ido-enable-flex-matching t)
- (setq ido-ignore-buffers '("\\` " "^\\*Completion" "^\\*Ido"))
- (setq ido-max-work-file-list 50)
- (setq ido-rotate-file-list-default nil)
- (setq ido-save-directory-list-file "~/.emacs.d/.ido.last")
- (setq ido-show-dot-for-dired t)
- (setq ido-work-directory-match-only nil)
- (defun jpk/ido-setup-hook ()
- (define-key ido-completion-map [remap backward-kill-word] nil)
- (define-key ido-completion-map (kbd "<C-backspace>") 'backward-kill-word)
- (define-key (cdr (assoc 'ido-mode minor-mode-map-alist)) ;; ido-mode-map
- [remap write-file] nil)
- )
- (add-hook 'ido-setup-hook 'jpk/ido-setup-hook)
- (defun jpk/ido-minibuffer-setup-hook ()
- ;; disallow wrapping of the minibuffer
- (make-local-variable 'truncate-lines)
- (setq truncate-lines t))
- (add-hook 'ido-minibuffer-setup-hook 'jpk/ido-minibuffer-setup-hook)
- (defvar ido-enable-replace-completing-read t
- "If t, use ido-completing-read instead of completing-read if possible.
- Set it to nil using let in around-advice for functions where the
- original completing-read is required. For example, if a function
- foo absolutely must use the original completing-read, define some
- advice like this:
- (defadvice foo (around original-completing-read-only activate)
- (let (ido-enable-replace-completing-read) ad-do-it))")
- ;; ido completion on just about everything
- (defadvice completing-read (around use-ido-when-possible activate)
- (if (or (not ido-enable-replace-completing-read) ;; Manual override disable ido
- (and (boundp 'ido-completing-read) ido-completing-read))
- ad-do-it
- (let ((allcomp (all-completions "" collection predicate))
- (ido-enable-replace-completing-read nil)) ;; prevent recursion
- (if allcomp
- (setq ad-return-value
- (ido-completing-read prompt
- allcomp
- nil require-match initial-input hist def))
- ad-do-it))))
- ;; I can't seem to disable ido unless I actually modify the function
- ;; definition.
- (defun write-file (filename &optional confirm)
- "Write current buffer into file FILENAME.
- This makes the buffer visit that file, and marks it as not modified.
- If you specify just a directory name as FILENAME, that means to use
- the default file name but in that directory. You can also yank
- the default file name into the minibuffer to edit it, using \\<minibuffer-local-map>\\[next-history-element].
- If the buffer is not already visiting a file, the default file name
- for the output file is the buffer name.
- If optional second arg CONFIRM is non-nil, this function
- asks for confirmation before overwriting an existing file.
- Interactively, confirmation is required unless you supply a prefix argument.
- This has been modified to disable ido."
- ;; (interactive "FWrite file: ")
- (interactive
- (let ((read-file-name-function nil)
- (ido-enable-replace-completing-read nil))
- (list (if buffer-file-name
- (read-file-name "Write file: "
- nil nil nil nil)
- (read-file-name "Write file: " default-directory
- (expand-file-name
- (file-name-nondirectory (buffer-name))
- default-directory)
- nil nil))
- (not current-prefix-arg))))
- (or (null filename) (string-equal filename "")
- (progn
- ;; If arg is just a directory,
- ;; use the default file name, but in that directory.
- (if (file-directory-p filename)
- (setq filename (concat (file-name-as-directory filename)
- (file-name-nondirectory
- (or buffer-file-name (buffer-name))))))
- (and confirm
- (file-exists-p filename)
- (or (y-or-n-p (format "File `%s' exists; overwrite? " filename))
- (error "Canceled")))
- (set-visited-file-name filename (not confirm))))
- (set-buffer-modified-p t)
- ;; Make buffer writable if file is writable.
- (and buffer-file-name
- (file-writable-p buffer-file-name)
- (setq buffer-read-only nil))
- (save-buffer)
- ;; It's likely that the VC status at the new location is different from
- ;; the one at the old location.
- (vc-find-file-hook))
- (defun insert-filename-or-buffername ()
- "If the buffer has a file, insert the base name of that file.
- Otherwise insert the buffer name."
- (interactive)
- (let* ((buffer (window-buffer (minibuffer-selected-window)))
- (file-path-maybe (buffer-file-name buffer)))
- (insert (if file-path-maybe
- (file-name-nondirectory file-path-maybe)
- (buffer-name buffer)))))
- (define-key minibuffer-local-map (kbd "C-c f") 'insert-filename-or-buffername)
- (defun smex-update-after-load (unused)
- (when (boundp 'smex-cache)
- (smex-update)))
- ;; ido for M-x
- ;; minibuffer-complete-cycle is also nice, but this is better
- (with-library 'smex
- (add-hook 'after-init-hook 'smex-initialize)
- (add-hook 'after-load-functions 'smex-update-after-load)
- (global-set-key (kbd "M-x") 'smex)
- (global-set-key (kbd "M-X") 'smex-major-mode-commands)
- (global-set-key (kbd "C-c M-x") 'execute-extended-command))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; TAGS
- (with-library 'etags
- (setq ctags-executable "ctags-exuberant")
- (defun create-tags (dir)
- "Create a tags file in directory DIR."
- (interactive "DDirectory: ")
- (shell-command
- (format "%s -f %s/TAGS -e -R %s"
- ctags-executable dir (directory-file-name dir))))
- (with-library 'etags-select
- (global-set-key (kbd "M-?") 'etags-select-find-tag-at-point)
- (global-set-key (kbd "M-.") 'etags-select-find-tag))
- )
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Backup
- (setq make-backup-files t
- vc-make-backup-files t
- version-control t
- kept-new-versions 16
- kept-old-versions 2
- delete-old-versions t
- backup-by-copying t)
- (setq backup-dir (concat user-emacs-directory "backup/"))
- (if (not (file-exists-p backup-dir))
- (make-directory backup-dir))
- (add-to-list 'backup-directory-alist
- `("." . ,backup-dir))
- (defun force-backup-of-buffer ()
- (setq buffer-backed-up nil))
- (add-hook 'before-save-hook 'force-backup-of-buffer)
- ;; this is what tramp uses
- (setq tramp-backup-directory-alist backup-directory-alist)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Autosave
- (setq autosave-dir (concat user-emacs-directory "autosaves/"))
- (if (not (file-exists-p autosave-dir))
- (make-directory autosave-dir))
- (add-to-list 'auto-save-file-name-transforms
- `("\\`/?\\([^/]*/\\)*\\([^/]*\\)\\'" ,(concat autosave-dir "\\2") t))
- ;; tramp autosaves
- (setq tramp-auto-save-directory (concat user-emacs-directory "tramp-autosaves/"))
- (if (not (file-exists-p tramp-auto-save-directory))
- (make-directory tramp-auto-save-directory))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; save-visited-files
- ;; Saves a list of the open files (via auto-save-hook), which can be
- ;; restored with save-visited-files-restore.
- (autoload 'save-visited-files-mode "save-visited-files"
- "Periodically saves a list of open files" t)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; recentf (recently visited files)
- (setq recentf-save-file (concat user-emacs-directory ".recentf"))
- (recentf-mode 1)
- (defun ido-recentf-open ()
- "Use `ido-completing-read' to \\[find-file] a recent file"
- (interactive)
- (if (find-file (ido-completing-read "Find recent file: " recentf-list))
- (message "Opening file...")
- (message "Aborting")))
- (defun undo-kill-buffer (arg)
- "Re-open the last buffer killed. With ARG, re-open the nth buffer."
- (interactive "p")
- (let ((recently-killed-list (copy-sequence recentf-list))
- (buffer-files-list
- (delq nil (mapcar (lambda (buf)
- (when (buffer-file-name buf)
- (expand-file-name (buffer-file-name buf))))
- (buffer-list)))))
- (mapc
- (lambda (buf-file)
- (setq recently-killed-list
- (delq buf-file recently-killed-list)))
- buffer-files-list)
- (find-file
- (if arg (nth arg recently-killed-list)
- (car recently-killed-list)))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Title and Modeline
- ;; frame title
- (setq-default frame-title-format
- '(:eval
- (format "%s@%s: %s %s"
- (or (file-remote-p default-directory 'user)
- user-real-login-name)
- (or (file-remote-p default-directory 'host)
- system-name)
- (buffer-name)
- (cond
- (buffer-file-truename
- (concat "(" buffer-file-truename ")"))
- (dired-directory
- (concat "{" dired-directory "}"))
- (t
- "[no file]")))))
- (global-set-key (kbd "<mode-line> <mouse-2>") 'mouse-delete-window)
- (global-set-key (kbd "<mode-line> <mouse-3>") 'mode-line-next-buffer)
- (require 'modeline-posn nil 'noerror)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; TRAMP
- (defface find-file-root-header-face
- '((t (:foreground "white" :background "red3")))
- "*Face use to display header-lines for files opened as root.")
- (defun find-file-root-header-warning ()
- "*Display a warning in header line of the current buffer.
- This function is suitable to add to `find-file-hook'."
- (when (string-equal
- (file-remote-p (or buffer-file-name default-directory) 'user)
- "root")
- (let* ((warning "WARNING: EDITING FILE AS ROOT!")
- (space (+ 6 (- (window-width) (length warning))))
- (bracket (make-string (/ space 2) ?-))
- (warning (concat bracket warning bracket)))
- (setq header-line-format
- (propertize warning 'face 'find-file-root-header-face)))))
- (defun find-alternative-file-with-sudo ()
- (interactive)
- (let ((bname (expand-file-name (or buffer-file-name
- default-directory)))
- (pt (point)))
- (setq bname (or (file-remote-p bname 'localname)
- (concat "/sudo::" bname)))
- ;; FIXME mostly works around, but not quite
- (flet ((server-buffer-done
- (buffer &optional for-killing)
- nil))
- (find-alternate-file bname))
- (goto-char pt)))
- ;; normally this is bound to find-file-read-only
- ;; use M-x toggle-read-only instead
- (global-set-key (kbd "C-x C-r") 'find-alternative-file-with-sudo)
- (add-hook 'find-file-hook 'find-file-root-header-warning)
- (add-hook 'dired-mode-hook 'find-file-root-header-warning)
- ;; Basically what this does is connect through ssh and then sudo on
- ;; the remote machine (except localhost). You can use
- ;; "/sudo:remote-host:/path/to/file" to open a remote file as root.
- (eval-after-load "tramp"
- '(progn
- (add-to-list 'tramp-default-proxies-alist
- '(nil "\\`root\\'" "/ssh:%h:"))
- (add-to-list 'tramp-default-proxies-alist
- '((regexp-quote (system-name)) nil nil))
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Mouse
- (with-library 'mouse+
- (global-set-key (kbd "<down-mouse-2>") 'mouse-flash-position)
- (global-set-key (kbd "S-<down-mouse-2>") 'mouse-scan-lines))
- ;; move mouse pointer away when the cursor gets near
- (mouse-avoidance-mode 'cat-and-mouse)
- ;; it's really annoying when the frame raises by itself
- (defadvice mouse-avoidance-set-mouse-position (around disable-raise activate)
- (flet ((raise-frame (&optional frame) t))
- ad-do-it))
- (global-set-key (kbd "<mouse-2>") 'mouse-yank-primary)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Windows
- ;; automatically save window configurations and cycle through them
- (with-library 'window-config-history
- (window-config-history-mode 1))
- (defun split-windows-in-quarters (arg)
- "Configure a frame to have 4 similarly sized windows. Splits
- the selected window with prefix arg."
- (interactive "P")
- (when (not arg)
- (delete-other-windows))
- (let ((this-window (selected-window)))
- (split-window-horizontally)
- (other-window 1)
- (split-window-vertically)
- (select-window this-window)
- (split-window-vertically)))
- ;; default bindings are too long, make single keystrokes
- (defun previous-window ()
- (interactive)
- (other-window -1))
- (global-set-key (kbd "M-1") 'previous-window)
- (global-set-key (kbd "C-x O") 'previous-window)
- (global-set-key (kbd "M-2") 'other-window)
- ;; default is the unwieldy C-x 4 C-o
- (global-set-key (kbd "<f6>") 'display-buffer)
- ;; default is C-x <left> and C-x <right>
- (global-set-key (kbd "M-<up>") 'previous-buffer)
- (global-set-key (kbd "M-<down>") 'next-buffer)
- (global-set-key (kbd "C-M-1") 'previous-buffer)
- (global-set-key (kbd "C-M-2") 'next-buffer)
- (dolist (func '(buf-move-up
- buf-move-down
- buf-move-left
- buf-move-right))
- (autoload func "buffer-move.el"
- "Move buffers to different windows." t))
- ;; Save point position per-window instead of per-buffer.
- (with-library 'winpoint
- (winpoint-mode 1))
- ;; I hate it when my windows get deleted.
- (defvar confirm-delete-window nil
- "Ask the user before deleting a window. This is used in
- around-advice for delete-window.")
- (defvar never-delete-window nil
- "Never allow windows to be deleted. This is used in
- around-advice for delete-window.")
- (defadvice delete-window (around confirm activate)
- (if (and (not never-delete-window)
- (if confirm-delete-window
- (y-or-n-p "Delete window? ")
- t))
- ad-do-it
- ;; delete-window raises an error if the window shouldn't be
- ;; deleted
- (error "Not deleting window")))
- (defadvice delete-windows-on (around confirm activate)
- (if (and (not never-delete-window)
- (if confirm-delete-window
- (y-or-n-p "Delete window? ")
- t))
- ad-do-it
- ;; delete-windows-on switches to other-buffer if the window
- ;; shouldn't be deleted
- (switch-to-buffer (other-buffer))))
- ;; prevent these functions from killing the selected window
- (defadvice-list
- '(finder-exit View-quit log-edit-done
- vc-revert vc-rollback)
- 'before 'no-window-delete
- '(lambda ()
- (let ((never-delete-window t))
- 'ad-do-it)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; VC mode
- (defvar hg-graphlog-re "^[\\\\|/o@ +-]*"
- "Matches the junk Mercurial's graphlog extension puts at the
- beginning of the line")
- (defun jpk/vc-hg-log-view-mode-hook ()
- (visual-line-mode 1)
- ;; ignore graphlog stuff
- (setq log-view-message-re
- (replace-regexp-in-string "^\\^" hg-graphlog-re
- log-view-message-re)))
- (add-hook 'vc-hg-log-view-mode-hook 'jpk/vc-hg-log-view-mode-hook)
- (eval-after-load "vc-hg"
- '(progn
- ;; graphlog
- (add-to-list 'vc-hg-log-switches "-G")
- (font-lock-add-keywords
- 'vc-hg-log-view-mode
- `((,(concat hg-graphlog-re "files:[ \t]+\\(.+\\)")
- (1 'change-log-file))
- (,(concat hg-graphlog-re "\\(description:\\)[ \t]+\\(.+\\)")
- (1 'log-view-message)
- (2 'log-view-message))
- (,(concat hg-graphlog-re "user:[ \t]+\\(.+\\)")
- (1 'change-log-name))
- (,(concat hg-graphlog-re "date:[ \t]+\\(.+\\)")
- (1 'change-log-date)))
- 'set)
- ))
- (eval-after-load "vc-dir"
- '(progn
- (defun vc-dir-toggle ()
- (interactive)
- (let (line col)
- (setq line (line-number-at-pos))
- ;; This automatically moves to the next line, but that isn't
- ;; as useful for toggling (I think), so we work around it.
- (vc-dir-mark-unmark 'vc-dir-toggle-mark-file)
- (setq col (current-column))
- (goto-line line)
- (move-to-column col)))
- (define-key vc-dir-mode-map
- (kbd "SPC") 'vc-dir-toggle)
- ;; incoming/outgoing
- (defun vc-hg-outgoing ()
- (interactive)
- (let ((bname "*Hg outgoing*"))
- (vc-hg-command bname nil nil "outgoing" "-n")
- (switch-to-buffer bname)
- (vc-hg-outgoing-mode)))
- (defun vc-hg-incoming ()
- (interactive)
- (let ((bname "*Hg incoming*"))
- (vc-hg-command bname nil nil "incoming" "-n")
- (switch-to-buffer bname)
- (vc-hg-incoming-mode)))
- (global-set-key (kbd "C-x v I") 'vc-hg-incoming)
- (global-set-key (kbd "C-x v O") 'vc-hg-outgoing)
- (add-hook 'vc-hg-log-view-mode-hook (lambda () (toggle-read-only 1)))
- (define-key vc-hg-log-view-mode-map
- (kbd "q") (lambda () (interactive) (kill-buffer (buffer-name))))
- ))
- (setq vc-log-short-style nil)
- ;; annotate (blame) customizations: I don't like the default (the date
- ;; is too verbose and there's no user name).
- (defconst vc-hg-annotate-re
- "^[ \t]*[[:alnum:]]+ \\([0-9]+\\) \\(.\\{10\\}\\)\\(?:\\(: \\)\\|\\(?: +\\(.+\\): \\)\\)")
- (defun vc-hg-annotate-command (file buffer &optional revision)
- "Execute \"hg annotate\" on FILE, inserting the contents in BUFFER.
- Optional arg REVISION is a revision to annotate from."
- (vc-hg-command buffer 0 file "annotate" "-d" "-q" "-u" "-n"
- (when revision (concat "-r" revision))))
- (defun vc-hg-annotate-time ()
- (when (looking-at vc-hg-annotate-re)
- (goto-char (match-end 0))
- (vc-annotate-convert-time
- (date-to-time (concat (match-string-no-properties 2) " 00:00:00")))))
- ;; TODO: submit patch for graphlog stuff
- (defun vc-hg-print-log (files buffer &optional shortlog start-revision limit)
- "Get change log associated with FILES."
- ;; `vc-do-command' creates the buffer, but we need it before running
- ;; the command.
- (vc-setup-buffer buffer)
- ;; If the buffer exists from a previous invocation it might be
- ;; read-only.
- (let ((inhibit-read-only t))
- (with-current-buffer
- buffer
- (apply 'vc-hg-command buffer 0 files "log"
- (append
- (when start-revision (list (format "-r%s" start-revision)))
- (when limit (list "-l" (format "%s" limit)))
- (when shortlog '("--style" "compact"))
- vc-hg-log-switches)))))
- ;; toggle-read-only prints an annoying message
- (defadvice toggle-read-only (around suppress-vc-message activate)
- (with-temp-message ""
- ad-do-it))
- ;; TODO
- ;;
- ;; vc-revert bug
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; diff
- (autoload 'commit-patch-buffer "commit-patch-buffer.el"
- "Use diff-mode buffers as commits for VC." t)
- (defun jpk/diff-mode-hook ()
- (local-set-key (kbd "C-c C-k") 'diff-hunk-kill)
- (local-set-key (kbd "C-c C-S-k") 'diff-file-kill)
- (local-set-key (kbd "C-c C-c") 'commit-patch-buffer)
- (local-set-key (kbd "C-c C-j") 'diff-add-trailing-CR-in-hunk)
- (local-set-key (kbd "C-c C-o") 'diff-goto-source))
- (add-hook 'diff-mode-hook 'jpk/diff-mode-hook)
- ;; don't bother me about previously manipulated hunks
- (defvar ediff-copy-diff-silent t
- "Do not ask if a previously copied hunk should be changed.")
- (defadvice ediff-test-save-region (around always-true activate)
- (if ediff-copy-diff-silent
- (flet ((yes-or-no-p (prompt) t))
- ad-do-it)
- ad-do-it))
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ;; commit-patch-buffer is very picky about the patch buffer.
- ;; Apparently, it needs the line endings to match the original file,
- ;; but the diff metadata needs unix line endings.
- ;;
- ;; TODO
- ;;
- ;; make diff-add-trailing-CR-in-hunk more fool-proof and use it to
- ;; operate on the whole diff buffer
- (defun insert-CR-eol (b e)
- (interactive "r")
- (replace-regexp "\\([^
- ]\\)$" "\\1
- " nil b e))
- (defun diff-add-trailing-CR-in-hunk ()
- "Add trailing carriage returns in the current hunk."
- (interactive)
- (save-excursion
- (diff-beginning-of-hunk)
- (when (diff-unified-hunk-p)
- (forward-line 1))
- (let* ((start (point))
- ;; Search the second match, since we're looking at the first.
- (nexthunk (when (re-search-forward diff-hunk-header-re nil t 2)
- (match-beginning 0)))
- (firsthunk (ignore-errors
- (goto-char start)
- (diff-beginning-of-file) (diff-hunk-next) (point)))
- (nextfile (ignore-errors (diff-file-next) (point)))
- (inhibit-read-only t))
- (goto-char start)
- (diff-end-of-hunk)
- (when (eobp)
- (forward-line -1)
- (end-of-line))
- (insert-CR-eol start (point)))))
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Skip over whitespace-only differences in ediff mode. Still finds
- ;; such regions, only changes navigation. Toggle with # # in ediff
- ;; mode.
- (setq-default ediff-ignore-similar-regions t)
- (defun ediff-regions-linewise-this-buffer ()
- (interactive)
- (ediff-regions-linewise (buffer-name) (buffer-name)))
- (defun ediff-regions-wordwise-this-buffer ()
- (interactive)
- (ediff-regions-wordwise (buffer-name) (buffer-name)))
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ;; binary diff with hexl-mode
- ;; http://trey-jackson.blogspot.com/2010/10/emacs-tip-38-automatically-diff-binary.html
- (defvar ediff-do-hexl-diff nil
- "variable used to store trigger for doing diff in hexl-mode")
- (defadvice ediff-files-internal (around ediff-files-internal-for-binary-files activate)
- "catch the condition when the binary files differ
- the reason for catching the error out here (when re-thrown from the inner advice)
- is to let the stack continue to unwind before we start the new diff
- otherwise some code in the middle of the stack expects some output that
- isn't there and triggers an error"
- (let ((file-A (ad-get-arg 0))
- (file-B (ad-get-arg 1))
- ediff-do-hexl-diff)
- (condition-case err
- (progn
- ad-do-it)
- (error
- (if ediff-do-hexl-diff
- (let ((buf-A (find-file-noselect file-A))
- (buf-B (find-file-noselect file-B)))
- (with-current-buffer buf-A
- (hexl-mode 1))
- (with-current-buffer buf-B
- (hexl-mode 1))
- (ediff-buffers buf-A buf-B))
- (error (error-message-string err)))))))
- (defadvice ediff-setup-diff-regions (around ediff-setup-diff-regions-for-binary-files activate)
- "when binary files differ, set the variable "
- (condition-case err
- (progn
- ad-do-it)
- (error
- (setq ediff-do-hexl-diff
- (and (string-match-p "^Errors in diff output. Diff output is in.*"
- (error-message-string err))
- (string-match-p "^\\(Binary \\)?[fF]iles .* and .* differ"
- (buffer-substring-no-properties
- (line-beginning-position)
- (line-end-position)))
- (y-or-n-p "The binary files differ, look at the differences in hexl-mode? ")))
- (error (error-message-string err)))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Comint - command interpreter
- (defvar comint-eob-on-send t
- "Like comint-eol-on-send, but moves to the end of buffer.")
- (defadvice comint-send-input
- (before move-to-end-of-buffer activate)
- (when comint-eob-on-send
- (goto-char (point-max))))
- ;; used for interactive terminals
- (eval-after-load "comint"
- '(progn
- (define-key comint-mode-map
- (kbd "<up>") 'comint-previous-matching-input-from-input)
- (define-key comint-mode-map
- (kbd "<down>") 'comint-next-matching-input-from-input)
- ))
- (autoload 'ansi-color-for-comint-mode-on "ansi-color")
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Terminals
- ;; multi-term is much better than shell, eshell, term, or ansi-term
- (dolist
- (func '(multi-term
- multi-term-prev
- multi-term-shell))
- (autoload func "multi-term.el"
- "Package for creating and managing multiple terminal buffers" t))
- (defun multi-term-shell (shell)
- "Programmatically start a terminal with a non-default program."
- (let ((multi-term-program shell))
- (multi-term)))
- (eval-after-load "multi-term"
- '(progn
- (defun term-send-quote ()
- (interactive)
- (term-send-raw-string "\C-v"))
- (defun term-send-M-x ()
- (interactive)
- (term-send-raw-string "\ex"))
- ;; These use strings like "\e0A" by default, and it's
- ;; questionable which is better. IPython likes the '[' versions
- ;; better, but most other things like the '0' version.
- ;; (defun term-send-up () (interactive) (term-send-raw-string "\e[A"))
- ;; (defun term-send-down () (interactive) (term-send-raw-string "\e[B"))
- ;; (defun term-send-right () (interactive) (term-send-raw-string "\e[C"))
- ;; (defun term-send-left () (interactive) (term-send-raw-string "\e[D"))
- (defun term-send-backward-kill-word ()
- (interactive)
- (term-send-raw-string "\C-H"))
- (dolist
- (bind '(("C-<right>" . term-send-forward-word)
- ("C-<left>" . term-send-backward-word)
- ("C-<backspace>" . term-send-backward-kill-word)
- ("C-<delete>" . term-send-forward-kill-word)
- ("C-k" . term-send-raw)
- ("C-y" . term-send-raw)
- ("C-c C-z" . term-stop-subjob)
- ("C-z" . term-stop-subjob)
- ;; work like urxvt tabbed
- ("<S-down>" . multi-term)
- ("<S-left>" . multi-term-prev)
- ("<S-right>" . multi-term-next)
- ("C-v" . term-paste)
- ))
- (add-to-list 'term-bind-key-alist bind))
- ))
- (defun jpk/term-mode-hook ()
- (setq cua--ena-cua-keys-keymap nil)
- ;; use a different face if possible
- (when (fboundp 'buffer-face-set)
- (defvar fixed-pitch-face 'fixed-pitch)
- (buffer-face-set fixed-pitch-face)))
- (add-hook 'term-mode-hook 'jpk/term-mode-hook)
- (global-set-key (kbd "C-c t") 'multi-term-prev)
- ;; see also C-u M-|
- (defun insert-from-shell-current-line ()
- "Run the current line as a shell command, and put the output
- immediately after it. If the region is active, use for the
- command."
- (interactive "*")
- (let ((beg (if (region-active-p)
- (region-beginning)
- (line-beginning-position)))
- (end (if (region-active-p)
- (region-end)
- (line-end-position))))
- (save-excursion
- (goto-char end)
- (insert "\n")
- (insert (shell-command-to-string
- (buffer-substring beg end))))))
- (global-set-key (kbd "C-<kp-enter>") 'insert-from-shell-current-line)
- (global-set-key (kbd "C-!") 'insert-from-shell-current-line)
- ;; TODO make this a emacs function
- ;; copy the terminfo files for eterm-color to a remote host
- ;; ssh remote mkdir -p .terminfo/e/
- ;; scp (concat data-directory "e/eterm-color") (concat data-directory "e/eterm-color.ti") remote:.terminfo/e/
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; file functions
- ;; move-buffer-file, copy-buffer-file-name-as-kill,
- ;; rename-file-and-buffer, and other useful commands.
- (require 'buffer-extension nil 'noerror)
- (defalias 'delete-this-buffer-and-file 'kill-this-buffer-and-file
- "I always think that this should be called 'delete'. It's not
- getting saved to the kill-ring...")
- (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
- ;; set-fill-column is dumb
- (global-set-key (kbd "C-x f") 'find-file-at-point)
- (defun get-file-name-in-path (dirs suffixes)
- "Use completing-read to select a file DIRS is a list of strings
- that are directory names (like `load-path'). SUFFIXES is a
- list of strings that the files must end with, e.g. '(\".h\"
- \".hpp\")."
- (let ((def (thing-at-point 'symbol)))
- (when def
- (setq def (and (locate-file-completion-table
- dirs suffixes def nil 'lambda)
- def)))
- (completing-read (if def (format "File name (default %s): " def)
- "File name: ")
- (apply-partially 'locate-file-completion-table
- dirs suffixes)
- (if suffixes
- (lambda (x) (string-match (concat (regexp-opt suffixes t) "$") x)))
- nil nil nil def)))
- (defun find-file-in-path (dirs suffixes)
- "Find a file with a certain extension in a list of directories.
- See `get-file-name-in-path' for more info."
- (let* ((library (get-file-name-in-path dirs suffixes))
- (buf (find-file-noselect (locate-file library dirs))))
- (condition-case nil (switch-to-buffer buf) (error (pop-to-buffer buf)))))
- (defun find-user-init-file ()
- "Finds ~/.emacs, or equivalent"
- (interactive)
- (find-file user-init-file))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Dired
- (eval-after-load "dired"
- '(progn
- (with-library 'dired-isearch
- (define-key dired-mode-map (kbd "C-s") 'dired-isearch-forward)
- (define-key dired-mode-map (kbd "C-r") 'dired-isearch-backward)
- (define-key dired-mode-map (kbd "C-M-s") 'dired-isearch-forward-regexp)
- (define-key dired-mode-map (kbd "C-M-r") 'dired-isearch-backward-regexp))
- (with-library 'dired+
- (toggle-dired-find-file-reuse-dir 1)
- (define-key dired-mode-map (kbd "<mouse-1>")
- 'diredp-mouse-mark/unmark)
- (define-key dired-mode-map (kbd "C-<down-mouse-1>") 'ignore)
- (define-key dired-mode-map (kbd "C-<mouse-1>")
- 'diredp-mouse-mark-region-files)
- (define-key dired-mode-map (kbd "<mouse-2>")
- 'diredp-mouse-find-file-reuse-dir-buffer))
- (with-library 'dired-x
- (define-key dired-mode-map (kbd "C-c C-o") 'dired-omit-mode)
- (add-hook 'dired-mode-hook 'dired-omit-mode))
- (define-key dired-mode-map (kbd "S-<return>")
- 'dired-find-file-other-window)
- (define-key dired-mode-map (kbd "S-<down-mouse-2>")
- 'dired-mouse-find-file-other-window)
- (setq dired-deletion-confirmer 'y-or-n-p)
- (define-key dired-mode-map (kbd "e") 'wdired-change-to-wdired-mode)
- (require 'wuxch-dired-copy-paste nil 'noerror)
- ))
- ;; word wrap looks terrible in dired buffers
- (add-hook 'dired-before-readin-hook (lambda () (setq word-wrap nil
- truncate-lines t)))
- (setq dired-image-viewer "geeqie"
- dired-pdf-viewer "okular"
- dired-media-player "vlc"
- dired-office-suite "ooffice")
- (setq dired-guess-shell-alist-user
- '(("\\.mpe?g$\\|\\.avi$" dired-media-player)
- ("\\.wmv$" dired-media-player)
- ("\\.mp4" dired-media-player)
- ("\\.ogg$" dired-media-player)
- ("\\.mp3$" dired-media-player)
- ("\\.wav$" dired-media-player)
- ("\\.xbm$" dired-image-viewer)
- ("\\.p[bgpn]m$" dired-image-viewer)
- ("\\.gif$" dired-image-viewer)
- ("\\.tif$" dired-image-viewer)
- ("\\.png$" dired-image-viewer)
- ("\\.jpe?g$" dired-image-viewer)
- ("\\.pdf$" dired-pdf-viewer)
- ("\\.doc$" dired-office-suite)
- ("\\.xls$" dired-office-suite)
- ("\\.ppt$" dired-office-suite)
- ("\\.od[tsgp]$" dired-office-suite)
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; IBuffer
- (eval-after-load "ibuffer"
- '(progn
- (define-ibuffer-sorter pathname
- "Sort by pathname"
- (:description "path")
- (flet ((get-pathname
- (data)
- (with-current-buffer (car data)
- (or buffer-file-name
- (if (eq major-mode 'dired-mode)
- (expand-file-name dired-directory))
- ;; so that all non pathnames are at the end
- "~"))))
- (string-lessp (get-pathname a) (get-pathname b))))
- (define-key ibuffer-mode-map (kbd "s p")
- 'ibuffer-do-sort-by-pathname)
- (define-ibuffer-sorter major-then-pathname
- "Sort the buffers by their major-mode, then by pathname if
- major modes are equal."
- (:description "major-then-path")
- (flet ((get-major
- (data)
- (downcase
- (symbol-name (with-current-buffer
- (car data)
- major-mode))))
- (get-pathname
- (data)
- (with-current-buffer (car data)
- (or buffer-file-name
- (if (eq major-mode 'dired-mode)
- (expand-file-name dired-directory))
- ;; so that all non pathnames are at the end
- "~"))))
- (if (string-equal (get-major a) (get-major b))
- (string-lessp (get-pathname a) (get-pathname b))
- (string-lessp (get-major a) (get-major b)))))
- (define-key ibuffer-mode-map (kbd "s M")
- 'ibuffer-do-sort-by-major-then-pathname)
- (define-key ibuffer-mode-map
- (kbd "/ M") 'ibuffer-set-filter-groups-by-mode)
- (define-key ibuffer-mode-map
- (kbd "C-<down>") 'ibuffer-forward-filter-group)
- (define-key ibuffer-mode-map
- (kbd "C-<up>") 'ibuffer-backward-filter-group)
- (define-key ibuffer-mode-map
- (kbd "<up>")
- (lambda (arg) (interactive "P") (ibuffer-backward-line arg t)))
- (define-key ibuffer-mode-map
- (kbd "<down>")
- (lambda (arg) (interactive "P") (ibuffer-forward-line arg t)))
- (defun ibuffer-mark-toggle (arg)
- (interactive "P")
- (ibuffer-forward-line 0)
- (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
- ;; on a group name
- (ibuffer-toggle-marks) ;; buggy, but not my fault
- ;; on a buffer name
- (if (eq (ibuffer-current-mark) ibuffer-marked-char)
- (ibuffer-mark-interactive arg ?\s 0)
- (ibuffer-mark-interactive arg ibuffer-marked-char 0))))
- (define-key ibuffer-mode-map
- (kbd "SPC") 'ibuffer-mark-toggle)
- ))
- ;; run when ibuffer buffer is created
- (defun jpk/ibuffer-mode-hook ()
- (ibuffer-auto-mode 1)
- (setq truncate-lines t))
- (add-hook 'ibffer-mode-hook 'jpk/ibuffer-mode-hook)
- ;; run when ibuffer command is invoked
- (defun jpk/ibuffer-hook ()
- (ibuffer-set-filter-groups-by-mode)
- (setq ibuffer-sorting-mode 'pathname))
- (add-hook 'ibuffer-hook 'jpk/ibuffer-hook)
- ;; jump to most recent buffer
- (defadvice ibuffer (around ibuffer-point-to-most-recenct activate)
- (let ((recent-buffer-name (buffer-name)))
- ad-do-it
- (unless (string-match-p "*Ibuffer*" recent-buffer-name)
- (ibuffer-jump-to-buffer recent-buffer-name))))
- (global-set-key (kbd "C-x C-b") 'ibuffer)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; *scratch*
- ;; if *scratch* is killed, recreate it
- (defun make-scratch-buffer ()
- (interactive)
- (save-excursion
- (set-buffer (get-buffer-create "*scratch*"))
- (lisp-interaction-mode)
- (message "") ;; remove message from above command
- ))
- (defun scratch-respawns-when-killed ()
- (interactive)
- (if (not (string= (buffer-name (current-buffer)) "*scratch*"))
- t ;; return t so the caller may kill it
- (let ((kill-buffer-query-functions kill-buffer-query-functions))
- (remove-hook 'kill-buffer-query-functions 'scratch-respawns-when-killed)
- (set-buffer (get-buffer-create "*scratch*"))
- (kill-buffer (current-buffer)))
- (make-scratch-buffer)
- nil)) ;; return nil so the caller doesn't try to kill it
- (add-hook 'kill-buffer-query-functions 'scratch-respawns-when-killed)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; figlet
- (dolist
- (func '(figlet
- figlet-comment
- figlet-figletify-region
- figlet-figletify-region-comment))
- (autoload func "figlet.el"
- "Figlet interface for Emacs." t))
- (eval-after-load "figlet.el"
- '(progn
- (add-to-list 'figlet-options "-k"))) ;; kerning
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Hi Lock
- ;; Hi Lock provides on-demand keyword highlighting. It uses
- ;; font-lock-mode to do the work. Unfortunately, this is overridden
- ;; by hl-line mode, so it looks bad when the point is on the line that
- ;; has hi locked words. This forces it to use overlays too, which is
- ;; a performance hit, but it works with hl-line.
- (defadvice hi-lock-set-pattern (around use-overlays activate)
- (let ((font-lock-fontified nil))
- ad-do-it))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Pretty mode
- ;; https://github.com/mattharrison/pretty-mode.git
- ;; interesting, although it kind of messes up indenting
- (autoload 'pretty-mode "pretty-mode.el"
- "Display certain keywords as pretty unicode glyphs" t)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; compile
- (defun kill-compile-buffer-if-successful (buffer string)
- " kill a compilation buffer if succeeded without warnings "
- (if (and
- (string-match "compilation" (buffer-name buffer))
- (string-match "finished" string)
- (not
- (with-current-buffer buffer
- (search-forward "warning" nil t))))
- (run-with-timer 1 nil
- 'kill-buffer
- buffer)))
- (add-hook 'compilation-finish-functions 'kill-compile-buffer-if-successful)
- (global-set-key (kbd "C-c b") 'compile)
- (global-set-key (kbd "C-x ~") 'previous-error)
- (defun doxygen-compile ()
- (interactive)
- (compile "doxygen 2>&1 1>/dev/null | sed s%`pwd`/%%"))
- (global-set-key (kbd "C-c B") 'doxygen-compile)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; fixme-mode
- (with-library 'fixme-mode
- (setq fixme-highlighted-words '("FIXME" "TODO" "BUG" "XXX" "DEBUG"))
- (dolist (m '(matlab-mode verilog-mode lisp-interaction-mode lisp-mode))
- (add-to-list 'fixme-modes m))
- (fixme-mode 1))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Generic Programming
- (defun insert-comment-bar (arg &optional len)
- (interactive "*P")
- (let ((num (or arg 72))
- (to-insert ""))
- (cond
- ((memq major-mode '(c-mode cc-mode c++-mode java-mode))
- (setq to-insert (concat "/*"
- (make-string (- num 4) ?*)
- "*/")))
- ((memq major-mode '(emacs-lisp-mode lisp-mode lisp-interaction-mode))
- (setq to-insert (make-string num ?\;)))
- ((memq major-mode '(latex-mode))
- (setq to-insert (make-string num ?%)))
- (t
- (setq to-insert (make-string num ?#))))
- (beginning-of-line)
- (if (looking-at "^[[:space:]]*$")
- (end-of-line)
- (setq to-insert (concat to-insert "\n")))
- (insert to-insert)))
- ;; extra syntax highlighting
- (defface font-lock-bracket-face
- '((t (:foreground "cyan3")))
- "Font lock mode face for brackets, e.g. '(', ']', etc."
- :group 'font-lock-faces)
- (defvar font-lock-bracket-face 'font-lock-bracket-face
- "Font lock mode face for backets. Changing this directly
- affects only new buffers.")
- (defvar operators-regexp
- (regexp-opt '("+" "-" "*" "/" "%" "!"
- "&" "^" "~" "|"
- "=" "<" ">"
- "." "," ";" ":" "?"))
- "Regexp matching symbols that are operators in most programming
- languages.")
- (setq operators-font-lock-spec
- (cons operators-regexp
- (list
- 0 ;; use whole match
- 'font-lock-builtin-face
- 'keep ;; OVERRIDE
- )))
- (defvar brackets-regexp
- (regexp-opt '("(" ")" "[" "]" "{" "}"))
- "Regexp matching symbols that are grouping operators in most
- programming languages.")
- (setq brackets-font-lock-spec
- (cons brackets-regexp
- (list
- 0 ;; use whole match
- 'font-lock-bracket-face
- 'keep ;; OVERRIDE
- )))
- (defun jpk/programming-mode-hook ()
- ;;(smart-tab-mode 0) ;; default to using spaces
- ;; for doxygen
- (with-library 'doxymacs
- (doxymacs-mode 1)
- (doxymacs-font-lock))
- (with-library 'filladapt
- (filladapt-mode 1))
- ;; check spelling on the fly, but only in comments and strings
- (with-library 'flyspell
- (flyspell-mode 0)
- (flyspell-prog-mode))
- ;; e.g. insert '(' and ')' around the region if it is active and '('
- ;; is typed; works for other delimiters too
- (with-library 'wrap-region
- (wrap-region-mode 1))
- ;; highlight nested parens
- (with-library 'highlight-parentheses
- (highlight-parentheses-mode 1))
- (local-set-key (kbd "C-M-;") 'insert-comment-bar)
- (with-library 'pretty-mode
- (pretty-mode 1))
- (add-hook 'after-save-hook 'imenu-force-rescan 'append 'local)
- )
- (defun imenu-force-rescan ()
- "Doesn't rescan, but forces a rescan the next time imenu is invoked."
- (interactive)
- (save-excursion
- (imenu--cleanup)
- (setq imenu--index-alist nil)))
- (eval-after-load "doxymacs"
- '(progn
- (load "doxymacs-hacks.el")
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; C programming language
- (defun cpp-highlight-if-0/1 ()
- "Modify the face of things in between #if 0 ... #endif."
- (interactive)
- (setq cpp-known-face '(background-color . "dim gray"))
- (setq cpp-unknown-face 'default)
- (setq cpp-face-type 'dark)
- (setq cpp-known-writable 't)
- (setq cpp-unknown-writable 't)
- (setq cpp-edit-list
- '((#("1" 0 1
- (fontified nil))
- nil
- (background-color . "dim gray")
- both nil)
- (#("0" 0 1
- (fontified nil))
- (background-color . "dim gray")
- nil
- both nil)))
- (cpp-highlight-buffer t))
- (setq c-types-regexp
- (concat
- "\\<[_a-zA-Z][_a-zA-Z0-9]*_t\\>" "\\|"
- (regexp-opt '("unsigned" "int" "char" "float" "void") 'words)))
- (eval-after-load "cc-mode"
- '(progn
- (font-lock-add-keywords
- 'c-mode
- (list
- operators-font-lock-spec
- brackets-font-lock-spec
- (cons c-types-regexp 'font-lock-type-face)))
- (font-lock-add-keywords
- 'c++-mode
- (list
- operators-font-lock-spec
- brackets-font-lock-spec
- (cons c-types-regexp 'font-lock-type-face)))
- ;; TODO find a better way to do this
- (with-library 'ffap
- (add-to-list 'ffap-c-path "/usr/lib/avr/include/"))
- ))
- (defun setup-simple-compile ()
- "Sets compile-command to something like `gcc -o foo foo.c' if
- there is no Makefile in the directory"
- (interactive)
- (when (and buffer-file-name (file-name-nondirectory buffer-file-name))
- (unless (file-exists-p "Makefile")
- (set (make-local-variable 'compile-command)
- (let* ((file (file-name-nondirectory buffer-file-name))
- (compiler (if (string-equal "c" (file-name-extension file))
- "gcc" "g++")))
- (format "%s -o %s %s %s %s" ;; "%s -c -o %s.o %s %s %s"
- (or (getenv "CC") compiler)
- (file-name-sans-extension file)
- (or (getenv "CPPFLAGS") "-DDEBUG=9")
- (or (getenv "CFLAGS") (if (string= compiler "gcc")
- "-ansi -Wall -g3 -std=c99"
- "-ansi -Wall -g3"))
- file))))))
- (defun jpk/c-mode-hook ()
- (smart-tab-mode 1)
- (setq tab-width 4)
- (setup-simple-compile)
- (imenu-add-to-menubar "IMenu")
- ;;(cpp-highlight-if-0/1)
- ;;(add-hook 'after-save-hook 'cpp-highlight-if-0/1 'append 'local)
- )
- (add-hook 'c-mode-common-hook 'jpk/programming-mode-hook)
- (add-hook 'c-mode-common-hook 'jpk/c-mode-hook)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; C#
- (autoload 'csharp-mode "csharp-mode.el"
- "Major mode for editing C# source. Derives from c-mode." t)
- (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Perl
- (eval-after-load "cperl-mode"
- '(progn
- (font-lock-add-keywords
- 'cperl-mode
- (list
- operators-font-lock-spec
- brackets-font-lock-spec))
- ))
- (add-hook 'cperl-mode-hook 'jpk/programming-mode-hook)
- (add-hook 'cperl-mode-hook
- (lambda ()
- (cperl-set-style "BSD")
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; PHP
- (autoload 'php-mode "php-mode.el"
- "Major mode for editing PHP source." t)
- (add-to-list 'auto-mode-alist '("\\.php\\'" . php-mode))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Python
- (eval-after-load "python"
- '(progn
- ;; syntax highlighting of operators
- (font-lock-add-keywords
- 'python-mode
- (list
- operators-font-lock-spec
- brackets-font-lock-spec))
- ))
- (defun python-send-region-or-line (beg en)
- "Like `python-send-region', but automatically send the current
- line if region is not active."
- (interactive "r")
- (if (use-region-p)
- (python-send-region beg en)
- (python-send-region (line-beginning-position)
- (line-end-position))))
- (defun jpk/python-mode-hook ()
- (when (condition-case nil
- (load-library "pylint")
- (error nil))
- (local-set-key (kbd "C-c C-w") 'pylint)
- (local-set-key (kbd "C-c C-v") 'pylint))
- (local-set-key (kbd "S-<return>") 'python-send-region-or-line)
- (when (condition-case nil
- (imenu-add-to-menubar "Imenu")
- (error nil))))
- (add-hook 'python-mode-hook 'jpk/programming-mode-hook)
- (add-hook 'python-mode-hook 'jpk/python-mode-hook)
- ;; a better debugger
- (add-to-list 'load-path "/usr/share/emacs/site-lisp/pydb")
- (autoload 'pydb "pydb.el"
- "Python debugger" t)
- ;; get pylint into the python.el menu
- (defvaralias 'py-mode-map 'python-mode-map)
- (defun python-path ()
- "Returns a list of strings containing all the directories in Python's path."
- (split-string (shell-command-to-string
- "python -c 'import sys; print \"+++\".join(sys.path)'")
- "+++"))
- (defun find-python-library ()
- (interactive)
- (find-file-in-path (python-path) '(".py")))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Octave/Matlab
- (add-to-list 'auto-mode-alist
- '("\\.m\\'" . matlab-mode))
- ;; transpose (') is still unhighlighted
- ;; any syntax highlighting must take into account strings
- ;; it seems like any operators, etc. inside a string fucks it all up
- ;; (setq matlab-operators-regexp
- ;; (regexp-opt '("+" "-" "*" "/" "!"
- ;; "&" "^" "~" "|"
- ;; "=" "<" ">"
- ;; "." "," ";" ":" "?")))
- (eval-after-load "matlab"
- '(progn
- (font-lock-add-keywords
- 'matlab-mode
- (list
- ;;(cons matlab-brackets-regexp 'font-lock-bracket-face)
- ;;brackets-font-lock-spec
- ))
- ))
- (defun jpk/matlab-hook ()
- (interactive)
- (define-key matlab-mode-map (kbd "M-;") 'comment-dwim)
- ;; not that simple
- ;; (modify-syntax-entry ?\" "\"" matlab-mode-syntax-table)
- ;; block style comments "%{ ... %}", "#{ ... #}"
- ;; (modify-syntax-entry ?\# ". 13" matlab-mode-syntax-table)
- ;; (modify-syntax-entry ?\% ". 13" matlab-mode-syntax-table)
- ;; (modify-syntax-entry ?\{ ". 2" matlab-mode-syntax-table)
- ;; (modify-syntax-entry ?\} ". 4" matlab-mode-syntax-table)
- ;; (modify-syntax-entry ?\n " " matlab-mode-syntax-table)
- ;; single-line comments "% ...", "# ..."
- ;; (add-to-list 'octave-font-lock-keywords '("[%#].*$" . 'font-lock-comment-face))
- )
- (add-hook 'matlab-mode-hook 'jpk/programming-mode-hook)
- (add-hook 'matlab-mode-hook 'jpk/matlab-hook)
- ;; hack for octave mode "end" keyword
- ;; (eval-after-load "octave-mod"
- ;; (progn
- ;; (add-to-list 'octave-end-keywords "end[[:space:]]*\\([%#].*\\|$\\)")
- ;; (setq octave-block-end-regexp
- ;; (concat "\\<\\("
- ;; (mapconcat 'identity octave-end-keywords "\\|")
- ;; "\\)\\>"))
- ;; ))
- (defun octave-send-buffer ()
- (interactive)
- (octave-send-region (point-min) (point-max)))
- (defun jpk/octave-mode-hook ()
- (interactive)
- (local-set-key (kbd "C-c C-s") 'octave-send-buffer)
- (local-set-key (kbd "C-c C-l") 'octave-send-line)
- (local-set-key (kbd "C-c C-r") 'octave-send-region))
- (add-hook 'octave-mode-hook 'jpk/octave-mode-hook)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Verilog
- (setq verilog-bitspec-regexp "\\<[0-9]+'[bdh]")
- (eval-after-load "verilog-mode"
- '(progn
- (font-lock-add-keywords
- 'verilog-mode
- (list
- operators-font-lock-spec
- brackets-font-lock-spec
- (cons verilog-bitspec-regexp 'font-lock-type-face)))
- ))
- (add-to-list 'auto-mode-alist
- '("\\.vams\\'" . verilog-mode))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Lisp
- (defun lisp-set-up-extra-font-lock (mode)
- (font-lock-add-keywords
- mode
- (list
- brackets-font-lock-spec)))
- (defun jpk/lisp-modes-hook ()
- (eldoc-mode 1)
- (local-set-key (kbd "C-M-S-x") 'eval-region))
- (eval-after-load "lisp-mode"
- '(progn
- (dolist (mode '(lisp-mode
- emacs-lisp-mode
- lisp-interaction-mode))
- (lisp-set-up-extra-font-lock mode))
- (dolist (hook '(lisp-mode-hook
- emacs-lisp-mode-hook
- lisp-interaction-mode-hook))
- (add-hook hook 'jpk/programming-mode-hook)
- (add-hook hook 'jpk/lisp-modes-hook))
- ))
- (defun jpk/ielm-mode-hook ()
- (with-library 'auto-complete
- (setq ac-sources '(ac-source-functions
- ac-source-variables
- ac-source-features
- ac-source-symbols
- ac-source-words-in-same-mode-buffers))
- (add-to-list 'ac-modes 'inferior-emacs-lisp-mode)
- (auto-complete-mode 1)))
- (add-hook 'ielm-mode-hook 'jpk/ielm-mode-hook)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Lua
- (autoload 'lua-mode "lua-mode.el"
- "Major mode for editing Lua source code." t)
- (add-to-list 'auto-mode-alist
- '("\\.lua\\'" . lua-mode))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Scheme
- ;; geiser is a nice REPL and other interaction to a scheme interpreter
- (add-to-list 'load-path (concat user-emacs-directory "geiser/elisp"))
- (require 'geiser nil 'noerror) ;; this is just autoloads
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; FVWM
- (autoload 'fvwm-mode "fvwm-mode.el"
- "Major mode for Fvwm config files." t)
- ;; fvwm config file major mode
- (eval-after-load "fvwm-mode"
- '(progn
- (setq fvwm-fvwmcommand-path "FvwmCommand")
- ;; this may be slow
- (setq fvwm-preload-completions nil)))
- (defun jpk/fvwm-mode-hook ()
- ;;(fvwm-enable-indentation)
- (local-set-key (kbd "RET") 'newline)
- (setq indent-line-function 'indent-relative-dwim)
- (setq tab-width 4))
- (add-hook 'fvwm-mode-hook 'jpk/fvwm-mode-hook)
- ;; fvwm major mode
- (add-to-list 'auto-mode-alist
- '("\\`FvwmApplet-" . fvwm-mode))
- (add-to-list 'auto-mode-alist
- '("\\`FvwmScript-" . fvwm-mode))
- (add-to-list 'auto-mode-alist
- '("\\.fvwm\\'" . fvwm-mode))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; HTML/XML
- (fset 'xml-mode 'nxml-mode)
- (fset 'html-mode 'nxml-mode)
- (fset 'sgml-mode 'nxml-mode)
- ;; Not really HTML editing related, but this will make an HTML file of
- ;; the buffer, with all the syntax highlighting.
- (with-library 'htmlize-view
- (htmlize-view-add-to-files-menu))
- ;; fix a bug in htmlize from emacs-goodies-el
- (eval-after-load "htmlize"
- '(progn
- (defun htmlize-face-size (face)
- ;; The size (height) of FACE, taking inheritance into account.
- ;; Only works in Emacs 21 and later.
- (let ((size-list
- (loop
- for f = face then (face-attribute f :inherit)
- until (or (not f) (eq f 'unspecified))
- for h = (face-attribute f :height)
- collect (if (eq h 'unspecified) nil h))))
- (reduce 'htmlize-merge-size (cons nil size-list))))
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; config files
- (defun jpk/conf-mode-hook ()
- (local-set-key (kbd "C-m") 'newline))
- (add-hook 'conf-mode-hook 'jpk/conf-mode-hook)
- (dolist (re '("\\.list\\'" ;; apt sources files
- "\\.hgrc" "\\.hgignore" ;; mercurial files
- "Doxyfile" ;; Doxygen
- ))
- (add-to-list 'auto-mode-alist `(,re . conf-mode)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; MEDIAWIKI MODE
- (autoload 'wikipedia-mode "wikipedia-mode.el"
- "Major mode for editing documents in Wikipedia markup." t)
- (add-to-list 'auto-mode-alist
- '("\\.wiki\\'" . wikipedia-mode))
- (defun jpk/wikipedia-mode-hook ()
- (local-unset-key (kbd "C-<right>"))
- (local-unset-key (kbd "C-<left>"))
- (local-unset-key (kbd "C-<up>"))
- (local-unset-key (kbd "C-<down>")))
- (add-hook 'wikipedia-mode-hook 'jpk/wikipedia-mode-hook)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; text-mode
- (defun jpk/text-mode-hook ()
- (setq indent-line-function 'indent-relative-dwim)
- (with-library 'flyspell
- (flyspell-mode 1))
- )
- (add-hook 'text-mode-hook 'jpk/text-mode-hook)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; LaTeX (AUCTeX mode)
- (defun jpk/LaTeX-mode-hook ()
- (visual-line-mode 1)
- (with-library 'flyspell
- (flyspell-mode 1))
- (setq fill-column 80)
- (local-set-key (kbd "C-M-;") 'insert-comment-bar))
- (add-hook 'LaTeX-mode-hook 'jpk/LaTeX-mode-hook)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; LINE NUMBERS
- ;; toggle line numbering
- (autoload 'linum-mode "linum.el"
- "Display line numbers in the left margin." t)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; UNDO/REDO
- ;; treat edit history like the tree it is
- (with-library 'undo-tree
- (global-undo-tree-mode 1)
- (global-set-key (kbd "C-z") 'undo-tree-undo)
- (global-set-key (kbd "C-S-z") 'undo-tree-redo))
- ;; C-x u starts the undo-tree visualizer
- (defvar undo-tree-visualize-window-state nil
- "Stores the window state before undo-tree-visualize is called,
- so that it can be restored by undo-tree-visualizer-quit")
- (defadvice undo-tree-visualize
- (before restore-window-layout activate)
- (setq undo-tree-visualize-window-state (current-window-configuration)))
- (defadvice undo-tree-visualizer-quit
- (after restore-window-layout activate)
- (when undo-tree-visualize-window-state
- (set-window-configuration undo-tree-visualize-window-state)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; isearch
- (defun recenter-no-redraw (&optional arg)
- (interactive "P")
- (let ((recenter-redisplay nil))
- (recenter arg)))
- ;; minor improvements to isearch
- (require 'isearch+ nil 'noerror)
- ;; Allow page up/down, C-l, and anything else that doesn't move the
- ;; point during isearch.
- (setq isearch-allow-scroll t)
- (put 'recenter-top-bottom 'isearch-scroll t)
- (put 'force-scroll-left-8 'isearch-scroll t)
- (put 'force-scroll-right-8 'isearch-scroll t)
- ;; make C-y and C-v do what you expect in ISearch mode
- (define-key isearch-mode-map (kbd "C-y") 'isearch-yank-kill)
- (define-key isearch-mode-map (kbd "C-v") 'isearch-yank-kill)
- ;; normally M-<tab> which is obviously not going to work
- ;; get a literal tab with C-q <tab>
- (define-key isearch-mode-map (kbd "<tab>") 'isearch-complete)
- ;; recenter the cursor after finding a match
- (defadvice isearch-search (after isearch-recenter activate)
- (when isearch-success
- (recenter-no-redraw)))
- ;; make backspace behave in a more intuitive way
- (define-key isearch-mode-map (kbd "<backspace>") 'isearch-del-char)
- ;; move cursor to the beginning of the match when searching forward
- (defun jpk/isearch-end-hook ()
- (when (and isearch-forward
- isearch-other-end)
- (goto-char isearch-other-end)))
- (add-hook 'isearch-mode-end-hook 'jpk/isearch-end-hook)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; flex isearch
- (with-library 'flex-isearch
- (flex-isearch-mode 1))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; grep
- ;; editable grep results
- (require 'wgrep nil 'noerror)
- ;; TODO
- ;; (defun rgrep-context (arg)
- ;; (interactive "p")
- ;; (let ((grep-template (concat "grep <X> <C> -C " (number-to-string arg)
- ;; " -nH -e <R> <F>")))
- ;; (message "grep-template: %s" grep-template)
- ;; (call-interactively 'rgrep)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Search and replace
- (define-key query-replace-map (kbd "b") 'backup)
- (define-key query-replace-map (kbd "B") 'backup)
- (define-key query-replace-map (kbd "RET") 'act-and-show)
- ;; Findr - find and operate on files recursively
- (autoload 'findr-query-replace "findr.el" "Replace text in files." t)
- (defun query-exchange (string-1 string-2)
- "Exchange string-1 and string-2 interactively.
- The user is prompted at each instance like query-replace."
- (interactive "sString 1: \nsString 2: ")
- (perform-replace
- (concat "\\(" string-1 "\\)\\|" string-2)
- '(replace-eval-replacement replace-quote
- (if (match-string 1) string-2 string-1))
- t t nil))
- (defun search-forward-and-center (string &optional bound noerror count)
- "Just like `search-forward', but centers the point in the window."
- (let ((ret (search-forward regexp bound noerror count)))
- (recenter-no-redraw)
- ret))
- (setq replace-search-function 'search-forward-and-center)
- (defun re-search-forward-and-center (regexp &optional bound noerror count)
- "Just like `re-search-forward', but centers the point in the window."
- (let ((ret (re-search-forward regexp bound noerror count)))
- (recenter-no-redraw)
- ret))
- (setq replace-re-search-function 're-search-forward-and-center)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Ack is a better grep
- ;; TODO look at easy-mmode-define-navigation
- (autoload 'ack "full-ack.el"
- "Emacs frontend for ack" t)
- (autoload 'ack-same "full-ack.el"
- "Emacs frontend for ack" t)
- (defun anchor-regexp (re)
- "Simply wrap RE with `^' and `$', like so: `foo' -> `^foo$'"
- (when (stringp re) (concat "^" re "$")))
- (eval-after-load "full-ack.el"
- '(progn
- (defsubst ack-read (regexp)
- (read-from-minibuffer
- (if regexp "ack pattern: " "ack literal search: ")
- (if (featurep 'thingatpt)
- (let ((str (thing-at-point 'symbol)))
- (set-text-properties 0 (length str) nil str)
- str))
- nil nil
- (if regexp 'ack-regexp-history 'ack-literal-history)))
- (defadvice ack-next-match (after recenter activate)
- (recenter-no-redraw))
- (defadvice ack-previous-match (after recenter activate)
- (recenter-no-redraw))
- (defun ack-next-file (pos arg)
- (interactive "d\np")
- (setq arg (* 2 arg))
- (unless (get-text-property pos 'ack-file)
- (setq arg (1- arg)))
- (assert (> arg 0))
- (dotimes (i arg)
- (setq pos (next-single-property-change pos 'ack-file))
- (unless pos
- (error "Moved past last file")))
- (goto-char pos)
- (recenter-no-redraw)
- pos)
- (defun ack-previous-file (pos arg)
- (interactive "d\np")
- (assert (> arg 0))
- (dotimes (i (* 2 arg))
- (setq pos (previous-single-property-change pos 'ack-file))
- (unless pos
- (error "Moved back before first file")))
- (goto-char pos)
- (recenter-no-redraw)
- pos)
- (add-to-list 'debug-ignored-errors
- (anchor-regexp (regexp-opt '("Moved back before first file"
- "Moved past last file"))))
- (define-key ack-mode-map (kbd "TAB") 'ack-next-match)
- (define-key ack-mode-map (kbd "<backtab>") 'ack-previous-match)
- (define-key ack-mode-map (kbd "N") 'ack-next-file)
- (define-key ack-mode-map (kbd "P") 'ack-previous-file)
- (define-key ack-mode-map (kbd "q") 'quit-window)
- ))
- ;; for grep-mode
- (add-to-list 'debug-ignored-errors
- (anchor-regexp (regexp-opt '("Moved past last grep hit"
- "Moved back before first grep hit"))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Paren insertion
- (add-to-list 'load-path (concat user-emacs-directory "wrap-region"))
- (with-library 'wrap-region
- (defun jpk/wrap-region-after-hook ()
- (goto-char (1+ wrap-region-end)))
- (add-hook 'wrap-region-after-hook 'jpk/wrap-region-after-hook))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Paren Highlighting
- ;; see also highlight-parentheses-mode
- (with-library 'mic-paren
- (paren-activate))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Thing at point
- ;; bounce between matching parens
- (defun goto-match-paren ()
- "Go to the matching parenthesis if on parenthesis. Else go to the
- opening parenthesis one level up."
- (interactive)
- (if (looking-at "\\s\(")
- (forward-list 1)
- (backward-char 1)
- (if (looking-at "\\s\)")
- (progn (forward-char 1) (backward-list 1))
- (while (not (looking-at "\\s("))
- (backward-char 1)
- (when (looking-at "\\s\)")
- (message "->> )")
- (forward-char 1)
- (backward-list 1)
- (backward-char 1))))))
- ;; (put 'goto-match-paren 'CUA 'move)
- (defun bounce-thing-boundary (thing &optional tweak-beginning tweak-end n)
- "Move point to beginning or end of THING.
- If in the middle of THING, go to the beginning. If at the
- beginning, go to end. If at the end, go to beginning. If not in
- a THING, search forward N THINGs (negative N searches backward).
- The optional TWEAK-BEGINNING and TWEAK-END are added to THING's
- beginning or end position, respectively, before moving the
- point."
- (interactive)
- (unless tweak-beginning
- (setq tweak-beginning 0))
- (unless tweak-end
- (setq tweak-end 0))
- (let ((bounds (bounds-of-thing-at-point thing)))
- (if (not bounds)
- (progn
- (when n
- (forward-thing thing n))
- (unless (thing-at-point thing)
- (error "No %s here." thing)))
- (setq bounds (cons (+ (car bounds) tweak-beginning)
- (+ (cdr bounds) tweak-end)))
- (cond
- ((eq (point) (car bounds))
- (goto-char (cdr bounds)))
- ((eq (point) (cdr bounds))
- (goto-char (car bounds)))
- (t
- (goto-char (car bounds)))))))
- (defun bounce-string-or-list ()
- (interactive)
- (if (> (length (thing-at-point 'string)) 0)
- (bounce-thing-boundary 'string)
- (goto-match-paren)))
- (global-set-key (kbd "C-S-<iso-lefttab>") 'bounce-string-or-list)
- (global-set-key (kbd "C-%") 'bounce-string-or-list)
- ;; TODO move this stuff to thing-opt
- ;; upward-mark-thing marks successively "bigger" things if it is
- ;; invoked repeatedly. mark-thing prompts for which thing to mark.
- (with-library 'thing-opt
- (defun reset-upward-bounds-of-thing ()
- (setq upward-bounds-of-thing-index 0
- upward-bounds-of-thing-trial 0
- upward-bounds-of-thing-original-position (point)
- upward-bounds-of-thing-prev nil))
- (defun upward-bounds-of-thing (list-of-things)
- (interactive)
- (let ((len (length list-of-things))
- (index upward-bounds-of-thing-index)
- bounds)
- (while (and (null bounds)
- (< index len))
- (let ((thing (nth index list-of-things))
- (limit '*))
- (if (consp thing)
- (setq limit (cdr thing)
- thing (car thing)))
- (setq bounds (bounds-of-thing-at-point thing))
- (if (not (or (null bounds)
- (and (not (eq limit '*)) (>= upward-bounds-of-thing-trial limit))
- (eq (car bounds) (cdr bounds))
- (and upward-bounds-of-thing-prev
- (equal bounds upward-bounds-of-thing-prev))))
- (setq upward-bounds-of-thing-name (format "%s" (symbol-name thing)))
- (setq bounds nil
- index (mod (1+ index) len)
- upward-bounds-of-thing-index (mod (1+ upward-bounds-of-thing-index) len)
- upward-bounds-of-thing-trial 0)
- (goto-char upward-bounds-of-thing-original-position))))
- (when bounds
- (setq upward-bounds-of-thing-trial (1+ upward-bounds-of-thing-trial))
- (setq upward-bounds-of-thing-prev bounds)
- bounds)))
- (defun upward-mark-thing ()
- (interactive)
- (unless (eq last-command this-command)
- (reset-upward-bounds-of-thing))
- (let ((bounds (upward-bounds-of-thing upward-mark-thing-list)))
- (when bounds
- (message "%s" upward-bounds-of-thing-name)
- (goto-char (car bounds))
- (push-mark (cdr bounds) t 'activate)
- (setq deactivate-mark nil))))
- (defun upward-isearch-thing ()
- (interactive)
- (unless (eq last-command this-command)
- (reset-upward-bounds-of-thing))
- (let ((bounds (upward-bounds-of-thing '(email url word symbol string filename))))
- (when bounds
- (setq isearch-initial-string (buffer-substring-no-properties
- (car bounds) (cdr bounds)))
- (setq isearch-string isearch-initial-string
- isearch-message isearch-initial-string)
- (isearch-update)
- (isearch-highlight (car bounds) (cdr bounds)))))
- (define-key isearch-mode-map (kbd "C-S-s") 'upward-isearch-thing)
- (define-key isearch-mode-map (kbd "M-3") 'upward-isearch-thing)
- (global-set-key (kbd "C-S-s") 'upward-mark-thing)
- (global-set-key (kbd "M-3") 'upward-mark-thing)
- (setq upward-mark-thing-list
- '(email
- url
- word
- symbol
- string
- (up-list . *)
- paragraph
- ))
- )
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Yasnippet (Yet Another Template Mode)
- (setq jpk-snippet-directory (concat user-emacs-directory "snippets/"))
- (setq yas-installed-directory (concat user-emacs-directory "yasnippet/"))
- (setq yas-snippet-directory (concat yas-installed-directory "snippets/"))
- (add-to-list 'load-path yas-installed-directory)
- (with-library 'yasnippet
- (yas/initialize)
- (setq yas/root-directory (list yas-snippet-directory
- jpk-snippet-directory))
- (with-library 'yas-jit
- (yas/jit-load))
- )
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; MISCELLANEOUS KEYBINDINGS
- ;; the best way to find the symbol for a key is to run C-h k <key>
- ;; use M-{ijkl} and C-M-{ijkl} like arrows
- ;; integrates with CUA mode so shifted keys extend the region
- (with-library 'ergo-movement-mode
- (ergo-movement-mode 1))
- ;; normally bound to C-<mouse-3>
- (global-set-key (kbd "<down-mouse-3>") 'mouse-popup-menubar-stuff)
- ;; macro record/playback
- ;; by default, F4 stops recording or plays the last macro
- ;; S-F4 starts recording
- ;; also see "C-x (" and "C-x )"
- (global-set-key (kbd "S-<f4>") 'kmacro-start-macro)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Changing case (capitalization)
- ;; enable the region case changing commands
- (put 'upcase-region 'disabled nil)
- (put 'downcase-region 'disabled nil)
- (defun downcase-region-or-word ()
- "Downcase the current word if the region is inactive, otherwise
- downcase the region."
- (interactive)
- (let ((deactivate-mark nil))
- (if (use-region-p)
- (downcase-region (region-beginning) (region-end))
- (let ((bounds (bounds-of-thing-at-point 'word)))
- (if bounds
- (downcase-region (car bounds) (cdr bounds))
- (message "Nothing to downcase."))))))
- (defun upcase-region-or-word ()
- "Upcase the current word if the region is inactive, otherwise
- upcase the region."
- (interactive)
- (let ((deactivate-mark nil))
- (if (use-region-p)
- (upcase-region (region-beginning) (region-end))
- (let ((bounds (bounds-of-thing-at-point 'word)))
- (if bounds
- (upcase-region (car bounds) (cdr bounds))
- (message "Nothing to upcase."))))))
- (defun capitalize-region-or-word ()
- "Capitalize the current word if the region is inactive, otherwise
- capitalize the region."
- (interactive)
- (let ((deactivate-mark nil))
- (if (use-region-p)
- (capitalize-region (region-beginning) (region-end))
- (let ((bounds (bounds-of-thing-at-point 'word)))
- (if bounds
- (capitalize-region (car bounds) (cdr bounds))
- (message "Nothing to capitalize."))))))
- (global-set-key (kbd "C-x C-u") 'upcase-region-or-word)
- (global-set-key (kbd "C-x C-i") 'capitalize-region-or-word)
- (global-set-key (kbd "C-x C-l") 'downcase-region-or-word)
- ;; (global-set-key (kbd "C-c c u") 'upcase-region-or-word)
- ;; (global-set-key (kbd "C-c c c") 'capitalize-region-or-word)
- ;; (global-set-key (kbd "C-c c d") 'downcase-region-or-word)
- ;; (global-set-key (kbd "C-6") 'downcase-region-or-word)
- ;; (global-set-key (kbd "M-6") 'capitalize-region-or-word)
- ;; (global-set-key (kbd "C-^") 'upcase-region-or-word)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; delete things
- (require 'delete-things)
- (with-library 'ergo-movement-mode
- (global-set-key (kbd "C-S-d") (make-run-keybind-func "DEL" 'move))
- (global-set-key (kbd "M-D") (make-run-keybind-func "C-<backspace>" 'move))
- (global-set-key (kbd "M-d") (make-run-keybind-func "C-<delete>" 'move)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Indentation
- (defun indent-relative-dwim ()
- "Indent the current line to either: the beginning of last
- preceding line with text, the next tab stop (as determined by
- tab-width, not tab-stop-list) after the previous indent, or the
- beginning of the line. Repeatedly calling this function cycles
- between these 3 actions."
- (interactive)
- (let ((last-line-indent 0)
- (next-indent 0))
- (save-excursion
- (save-match-data
- (beginning-of-line)
- (when (re-search-backward "[^\t ]" nil t)
- (beginning-of-line)
- (re-search-forward "[^\t ]" nil t)
- (goto-char (match-beginning 0))
- (setq last-line-indent (current-column)))))
- (setq next-indent (* (1+ (/ last-line-indent tab-width)) tab-width))
- (cond
- ((= (current-column) last-line-indent)
- (indent-line-to next-indent))
- ((= (current-column) next-indent)
- (indent-line-to 0))
- (t
- (indent-line-to last-line-indent)))))
- (setq-default indent-line-function 'indent-relative-dwim)
- (global-set-key (kbd "C-m") 'newline-and-indent)
- (defun set-tab-width (arg)
- (interactive "nSet tab width: ")
- (set-variable 'tab-width arg))
- ;; in Emacs23, you can indent the region with a simple TAB
- (unless (fboundp 'region-active-p)
- ;; use-region-p is not built-in in emacs22 or earlier
- (defun region-active-p ()
- "Return t if Transient Mark mode is enabled and the mark is active.
- Most commands that act on the region if it is active and
- Transient Mark mode is enabled, and on the text near point
- otherwise, should use `use-region-p' instead. That function
- checks the value of `use-empty-active-region' as well."
- (and transient-mark-mode mark-active))
- (defcustom use-empty-active-region nil
- "Whether \"region-aware\" commands should act on empty regions.
- If nil, region-aware commands treat empty regions as inactive.
- If non-nil, region-aware commands treat the region as active as
- long as the mark is active, even if the region is empty.
- Region-aware commands are those that act on the region if it is
- active and Transient Mark mode is enabled, and on the text near
- point otherwise."
- :type 'boolean
- :version "23.1"
- :group 'editing-basics)
- (defun use-region-p ()
- "Return t if the region is active and it is appropriate to act on it.
- This is used by commands that act specially on the region under
- Transient Mark mode. It returns t if and only if Transient Mark
- mode is enabled, the mark is active, and the region is non-empty.
- If `use-empty-active-region' is non-nil, it returns t even if the
- region is empty.
- For some commands, it may be appropriate to disregard the value
- of `use-empty-active-region'; in that case, use `region-active-p'."
- (and (region-active-p)
- (or use-empty-active-region (> (region-end) (region-beginning)))))
- (defadvice indent-for-tab-command (around indent-dwim activate)
- "If the region is active, run indent-region-function instead."
- (if (use-region-p)
- (let ((deactivate-mark nil))
- (funcall indent-region-function (region-beginning) (region-end)))
- ad-do-it))
- )
- ;; new buffers default to using 4 spaces for indent
- (setq-default tab-width 8)
- (setq-default indent-tabs-mode nil)
- ;; mostly use spaces for indent, but sometimes you need tabs
- (define-minor-mode smart-tab-mode
- "Switches between using tabs and spaces for indenting."
- :init-value nil
- :lighter " Tab" ;; modeline indicator
- (cond
- (smart-tab-mode
- (progn
- ;;(setq indent-tabs-mode t)
- ;;(setq tab-width 4)
- (message "Tab mode")))
- ((not smart-tab-mode)
- (progn
- ;;(setq indent-tabs-mode nil)
- ;;(setq tab-width 8)
- (message "Space mode")))))
- (defmacro smart-tabs-advise (function offset)
- "Wraps an indentation function to make it handle tabs in a
- rational way. See http://www.emacswiki.org/emacs/SmartTabs"
- `(progn
- (defadvice ,function (around smart-tabs activate)
- ;; honor per-buffer minor mode
- (if (not smart-tab-mode)
- ad-do-it
- (save-excursion
- (beginning-of-line)
- (while (looking-at "\t*\\( +\\)\t+")
- (replace-match "" nil nil nil 1)))
- (setq tab-width tab-width)
- (let ((indent-tabs-mode t)
- (tab-width fill-column)
- (,offset fill-column))
- ad-do-it)))
- ))
- (smart-tabs-advise cperl-indent-line cperl-indent-level)
- (smart-tabs-advise c-indent-line c-basic-offset)
- (smart-tabs-advise c-indent-region c-basic-offset)
- (smart-tabs-advise php-cautious-indent-region c-basic-offset)
- (smart-tabs-advise php-cautious-indent-line c-basic-offset)
- ;; shift-tab should undo what tab does
- (global-set-key (kbd "<backtab>") 'delete-indentation)
- ;; rigidly indent
- ;; see EmacsWiki://MovingRegionHorizontally
- (defun move-horizontally (beg en arg)
- "Move the region defined by (beg en) by arg characters.
- Positive arg means right; negative means left"
- (save-excursion
- (let ((deactivate-mark nil)
- beg-bol)
- (goto-char beg)
- (setq beg-bol (line-beginning-position))
- (goto-char en)
- ;;(move-beginning-of-line nil)
- (indent-rigidly beg-bol en arg)
- (push-mark beg t t))))
- (defun move-horizontally-dwim (beg en arg)
- "If there is an active region, move the whole region arg
- columns. Otherwise, move the cursor line arg columns."
- (interactive "r")
- (if (use-region-p)
- (move-horizontally beg en arg)
- (move-horizontally (line-beginning-position) (line-end-position) arg)))
- (global-set-key (kbd "C-9")
- (lambda (beg en)
- "move region left by one"
- (interactive "r")
- (move-horizontally-dwim beg en -1)))
- (global-set-key (kbd "C-0")
- (lambda (beg en)
- "move region right by one"
- (interactive "r")
- (move-horizontally-dwim beg en 1)))
- (global-set-key (kbd "C-(")
- (lambda (beg en)
- "move region left by four"
- (interactive "r")
- (move-horizontally-dwim beg en -4)))
- (global-set-key (kbd "C-)")
- (lambda (beg en)
- "move region right by four"
- (interactive "r")
- (move-horizontally-dwim beg en 4)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; drag-stuff
- ;; drag things (words, regions, lines) with arrow keys
- (add-to-list 'load-path (concat user-emacs-directory "drag-stuff"))
- (with-library 'drag-stuff
- (setq drag-stuff-modifier '(meta shift)))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; Fill
- ;; a smarter fill
- ;; this can't be autoloaded, apparently
- (require 'filladapt nil 'noerror)
- ;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
- (defun unfill-paragraph ()
- "Takes a multi-line paragraph and makes it into a single line
- of text."
- (interactive)
- (let ((fill-column (point-max)))
- (fill-paragraph nil)))
- (global-set-key (kbd "M-Q") 'unfill-paragraph)
- (defadvice fill-paragraph (after scroll-to-left activate)
- (scroll-right (window-hscroll)))
- (defun align-regexp-repeated (start stop regexp)
- "Like align-regexp, but repeated for multiple columns. See
- http://www.emacswiki.org/emacs/AlignCommands"
- (interactive "r\nsAlign regexp: ")
- (let ((spacing 1)
- (old-buffer-size (buffer-size)))
- ;; If our align regexp is just spaces, then we don't need any
- ;; extra spacing.
- (when (string-match regexp " ")
- (setq spacing 0))
- (align-regexp start stop
- ;; add space at beginning of regexp
- (concat "\\([[:space:]]*\\)" regexp)
- 1 spacing t)
- ;; modify stop because align-regexp will add/remove characters
- (align-regexp start (+ stop (- (buffer-size) old-buffer-size))
- ;; add space at end of regexp
- (concat regexp "\\([[:space:]]*\\)")
- 1 spacing t)))
- ;; see also fill-individual-paragraphs
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; scrolling
- ;; pager makes scrolling makes scroll-up and scroll-down inverses (the
- ;; point is in the same place after doing one and then the other).
- (with-library 'pager
- (global-set-key (kbd "<next>") 'pager-page-down)
- (global-set-key (kbd "<prior>") 'pager-page-up)
- (unless cua-enable-cua-keys
- (global-set-key (kbd "C-v") 'pager-page-down)
- (global-set-key (kbd "M-v") 'pager-page-up)))
- ;; makes scrolling less jittery
- (setq auto-window-vscroll nil
- scroll-conservatively most-positive-fixnum
- redisplay-dont-pause t
- ;;smooth-scroll-margin 1 ;; what is this? was in custom.el
- ;;scroll-step 0 ;; default
- )
- (put 'scroll-left 'disabled nil)
- (setq auto-hscroll-mode-default auto-hscroll-mode)
- (make-local-variable 'auto-hscroll-mode)
- (setq hscroll-point-previous 0)
- (make-local-variable 'hscroll-point-previous)
- (defun detect-cursor-movement ()
- (with-temp-message (current-message)
- (let ((pt (point)))
- (unless (= pt hscroll-point-previous)
- (setq hscroll-point-previous pt)
- (setq auto-hscroll-mode auto-hscroll-mode-default)
- ;; a hack to make it apply on the first movement
- (message nil)
- ))))
- (defvar cursor-movement-detector-timer nil
- "Periodic timer that checks for cursor movement.")
- (define-minor-mode smart-hscroll-mode
- :init-value nil
- :lighter nil
- (when cursor-movement-detector-timer
- (cancel-timer cursor-movement-detector-timer))
- (when smart-hscroll-mode
- (save-current-buffer
- (dolist (buf (buffer-list))
- (set-buffer buf)
- (setq hscroll-point-previous (point))))
- (setq cursor-movement-detector-timer
- (run-with-idle-timer 0.1 t 'detect-cursor-movement))
- ))
- (smart-hscroll-mode 1)
- (defun beginning-of-line-dwim (arg)
- (interactive "p")
- (if (bolp)
- (beginning-of-line-text arg)
- (move-beginning-of-line arg)))
- (put 'beginning-of-line-dwim 'CUA 'move)
- ;; <home> is still bound to move-beginning-of-line
- (global-set-key (kbd "C-a") 'beginning-of-line-dwim)
- (defun end-of-code-or-line ()
- "Move to EOL. If already there, to EOL sans comments.
- That is, the end of the code, ignoring any trailing comment
- or whitespace. Note this does not handle 2 character
- comment starters like // or /*. Such will not be skipped."
- (interactive)
- (if (not (eolp))
- (end-of-line)
- (skip-chars-backward " \t")
- (let ((pt (point))
- (lbp (line-beginning-position))
- (comment-start-re (concat (regexp-quote
- (replace-regexp-in-string
- "[[:space:]]*" "" comment-start))
- "\\|\\s<"))
- (comment-stop-re "\\s>")
- (lim))
- (when (re-search-backward comment-start-re lbp t)
- (setq lim (point))
- (if (re-search-forward comment-stop-re (1- pt) t)
- (goto-char pt)
- (goto-char lim) ; test here ->
- (while (looking-back comment-start-re (1- (point)))
- (backward-char))
- (skip-chars-backward " \t"))))))
- (put 'end-of-code-or-line 'CUA 'move)
- ;; <end> is still bound to end-of-visual-line
- (global-set-key (kbd "C-e") 'end-of-code-or-line)
- (defun force-scroll-left (&optional amount window)
- "Disable auto-hscroll-mode when scrolling. This means that if
- you use this function to scroll, the view will not snap back to
- the cursor unless it moves."
- (interactive)
- (unless amount
- (setq amount 4))
- (unless window
- (setq window (selected-window)))
- (setq auto-hscroll-mode nil)
- (scroll-left amount))
- (defun force-scroll-left-8 ()
- (interactive)
- (force-scroll-left 8))
- (defun force-scroll-right-8 ()
- (interactive)
- (force-scroll-left -8))
- (require 'mwheel)
- (defvar mouse-wheel-horiz-scroll-amount
- '(4 ((shift) . 1) ((control) . 0.25))
- "Amount to scroll windows by when spinning the mouse wheel.
- Similar to `mouse-wheel-scroll-amount'. This is an alist mapping
- the modifier key to the amount to scroll when the wheel is moved
- with the modifier key depressed. Elements of the list have the
- form (MODIFIERS . AMOUNT) or just AMOUNT if MODIFIERS is nil.
- Meta has no effect.")
- (defun mwheel-scroll-horiz (event)
- "Scroll left or right according to the EVENT.
- This should only be bound to mouse buttons 4 and 5."
- (interactive (list last-input-event))
- (let* ((mousewin (mwheel-event-window event))
- (curwin (when mouse-wheel-follow-mouse
- (prog1 (selected-window)
- (select-window mousewin))))
- (buffer (window-buffer curwin))
- (opoint (with-current-buffer buffer
- (when (eq (car-safe transient-mark-mode) 'only)
- (point))))
- (mods
- (delq 'meta (delq 'click (delq 'double (delq 'triple (event-modifiers event))))))
- (amt (assoc mods mouse-wheel-horiz-scroll-amount)))
- ;; Extract the actual amount or find the element that has no modifiers.
- (if amt (setq amt (cdr amt))
- (let ((list-elt mouse-wheel-horiz-scroll-amount))
- (while (consp (setq amt (pop list-elt))))))
- (if (floatp amt) (setq amt (1+ (truncate (* amt (window-width))))))
- (unwind-protect
- (let ((button (mwheel-event-button event)))
- (cond ((eq button mouse-wheel-down-event)
- (condition-case nil (force-scroll-left (- amt))))
- ((eq button mouse-wheel-up-event)
- (condition-case nil (force-scroll-left amt)))
- (t (error "Bad binding in mwheel-scroll-horiz"))))
- (if curwin (select-window curwin)))
- ;; If there is a temporarily active region, deactivate it iff
- ;; scrolling moves point.
- (when opoint
- (with-current-buffer buffer
- (when (/= opoint (point))
- (deactivate-mark)))))
- (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time)
- (if mwheel-inhibit-click-event-timer
- (cancel-timer mwheel-inhibit-click-event-timer)
- (add-hook 'pre-command-hook 'mwheel-filter-click-events))
- (setq mwheel-inhibit-click-event-timer
- (run-with-timer mouse-wheel-inhibit-click-time nil
- 'mwheel-inhibit-click-timeout))))
- (global-set-key (kbd "<M-mouse-4>") 'mwheel-scroll-horiz)
- (global-set-key (kbd "<M-mouse-5>") 'mwheel-scroll-horiz)
- (global-set-key (kbd "<C-M-mouse-4>") 'mwheel-scroll-horiz)
- (global-set-key (kbd "<C-M-mouse-5>") 'mwheel-scroll-horiz)
- (global-set-key (kbd "<S-M-mouse-4>") 'mwheel-scroll-horiz)
- (global-set-key (kbd "<S-M-mouse-5>") 'mwheel-scroll-horiz)
- ;; these are generally the horizontal nudges on a scroll wheel
- (global-set-key (kbd "<mouse-7>") 'force-scroll-left-8)
- (global-set-key (kbd "<mouse-6>") 'force-scroll-right-8)
- (global-set-key (kbd "C-<next>") 'force-scroll-left-8)
- (global-set-key (kbd "C-<prior>") 'force-scroll-right-8)
- ;; scroll the other buffer
- (global-set-key (kbd "S-<next>") 'scroll-other-window)
- (global-set-key (kbd "S-<prior>") 'scroll-other-window-down)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; convert between different EOL modes
- (defun dos2unix ()
- "Convert a DOS file ('\\r\\n') to Unix ('\\n')"
- (interactive)
- (set-buffer-file-coding-system 'undecided-unix t))
- (defun force-unix-line-endings ()
- "Replace all occurances of \\r\\n with \\n."
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (while (search-forward "\015\012" nil t)
- (replace-match "\012" nil t))))
- (defun unix2dos ()
- "Convert a Unix ('\n') file to DOS ('\r\n')"
- (interactive)
- (set-buffer-file-coding-system 'undecided-dos t))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; 123-menu
- (autoload '123-menu-display-menu-root-menu "123-menu.el"
- "Display a simple text menu in the minibuffer." t)
- (global-set-key (kbd "C-`") '123-menu-display-menu-root-menu)
- (eval-after-load "123-menu.el"
- '(progn
- (123-menu-defmenu
- breadcrumb-menu
- ("m" "[m] Make breadcrumb" 'bc-set)
- ("p" "[p] Goto previous" 'bc-previous)
- ("n" "[n] Goto next" 'bc-next)
- ("P" "[P] Goto previous in this buffer" 'bc-local-previous)
- ("N" "[N] Goto next in this buffer" 'bc-local-next)
- ("c" "[c] Goto current" 'bc-goto-current)
- ("l" "[l] List breadcrumbs" 'bc-list)
- ("X" "[X] Clear All" 'bc-clear)
- )
- (123-menu-defmenu
- display-menu
- ("l" "[l] Toggle Line numbers" 'linum-mode)
- ("s" "[s] Toggle visible whitespace" 'whitespace-mode)
- ("w" "[w] Visual Line mode (word-wrap)" 'visual-line-mode)
- ("m" "[m] Menu Bar mode" 'menu-bar-mode)
- )
- (123-menu-defmenu
- misc-menu
- ("r" "[r] remember" 'remember)
- ("e" "[e] Find init.el" 'find-user-init-file)
- ("i" "[i] Toggle input method" 'toggle-input-method)
- ("c" "[c] Interactive ELisp console" 'ielm)
- ("t" "[t] Start timer" 'elapsed-time-start)
- ("T" "[T] Print elapsed time" (lambda () (interactive)
- (message "Elapsed time: %0.3f s." (elapsed-time))))
- ("v" "[v] Toggle save-visited-files-mode" 'save-visited-files-mode)
- ("a" "[a] Toggle auto-complete-mode" 'auto-complete-mode)
- )
- (123-menu-defmenu
- format-menu
- ("t" "[t] Smart Tab mode" 'smart-tab-mode)
- ("w" "[w] Set tab width" 'set-tab-width)
- ("q" "[q] Autofill mode" 'auto-fill-mode)
- )
- (123-menu-defmenu-repeated
- window-history-menu
- ("p" "[p] Previous window configuration" 'window-config-history-backward)
- ("n" "[n] Next window configuration" 'window-config-history-forward)
- )
- (123-menu-defmenu-repeated
- buf-move-menu
- ("i" "[i] Move buffer up" 'buf-move-up)
- ("j" "[j] Move buffer right" 'buf-move-left)
- ("k" "[k] Move buffer down" 'buf-move-down)
- ("l" "[l] Move buffer left" 'buf-move-right)
- )
- (123-menu-defmenu-repeated
- nav-menu
- ("i" "[i] up line" 'previous-line)
- ("j" "[j] left char" 'backward-char)
- ("k" "[k] down line" 'next-line)
- ("l" "[l] right char" 'forward-char)
- ("u" "[u] scroll up" 'cua-scroll-down)
- ("o" "[o] scroll down" 'cua-scroll-up)
- ("C-i" "[C-i] up para" 'backward-paragraph)
- ("C-j" "[C-j] left word" 'c-backward-subword)
- ("C-k" "[C-k] down para" 'forward-paragraph)
- ("C-l" "[C-l] right word" 'c-forward-subword)
- ("C-u" "[C-u] scroll left" 'force-scroll-right-8)
- ("C-o" "[C-o] scroll right" 'force-scroll-left-8)
- )
- (123-menu-defmenu
- root-menu
- ("b" "[b] Breadcrumbs" '123-menu-display-menu-breadcrumb-menu)
- ("d" "[d] Display options" '123-menu-display-menu-display-menu)
- ("f" "[f] Formatting" '123-menu-display-menu-format-menu)
- ("h" "[h] Window Config History" '123-menu-display-menu-window-history-menu)
- ("m" "[m] Miscellaneous" '123-menu-display-menu-misc-menu)
- ("n" "[n] Navigation" '123-menu-display-menu-nav-menu)
- ("w" "[w] Move Buffers in Windows" '123-menu-display-menu-buf-move-menu)
- )
- ))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; host-specific stuff
- (load (concat user-emacs-directory "host.el") 'noerror)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (message "jpkotta's init.el loaded")
- (message "init.el loaded in %0.3f s." (toc init-el-time))
Add Comment
Please, Sign In to add comment