Guest User

Emacs init.el

a guest
Jun 23rd, 2011
663
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 119.68 KB | None | 0 0
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;; GNU Emacs init file
  3.  
  4. (message "loading jpkotta's init.el")
  5.  
  6. (defun make-tictoc ()
  7. (current-time))
  8. (defmacro tic (tt)
  9. `(setq ,tt (current-time)))
  10. (defun toc (tt)
  11. (- (time-to-seconds (current-time))
  12. (time-to-seconds tt)))
  13.  
  14. ;; profile this file's evaluation time
  15. (setq init-el-time (make-tictoc))
  16.  
  17. ;; this init file uses principles from:
  18. ;; http://a-nickels-worth.blogspot.com/2007/11/effective-emacs.html
  19.  
  20. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  21. ;;; Paths
  22. ;; add my elisp files to the load path
  23. (add-to-list 'load-path user-emacs-directory)
  24.  
  25. ;; info directory
  26. (eval-after-load "info"
  27. '(add-to-list 'Info-additional-directory-list "~/.info")
  28. )
  29.  
  30. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  31. ;;; Custom
  32. ;; store settings from customization system in a separate file
  33. (setq custom-file (concat user-emacs-directory "custom.el"))
  34. (message "loading customizations from %s" custom-file)
  35. (let ((custom-el-time (make-tictoc)))
  36. (load custom-file 'noerror)
  37. (message "custom.el loaded in %f s" (toc custom-el-time)))
  38.  
  39. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  40. ;;; Miscellaneous
  41.  
  42. (defmacro with-library (feature &rest body)
  43. "Evaluate BODY only if FEATURE is provided. (require FEATURE) will be attempted."
  44. (declare (indent defun))
  45. `(when (require ,feature nil 'noerror)
  46. ,@body))
  47.  
  48. (defun setup-RAIDE-file ()
  49. "View RAIDE files from Eagle."
  50. (interactive)
  51. (recode-region (point-min) (point-max)
  52. 'cp437-dos 'iso-latin-1-dos)
  53. (buffer-face-set 'fixed-pitch)
  54. (view-mode))
  55.  
  56. (defun defadvice-list (funclist class name lambda-expr)
  57. "A convenience function to define the same advice on several
  58. functions at once. FUNCLIST is a list of functions. CLASS is
  59. one of `before', `after', or `around'. NAME is a name for the
  60. advice. LAMBDA-EXPR is a lambda expression that is the body of
  61. the advice. The advice is not protected, is put at the
  62. beginning of the functions' advice lists, and is activated
  63. immediately."
  64. (dolist (func funclist)
  65. (ad-add-advice func
  66. `(,name
  67. nil ;; protect
  68. t ;; activate
  69. (advice . ,lambda-expr))
  70. class
  71. 'first) ;; position
  72. (ad-activate func)))
  73.  
  74. ;; suspend-frame is annoying in X, but useful in terminals.
  75. (global-set-key (kbd "C-x C-z")
  76. (lambda () (interactive)
  77. (if (display-graphic-p)
  78. (message "Use `M-x suspend-frame' instead.")
  79. (suspend-frame))))
  80.  
  81. (defun pl-tr (STRING FROM TO)
  82. "perlish transpose: similar to STRING =~ tr/FROM/TO/"
  83. (replace-regexp-in-string
  84. (concat "\[" FROM "\]")
  85. (lambda (s)
  86. (string (elt TO (search s FROM))))
  87. STRING))
  88.  
  89. ;; ;; http://emacs.wordpress.com/2007/01/17/eval-and-replace-anywhere/
  90. ;; (defun eval-and-replace-last-sexp ()
  91. ;; "Replace the preceding sexp with its value."
  92. ;; (interactive "*")
  93. ;; (save-excursion
  94. ;; (with-syntax-table emacs-lisp-mode-syntax-table
  95. ;; (backward-kill-sexp)))
  96. ;; (condition-case nil
  97. ;; (prin1 (eval (read (current-kill 0)))
  98. ;; (current-buffer))
  99. ;; (error (message "Invalid expression")
  100. ;; (insert (current-kill 0)))))
  101. ;; (global-set-key (kbd "C-c C-e") 'eval-and-replace-last-sexp)
  102. (global-set-key (kbd "C-c e") 'eval-print-last-sexp)
  103.  
  104. ;; locking is dumb sometimes
  105. ;; this effectively disables it by always silently stealing the file
  106. (defun ask-user-about-lock (file other-user)
  107. t)
  108.  
  109. ;; enable with M-x sticky-buffer-mode
  110. (define-minor-mode sticky-buffer-mode
  111. "Make the current window always display this buffer."
  112. nil " sticky" nil
  113. (set-window-dedicated-p (selected-window) sticky-buffer-mode))
  114.  
  115. ;; from http://svn.red-bean.com/repos/kfogel/trunk/.emacs
  116. (defmacro do-on-lines (start end &rest body)
  117. "Run BODY at each line start of every line from START to END."
  118. (declare (indent defun))
  119. `(save-excursion
  120. (save-restriction
  121. (save-match-data
  122. (goto-char ,start)
  123. (while (< (point) ,end)
  124. (beginning-of-line)
  125. ,@body
  126. (forward-line 1))))))
  127.  
  128. ;; not used anywhere but interesting
  129. (defun permutations (bag)
  130. "Return a list of all the permutations of the input."
  131. ;; If the input is nil, there is only one permutation:
  132. ;; nil itself
  133. (if (null bag)
  134. '(())
  135. ;; Otherwise, take an element, e, out of the bag.
  136. ;; Generate all permutations of the remaining elements,
  137. ;; And add e to the front of each of these.
  138. ;; Do this for all possible e to generate all permutations.
  139. (mapcan (lambda (e)
  140. (mapcar (lambda (p) (cons e p))
  141. (permutations
  142. (remove* e bag :count 1))))
  143. bag)))
  144.  
  145. (defun filter (condp lst)
  146. "The filter higher-order function. Returns a list containing
  147. all elements of LST for which CONDP is not nil."
  148. (delq nil (mapcar (lambda (x) (and (funcall condp x) x)) lst)))
  149.  
  150. ;; narrowing makes a region effectively the entire buffer
  151. ;; useful for not mangling the entire buffer
  152. ;; disable with widen
  153. (put 'narrow-to-region 'disabled nil)
  154.  
  155. ;; I hit this by accident sometimes, and don't find the default
  156. ;; binding compose-mail useful.
  157. (global-unset-key (kbd "C-x m"))
  158.  
  159. (defun minibuffer-refocus ()
  160. "Refocus the minibuffer if it is waiting for input."
  161. (interactive)
  162. (when (active-minibuffer-window)
  163. (message "") ;; clear the echo area, in case it overwrote the minibuffer
  164. (select-window (minibuffer-window))))
  165.  
  166. (defadvice mouse-set-point (around no-mouse-select-window-if-minibuffer-active activate)
  167. (unless (minibuffer-window-active-p (selected-window))
  168. ad-do-it))
  169.  
  170. ;; cancel everything, including active minibuffers and recursive edits
  171. (global-set-key (kbd "C-M-g") 'top-level)
  172.  
  173. (defun remove-from-list (symbol element)
  174. "Inverse of `add-to-list'. TODO: add compare-fn."
  175. (set symbol (delete element (eval symbol))))
  176.  
  177. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  178. ;;; Org Mode
  179.  
  180. (defun jpk/org-mode-hook ()
  181. (interactive)
  182. (local-unset-key (kbd "C-<tab>"))
  183. (local-unset-key (kbd "C-S-<iso-lefttab>"))
  184. (local-unset-key (kbd "<backtab>"))
  185. (local-unset-key (kbd "<S-iso-lefttab>"))
  186. (local-unset-key (kbd "M-<up>"))
  187. (local-unset-key (kbd "M-<down>"))
  188. (local-unset-key (kbd "S-<left>"))
  189. (local-unset-key (kbd "S-<right>"))
  190. (local-unset-key (kbd "C-S-<left>"))
  191. (local-unset-key (kbd "C-S-<right>"))
  192. (local-set-key (kbd "C-<down>") 'outline-forward-same-level)
  193. (local-set-key (kbd "C-<up>") 'outline-backward-same-level)
  194. (when (featurep 'filladapt)
  195. (filladapt-mode 0))
  196. (visual-line-mode 1)
  197. (with-library 'flyspell
  198. (flyspell-mode 1)))
  199.  
  200. (eval-after-load "org"
  201. '(progn
  202. (setq-default org-hide-leading-stars t)
  203. (add-to-list 'org-mode-hook 'jpk/org-mode-hook)
  204. ))
  205.  
  206. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  207. ;;; misc insertions
  208.  
  209. ;; insert placeholder text
  210. (defun insert-lorem-ipsum ()
  211. (interactive "*")
  212. (insert "Lorem ipsum dolor sit amet, consectetur adipisicing "
  213. "elit, sed do eiusmod tempor incididunt ut labore et "
  214. "dolore magna aliqua. Ut enim ad minim veniam, quis "
  215. "nostrud exercitation ullamco laboris nisi ut aliquip "
  216. "ex ea commodo consequat. Duis aute irure dolor in "
  217. "reprehenderit in voluptate velit esse cillum dolore "
  218. "eu fugiat nulla pariatur. Excepteur sint occaecat "
  219. "cupidatat non proident, sunt in culpa qui officia "
  220. "deserunt mollit anim id est laborum."))
  221.  
  222. (defun insert-look-of-disapproval (arg)
  223. (interactive "*P")
  224. (if (not arg)
  225. ;;(mapconcat 'ucs-insert '(3232 95 3232) "")
  226. (insert "ಠ_ಠ")
  227. (insert " _____) _____)\n"
  228. " / \\ / \\\n"
  229. "( O ) ( O )\n"
  230. " \\___/ \\___/\n"
  231. " ======= \n")
  232. ))
  233. (global-set-key (kbd "C-c w t f") 'insert-look-of-disapproval)
  234.  
  235. (defun insert-awesome-face (arg)
  236. (interactive "*P")
  237. (if (not arg)
  238. ;;(ucs-insert 9787)
  239. (insert "☻")
  240. (insert " __ __ \n"
  241. " / o / o \n"
  242. "|____| |____| \n"
  243. " \n"
  244. "------------- \n"
  245. "| )\n"
  246. " \\ ,-----, \n"
  247. " '-./____-' \n")
  248. ))
  249.  
  250. (defun insert-look-of-worry ()
  251. (interactive "*")
  252. (insert "٩( ͡๏̯͡๏)۶"))
  253.  
  254. (defun list-unicode-display (&optional regexp)
  255. "Display a list of unicode characters and their names in a buffer."
  256. (interactive "sRegexp (default \".*\"): ")
  257. (let* ((regexp (or regexp ".*"))
  258. (case-fold-search t)
  259. ;;(cmp (lambda (x y) (string< (car x) (car y))))
  260. (cmp (lambda (x y) (< (cdr x) (cdr y))))
  261. ;; alist like ("name" . code-point)
  262. (char-alist (sort (filter (lambda (x) (string-match regexp (car x)))
  263. (ucs-names))
  264. cmp)))
  265. (with-help-window "*Unicode characters*"
  266. (with-current-buffer standard-output
  267. (dolist (c char-alist)
  268. (insert (format "0x%06X\t" (cdr c)))
  269. (insert (cdr c))
  270. (insert (format "\t%s\n" (car c))))))))
  271.  
  272. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  273. ;;; Date and Time
  274.  
  275. (defvar insert-time-format "%H:%M:%S"
  276. "*Format for `insert-time', see `format-time-string' for syntax.")
  277.  
  278. (defvar insert-date-format "%Y-%m-%d"
  279. "*Format for `insert-date', see `format-time-string' for syntax.")
  280.  
  281. (defun insert-time-str (fmt)
  282. "Insert a formatted timestamp string in the buffer. See
  283. `format-time-string' for syntax of FMT."
  284. (insert (format-time-string fmt (current-time))))
  285.  
  286. (defun insert-time ()
  287. "Insert the current time in the buffer."
  288. (interactive "*")
  289. (insert-time-str insert-time-format))
  290.  
  291. (defun insert-date ()
  292. "Insert the current date in the buffer."
  293. (interactive "*")
  294. (insert-time-str insert-date-format))
  295.  
  296. (defun insert-date-and-time ()
  297. "Insert the current date and time in the buffer."
  298. (interactive "*")
  299. (insert-time-str (concat insert-date-format " " insert-time-format)))
  300.  
  301. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  302. ;;; ssh
  303.  
  304. ;; keychain is a way to manage ssh-agents. In particular, it looks
  305. ;; for a running ssh-agent and stores it's env vars in a file, any
  306. ;; program that knows how to read the file can use the agent.
  307. (with-library 'keychain-environment
  308. (refresh-keychain-environment))
  309.  
  310. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  311. ;;; C SubWordMode
  312. ;; FindSubWordsInCamelCase
  313.  
  314. ;; the old name is c-subword-mode, and it did not define a global mode
  315. ;; (with-library 'c-subword-mode
  316. ;; (define-global-minor-mode global-subword-mode
  317. ;; c-subword-mode
  318. ;; (lambda () (c-subword-mode 1))))
  319.  
  320. ;; (with-library 'subword
  321. ;; (global-subword-mode 1)
  322. ;; )
  323.  
  324. (with-library 'syntax-subword
  325. (global-syntax-subword-mode 1)
  326. )
  327.  
  328. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  329. ;;; Diminish
  330. ;; Hide some minor mode indicators in the modeline.
  331. (eval-after-load "eldoc" '(diminish 'eldoc-mode ""))
  332. (eval-after-load "filladapt" '(diminish 'filladapt-mode ""))
  333. (eval-after-load "doxymacs" '(diminish 'doxymacs-mode ""))
  334. (eval-after-load "auto-complete" '(diminish 'auto-complete-mode ""))
  335. (eval-after-load "face-remap" '(diminish 'buffer-face-mode ""))
  336. (eval-after-load "highlight-parentheses" '(diminish 'highlight-parentheses-mode ""))
  337. (eval-after-load "wrap-region" '(diminish 'wrap-region-mode ""))
  338. (eval-after-load "abbrev" '(diminish 'abbrev-mode ""))
  339. (eval-after-load "fixme-mode" '(diminish 'fixme-mode ""))
  340. (eval-after-load "yasnippet" '(diminish 'yas/minor-mode ""))
  341. (eval-after-load "flyspell" '(diminish 'flyspell-mode ""))
  342.  
  343. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  344. ;;; Help
  345.  
  346. (autoload 'apropos-toc "apropos-toc.el"
  347. "A nicer apropos buffer." t)
  348. (global-set-key (kbd "C-h a") 'apropos-toc)
  349.  
  350. (setq message-log-max 1000)
  351.  
  352. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  353. ;;; numbers and strings
  354.  
  355. ;; make it a bit easier to do hex sequences
  356. ;; could replace string-to-number in most cases
  357. (defun str2num (str &optional base)
  358. "Like string-to-number, but with 'normal' (C-style) prefixes
  359. for non-decimal strings."
  360. (let ((case-fold-search nil))
  361. (cond
  362. ((string-match "0x[0-9A-F]+" str)
  363. (string-to-number (replace-regexp-in-string "0x" "" str)
  364. 16))
  365. ((string-match "0o[0-7]+" str)
  366. (string-to-number (replace-regexp-in-string "0o" "" str)
  367. 8))
  368. ((string-match "0d[0-9]+" str)
  369. (string-to-number (replace-regexp-in-string "0d" "" str)
  370. 10))
  371. ((string-match "0b[01]+" str)
  372. (string-to-number (replace-regexp-in-string "0b" "" str)
  373. 2))
  374. (t
  375. (string-to-number str base)))))
  376.  
  377. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  378. ;;; CUA mode
  379.  
  380. ;; Provides CUA-type ("Common User Access") keybindings, usable
  381. ;; rectangles, and other goodies. Most things are set through custom.
  382.  
  383. ;; CUA mode takes over C-z, C-x, C-c, and C-v completely. This will
  384. ;; enable us to turn those bindings off in certain buffers.
  385. (make-variable-buffer-local 'cua--ena-cua-keys-keymap)
  386.  
  387. ;; (cua-mode t) ;; enable with C-x, C-c, C-v
  388. (cua-selection-mode t) ;; enable without C-x, C-c, C-v
  389.  
  390. (eval-after-load "cua-rect"
  391. '(progn
  392. (defun cua-sequence-rectangle (first incr format)
  393. "Resequence each line of CUA rectangle starting from FIRST.
  394. The numbers are formatted according to the FORMAT string."
  395. (interactive
  396. (list (if current-prefix-arg
  397. (prefix-numeric-value current-prefix-arg)
  398. (str2num
  399. (read-string "Start value: (0) " nil nil "0")))
  400. (str2num
  401. (read-string "Increment: (1) " nil nil "1"))
  402. (read-string (concat "Format: (" cua--rectangle-seq-format ") "))))
  403. (if (= (length format) 0)
  404. (setq format cua--rectangle-seq-format)
  405. (setq cua--rectangle-seq-format format))
  406. (cua--rectangle-operation 'clear nil t 1 nil
  407. '(lambda (s e l r)
  408. (delete-region s e)
  409. (insert (format format first))
  410. (setq first (+ first incr)))))
  411. ))
  412.  
  413. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  414. ;;; revert
  415.  
  416. (global-auto-revert-mode 1)
  417. (setq auto-revert-verbose nil)
  418.  
  419. (global-set-key (kbd "<f5>") 'revert-buffer)
  420.  
  421. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  422. ;;; clipboard
  423.  
  424. (setq x-select-enable-clipboard t
  425. x-select-enable-primary nil
  426. x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)
  427. select-active-regions t)
  428.  
  429. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  430. ;;; unicode
  431.  
  432. ;; tip - use ucs-insert to insert unicode characters by name
  433.  
  434. ;; from Jonathan Arkell (http://stackoverflow.com/questions/154097/whats-in-your-emacs/154980#154980)
  435. (prefer-coding-system 'utf-8)
  436. (set-default-coding-systems 'utf-8)
  437. (set-terminal-coding-system 'utf-8)
  438. (set-keyboard-coding-system 'utf-8)
  439. (setq default-buffer-file-coding-system 'utf-8)
  440.  
  441. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  442. ;;; Daemon/Server
  443.  
  444. ;; from http://emacs-fu.blogspot.com/2009/05/getting-your-ip-address.html
  445. ;; does not work on Windows
  446. (defun get-ip-address (&optional dev)
  447. "get the IP-address for device DEV (default: eth0)"
  448. (let ((dev (if dev dev "eth0")))
  449. (format-network-address (car (network-interface-info dev)) t)))
  450.  
  451. (setq host-ip-address
  452. (or (get-ip-address "eth0")
  453. (get-ip-address "eth1")
  454. (get-ip-address "eth2")
  455. (get-ip-address "wlan0")
  456. (get-ip-address "wlan1")
  457. (get-ip-address "lo")))
  458.  
  459. ;; use network rather than local sockets
  460. ;; (setq server-use-tcp t
  461. ;; server-host host-ip-address)
  462.  
  463. ;; daemonp tests for daemon-ness, but is not available in emacs22
  464. (unless (fboundp 'daemonp)
  465. (defun daemonp () nil))
  466.  
  467. (defadvice server-start (after remove-kill-buffer-hook activate)
  468. ;; don't ask if it's OK to kill a buffer if some client has it open
  469. (remove-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function))
  470.  
  471. ;; confirm killing emacsclients
  472. ;; can't advise server-delete-client, it's used elsewhere
  473. (eval-after-load "server"
  474. '(progn
  475.  
  476. (defun server-save-buffers-kill-terminal (arg)
  477. ;; Called from save-buffers-kill-terminal in files.el.
  478. "Offer to save each buffer, then kill the current client.
  479. With ARG non-nil, silently save all file-visiting buffers, then kill.
  480.  
  481. If emacsclient was started with a list of filenames to edit, then
  482. only these files will be asked to be saved."
  483. (let ((proc (frame-parameter (selected-frame) 'client)))
  484. (cond ((eq proc 'nowait)
  485. ;; Nowait frames have no client buffer list.
  486. (if (cdr (frame-list))
  487. (progn (save-some-buffers arg)
  488. (delete-frame))
  489. ;; If we're the last frame standing, kill Emacs.
  490. (save-buffers-kill-emacs arg)))
  491. ((processp proc)
  492. (let ((buffers (process-get proc 'buffers)))
  493. ;; If client is bufferless, emulate a normal Emacs exit
  494. ;; and offer to save all buffers. Otherwise, offer to
  495. ;; save only the buffers belonging to the client.
  496. (save-some-buffers
  497. arg (if buffers
  498. (lambda () (memq (current-buffer) buffers))
  499. t))
  500. (when (y-or-n-p "Kill this emacsclient? ") ;; XXX my change
  501. (server-delete-client proc))))
  502. (t (error "Invalid client frame")))))
  503.  
  504. (defalias 'kill-emacs-server 'client-save-kill-emacs)
  505. (defun client-save-kill-emacs (&optional display)
  506. " This is a function that can bu used to shutdown save buffers and
  507. shutdown the emacs daemon. It should be called using
  508. emacsclient -e '(client-save-kill-emacs)'. This function will
  509. check to see if there are any modified buffers or active clients
  510. or frame. If so an x window will be opened and the user will
  511. be prompted."
  512. (interactive)
  513. (let (new-frame modified-buffers active-clients-or-frames)
  514.  
  515. ;; Check if there are modified buffers or active clients or frames.
  516. (setq modified-buffers (modified-buffers-exist))
  517. (setq active-clients-or-frames (or (> (length server-clients) 1)
  518. (> (length (frame-list)) 1)))
  519.  
  520. ;; Create a new frame if prompts are needed.
  521. (when (or modified-buffers active-clients-or-frames)
  522. (when (not (eq window-system 'x))
  523. (message "Initializing x windows system.")
  524. (x-initialize-window-system))
  525. (when (not display) (setq display (getenv "DISPLAY")))
  526. (message "Opening frame on display: %s" display)
  527. (select-frame (make-frame-on-display display '((window-system . x)))))
  528.  
  529. ;; Save the current frame.
  530. (setq new-frame (selected-frame))
  531.  
  532. ;; When displaying the number of clients and frames:
  533. ;; subtract 1 from the clients for this client.
  534. ;; subtract 2 from the frames this frame (that we just created) and the default frame.
  535. (when (or (not active-clients-or-frames)
  536. (yes-or-no-p
  537. (format "There are currently %d clients and %d frames. Exit anyway? "
  538. (- (length server-clients) 1)
  539. (- (length (frame-list)) 2))))
  540.  
  541. ;; If the user quits during the save dialog then don't exit emacs.
  542. ;; Still close the terminal though.
  543. (let ((inhibit-quit t))
  544. ;; Save buffers
  545. (with-local-quit
  546. (save-some-buffers))
  547.  
  548. (if quit-flag
  549. (setq quit-flag nil)
  550. ;; Kill all remaining clients
  551. (progn
  552. (dolist (client server-clients)
  553. (server-delete-client client))
  554. ;; Exit emacs
  555. (kill-emacs)))))
  556.  
  557. ;; If we made a frame then kill it.
  558. (when (or modified-buffers active-clients-or-frames)
  559. (delete-frame new-frame))))
  560.  
  561. (defun modified-buffers-exist ()
  562. "This function will check to see if there are any buffers
  563. that have been modified. It will return true if there are
  564. and nil otherwise. Buffers that have buffer-offer-save set to
  565. nil are ignored."
  566. (let (modified-found)
  567. (dolist (buffer (buffer-list))
  568. (when (and (buffer-live-p buffer)
  569. (buffer-modified-p buffer)
  570. (not (buffer-base-buffer buffer))
  571. (or (buffer-file-name buffer)
  572. (progn
  573. (set-buffer buffer)
  574. (and buffer-offer-save
  575. (> (buffer-size) 0)))))
  576. (setq modified-found t)))
  577. modified-found))
  578.  
  579. ))
  580.  
  581. (defun delete-frame-or-kill-emacs ()
  582. (interactive)
  583. (condition-case err
  584. (delete-frame)
  585. (error
  586. (if (daemonp)
  587. (if (string= "y" (downcase (read-from-minibuffer
  588. "Kill emacs (y/n)? " "n")))
  589. (save-buffers-kill-emacs)
  590. (message "Cancelled."))
  591. (save-buffers-kill-emacs)))))
  592. (global-set-key (kbd "C-x C-c") 'delete-frame-or-kill-emacs)
  593.  
  594. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  595. ;;; Web Browser
  596. (defcustom browse-url-opera-arguments '()
  597. "A list of strings passed to the Opera browser as arguments."
  598. :version "21.1"
  599. :type '(repeat (string :tag "Argument"))
  600. :group 'browse-url)
  601.  
  602. (defun browse-url-opera (url &optional new-window)
  603. "Ask Opera to load URL. Default to the URL around or before
  604. point. The strings in variable `browse-url-opera-arguments'
  605. are also passed.
  606.  
  607. When called interactively, if variable `browse-url-new-window-flag' is
  608. non-nil, load the document in a new browser window, otherwise use an
  609. existing one. A non-nil interactive prefix argument reverses the
  610. effect of `browse-url-new-window-flag'.
  611.  
  612. When called non-interactively, optional second argument NEW-WINDOW is
  613. used instead of `browse-url-new-window-flag'."
  614. (interactive (browse-url-interactive-arg "URL: "))
  615. (apply 'start-process (concat "opera " url)
  616. nil
  617. "opera"
  618. (append
  619. browse-url-gnome-moz-arguments
  620. (if (browse-url-maybe-new-window new-window)
  621. '("-newwindow"))
  622. (list url))))
  623.  
  624. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  625. ;;; auto-complete
  626. ;; TAB completion with a nice UI
  627.  
  628. (add-to-list 'load-path (concat user-emacs-directory "auto-complete"))
  629. (with-library 'auto-complete-config
  630. (ac-config-default)
  631. (add-to-list 'ac-dictionary-directories
  632. (concat user-emacs-directory "auto-complete/dict")))
  633.  
  634. (eval-after-load "auto-complete"
  635. '(progn
  636.  
  637. ;; make expanding work when moving forwards or backwards through
  638. ;; the candidate list
  639. (defun ac-expand-1 (forward?)
  640. "Main implementation of `ac-expand' and `ac-expand-previous'."
  641. (interactive)
  642. (unless (ac-expand-common)
  643. (let ((string (ac-selected-candidate)))
  644. (when string
  645. (when (equal ac-prefix string)
  646. (if forward?
  647. (ac-next)
  648. (ac-previous))
  649. (setq string (ac-selected-candidate)))
  650. (ac-expand-string string t) (or (eq last-command 'ac-expand)
  651. (eq last-command 'ac-expand-previous)))
  652. ;; Do reposition if menu at long line
  653. (if (and (> (popup-direction ac-menu) 0)
  654. (ac-menu-at-wrapper-line-p))
  655. (ac-reposition))
  656. (setq ac-show-menu t)
  657. string)))
  658.  
  659. (defun ac-expand ()
  660. "Try expand, and if expanded twice, select next candidate."
  661. (interactive)
  662. (ac-expand-1 t))
  663.  
  664. (defun ac-expand-previous ()
  665. "Try expand, and if expanded twice, select previous candidate."
  666. (interactive)
  667. (ac-expand-1 nil))
  668.  
  669. ;; redefine this so it doesn't expand on C++ comments
  670. (defun ac-prefix-valid-file ()
  671. "Existed (or to be existed) file prefix."
  672. (let* ((line-beg (line-beginning-position))
  673. (end (point))
  674. (start (or (let ((point (re-search-backward "[\"<>'= \t\r\n]" line-beg t)))
  675. (if point (1+ point)))
  676. line-beg))
  677. (file (buffer-substring start end)))
  678. (when (and file
  679. (not (string-match "//+" file)) ;; C++ comments
  680. (or (string-match "^/" file)
  681. (and (setq file (and (string-match "^[^/]*/" file)
  682. (match-string 0 file)))
  683. (file-directory-p file))))
  684. start)))
  685.  
  686. ;; ;; extra sources
  687. ;; (with-library 'ac-dabbrev
  688. ;; (add-to-list 'ac-sources 'ac-source-dabbrev))
  689. ;; (setq-default ac-sources ac-sources)
  690.  
  691. ;; keybinds
  692. (define-key ac-complete-mode-map (kbd "C-n") 'ac-next)
  693. (define-key ac-complete-mode-map (kbd "C-p") 'ac-previous)
  694. (define-key ac-complete-mode-map (kbd "M-k") 'ac-next)
  695. (define-key ac-complete-mode-map (kbd "M-i") 'ac-previous)
  696. (define-key ac-complete-mode-map (kbd "<backtab>") 'ac-expand-previous)
  697. ;; (define-key ac-complete-mode-map (kbd "<backtab>") 'ac-previous)
  698. ;; (define-key ac-complete-mode-map (kbd "<tab>") 'ac-next)
  699. ;; (define-key ac-complete-mode-map (kbd "M-/") 'ac-expand)
  700.  
  701. ;; workaround for flyspell-mode
  702. (ac-flyspell-workaround)
  703. ))
  704.  
  705. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  706. ;;; Flyspell
  707.  
  708. (eval-after-load "flyspell"
  709. '(define-key flyspell-mode-map (kbd "M-TAB") nil))
  710.  
  711. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  712. ;;; Remember.el remembers things
  713. (add-to-list 'load-path (concat user-emacs-directory "remember-2.0/"))
  714. (autoload 'remember "remember.el" nil t)
  715.  
  716. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  717. ;;; Bookmarks
  718.  
  719. ;; bm.el is a visible bookmark package. Bookmarks are indicated with
  720. ;; highlighting in the text and/or the fringe. They are optionally
  721. ;; (per-buffer) persistent.
  722. (autoload 'bm-toggle "bm" "Toggle bookmark in current buffer." t)
  723. (autoload 'bm-next "bm" "Goto next bookmark." t)
  724. (autoload 'bm-previous "bm" "Goto previous bookmark." t)
  725. (autoload 'bm-toggle-mouse "bm" "Toggle bookmark with mouse." t)
  726. (autoload 'bm-next-mouse "bm" "Goto next bookmark with mouse." t)
  727. (autoload 'bm-previous-mouse "bm" "Goto previous bookmark with mouse." t)
  728.  
  729. (setq bm-marker 'bm-marker-right)
  730.  
  731. (global-set-key (kbd "C-c m m") 'bm-toggle)
  732. (global-set-key (kbd "C-c m n") 'bm-next)
  733. (global-set-key (kbd "C-c m p") 'bm-previous)
  734.  
  735. (global-set-key (kbd "<right-fringe> <mouse-5>") 'bm-next-mouse)
  736. (global-set-key (kbd "<right-fringe> <mouse-4>") 'bm-previous-mouse)
  737. (global-set-key (kbd "<right-fringe> <mouse-1>") 'bm-toggle-mouse)
  738.  
  739. ;; breadcrumb.el is similar to bm.el, but global across all buffers
  740. ;; and without the visual indicators. Also, provides an interactive
  741. ;; buffer for showing all breadcrumbs.
  742. (dolist (func '(bc-set bc-previous bc-next bc-local-previous bc-local-next
  743. bc-goto-current bc-list bc-clear))
  744. (autoload func "breadcrumb.el" "Breadcrumbs for Emacs." t))
  745. ;; bindings are via 123-menu
  746.  
  747. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  748. ;; re-builder
  749.  
  750. (setq reb-re-syntax 'string)
  751.  
  752. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  753. ;;; hide-lines
  754.  
  755. (autoload 'hide-non-matching-lines "hide-lines"
  756. "Hide all lines not matching a regexp." t)
  757. (autoload 'hide-matching-lines "hide-lines"
  758. "Hide all lines matching a regexp." t)
  759. (autoload 'show-all-invisible "hide-lines"
  760. "Show all lines hidden by hide-lines." t)
  761.  
  762. (global-set-key (kbd "C-c s a") 'show-all-invisible)
  763. (global-set-key (kbd "C-c s s") 'hide-non-matching-lines)
  764. (global-set-key (kbd "C-c s d") 'hide-matching-lines)
  765.  
  766. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  767. ;;; Hideshow (code folding)
  768.  
  769. (autoload 'hideshowvis-minor-mode "hideshowvis.el"
  770. "Code folding indicators in the left fringe." t)
  771.  
  772. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  773. ;;; ido - Interactive Do
  774.  
  775. (ido-mode 'both) ;; both buffers and files
  776. (ido-everywhere t)
  777.  
  778. (setq ido-confirm-unique-completion t)
  779. (setq ido-default-buffer-method 'selected-window)
  780. (setq ido-default-file-method 'selected-window)
  781. (setq ido-enable-flex-matching t)
  782. (setq ido-ignore-buffers '("\\` " "^\\*Completion" "^\\*Ido"))
  783. (setq ido-max-work-file-list 50)
  784. (setq ido-rotate-file-list-default nil)
  785. (setq ido-save-directory-list-file "~/.emacs.d/.ido.last")
  786. (setq ido-show-dot-for-dired t)
  787. (setq ido-work-directory-match-only nil)
  788.  
  789. (defun jpk/ido-setup-hook ()
  790. (define-key ido-completion-map [remap backward-kill-word] nil)
  791. (define-key ido-completion-map (kbd "<C-backspace>") 'backward-kill-word)
  792. (define-key (cdr (assoc 'ido-mode minor-mode-map-alist)) ;; ido-mode-map
  793. [remap write-file] nil)
  794. )
  795. (add-hook 'ido-setup-hook 'jpk/ido-setup-hook)
  796.  
  797. (defun jpk/ido-minibuffer-setup-hook ()
  798. ;; disallow wrapping of the minibuffer
  799. (make-local-variable 'truncate-lines)
  800. (setq truncate-lines t))
  801. (add-hook 'ido-minibuffer-setup-hook 'jpk/ido-minibuffer-setup-hook)
  802.  
  803. (defvar ido-enable-replace-completing-read t
  804. "If t, use ido-completing-read instead of completing-read if possible.
  805.  
  806. Set it to nil using let in around-advice for functions where the
  807. original completing-read is required. For example, if a function
  808. foo absolutely must use the original completing-read, define some
  809. advice like this:
  810.  
  811. (defadvice foo (around original-completing-read-only activate)
  812. (let (ido-enable-replace-completing-read) ad-do-it))")
  813.  
  814. ;; ido completion on just about everything
  815. (defadvice completing-read (around use-ido-when-possible activate)
  816. (if (or (not ido-enable-replace-completing-read) ;; Manual override disable ido
  817. (and (boundp 'ido-completing-read) ido-completing-read))
  818. ad-do-it
  819. (let ((allcomp (all-completions "" collection predicate))
  820. (ido-enable-replace-completing-read nil)) ;; prevent recursion
  821. (if allcomp
  822. (setq ad-return-value
  823. (ido-completing-read prompt
  824. allcomp
  825. nil require-match initial-input hist def))
  826. ad-do-it))))
  827.  
  828. ;; I can't seem to disable ido unless I actually modify the function
  829. ;; definition.
  830. (defun write-file (filename &optional confirm)
  831. "Write current buffer into file FILENAME.
  832. This makes the buffer visit that file, and marks it as not modified.
  833.  
  834. If you specify just a directory name as FILENAME, that means to use
  835. the default file name but in that directory. You can also yank
  836. the default file name into the minibuffer to edit it, using \\<minibuffer-local-map>\\[next-history-element].
  837.  
  838. If the buffer is not already visiting a file, the default file name
  839. for the output file is the buffer name.
  840.  
  841. If optional second arg CONFIRM is non-nil, this function
  842. asks for confirmation before overwriting an existing file.
  843. Interactively, confirmation is required unless you supply a prefix argument.
  844.  
  845. This has been modified to disable ido."
  846. ;; (interactive "FWrite file: ")
  847. (interactive
  848. (let ((read-file-name-function nil)
  849. (ido-enable-replace-completing-read nil))
  850. (list (if buffer-file-name
  851. (read-file-name "Write file: "
  852. nil nil nil nil)
  853. (read-file-name "Write file: " default-directory
  854. (expand-file-name
  855. (file-name-nondirectory (buffer-name))
  856. default-directory)
  857. nil nil))
  858. (not current-prefix-arg))))
  859. (or (null filename) (string-equal filename "")
  860. (progn
  861. ;; If arg is just a directory,
  862. ;; use the default file name, but in that directory.
  863. (if (file-directory-p filename)
  864. (setq filename (concat (file-name-as-directory filename)
  865. (file-name-nondirectory
  866. (or buffer-file-name (buffer-name))))))
  867. (and confirm
  868. (file-exists-p filename)
  869. (or (y-or-n-p (format "File `%s' exists; overwrite? " filename))
  870. (error "Canceled")))
  871. (set-visited-file-name filename (not confirm))))
  872. (set-buffer-modified-p t)
  873. ;; Make buffer writable if file is writable.
  874. (and buffer-file-name
  875. (file-writable-p buffer-file-name)
  876. (setq buffer-read-only nil))
  877. (save-buffer)
  878. ;; It's likely that the VC status at the new location is different from
  879. ;; the one at the old location.
  880. (vc-find-file-hook))
  881.  
  882. (defun insert-filename-or-buffername ()
  883. "If the buffer has a file, insert the base name of that file.
  884. Otherwise insert the buffer name."
  885. (interactive)
  886. (let* ((buffer (window-buffer (minibuffer-selected-window)))
  887. (file-path-maybe (buffer-file-name buffer)))
  888. (insert (if file-path-maybe
  889. (file-name-nondirectory file-path-maybe)
  890. (buffer-name buffer)))))
  891.  
  892. (define-key minibuffer-local-map (kbd "C-c f") 'insert-filename-or-buffername)
  893.  
  894. (defun smex-update-after-load (unused)
  895. (when (boundp 'smex-cache)
  896. (smex-update)))
  897.  
  898. ;; ido for M-x
  899. ;; minibuffer-complete-cycle is also nice, but this is better
  900. (with-library 'smex
  901. (add-hook 'after-init-hook 'smex-initialize)
  902. (add-hook 'after-load-functions 'smex-update-after-load)
  903. (global-set-key (kbd "M-x") 'smex)
  904. (global-set-key (kbd "M-X") 'smex-major-mode-commands)
  905. (global-set-key (kbd "C-c M-x") 'execute-extended-command))
  906.  
  907. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  908. ;;; TAGS
  909.  
  910. (with-library 'etags
  911.  
  912. (setq ctags-executable "ctags-exuberant")
  913.  
  914. (defun create-tags (dir)
  915. "Create a tags file in directory DIR."
  916. (interactive "DDirectory: ")
  917. (shell-command
  918. (format "%s -f %s/TAGS -e -R %s"
  919. ctags-executable dir (directory-file-name dir))))
  920.  
  921. (with-library 'etags-select
  922. (global-set-key (kbd "M-?") 'etags-select-find-tag-at-point)
  923. (global-set-key (kbd "M-.") 'etags-select-find-tag))
  924. )
  925.  
  926. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  927. ;;; Backup
  928. (setq make-backup-files t
  929. vc-make-backup-files t
  930. version-control t
  931. kept-new-versions 16
  932. kept-old-versions 2
  933. delete-old-versions t
  934. backup-by-copying t)
  935. (setq backup-dir (concat user-emacs-directory "backup/"))
  936. (if (not (file-exists-p backup-dir))
  937. (make-directory backup-dir))
  938. (add-to-list 'backup-directory-alist
  939. `("." . ,backup-dir))
  940. (defun force-backup-of-buffer ()
  941. (setq buffer-backed-up nil))
  942. (add-hook 'before-save-hook 'force-backup-of-buffer)
  943. ;; this is what tramp uses
  944. (setq tramp-backup-directory-alist backup-directory-alist)
  945.  
  946. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  947. ;;; Autosave
  948.  
  949. (setq autosave-dir (concat user-emacs-directory "autosaves/"))
  950. (if (not (file-exists-p autosave-dir))
  951. (make-directory autosave-dir))
  952. (add-to-list 'auto-save-file-name-transforms
  953. `("\\`/?\\([^/]*/\\)*\\([^/]*\\)\\'" ,(concat autosave-dir "\\2") t))
  954. ;; tramp autosaves
  955. (setq tramp-auto-save-directory (concat user-emacs-directory "tramp-autosaves/"))
  956. (if (not (file-exists-p tramp-auto-save-directory))
  957. (make-directory tramp-auto-save-directory))
  958.  
  959. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  960. ;;; save-visited-files
  961.  
  962. ;; Saves a list of the open files (via auto-save-hook), which can be
  963. ;; restored with save-visited-files-restore.
  964. (autoload 'save-visited-files-mode "save-visited-files"
  965. "Periodically saves a list of open files" t)
  966.  
  967. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  968. ;;; recentf (recently visited files)
  969.  
  970. (setq recentf-save-file (concat user-emacs-directory ".recentf"))
  971. (recentf-mode 1)
  972.  
  973. (defun ido-recentf-open ()
  974. "Use `ido-completing-read' to \\[find-file] a recent file"
  975. (interactive)
  976. (if (find-file (ido-completing-read "Find recent file: " recentf-list))
  977. (message "Opening file...")
  978. (message "Aborting")))
  979.  
  980. (defun undo-kill-buffer (arg)
  981. "Re-open the last buffer killed. With ARG, re-open the nth buffer."
  982. (interactive "p")
  983. (let ((recently-killed-list (copy-sequence recentf-list))
  984. (buffer-files-list
  985. (delq nil (mapcar (lambda (buf)
  986. (when (buffer-file-name buf)
  987. (expand-file-name (buffer-file-name buf))))
  988. (buffer-list)))))
  989. (mapc
  990. (lambda (buf-file)
  991. (setq recently-killed-list
  992. (delq buf-file recently-killed-list)))
  993. buffer-files-list)
  994. (find-file
  995. (if arg (nth arg recently-killed-list)
  996. (car recently-killed-list)))))
  997.  
  998. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  999. ;;; Title and Modeline
  1000.  
  1001. ;; frame title
  1002. (setq-default frame-title-format
  1003. '(:eval
  1004. (format "%s@%s: %s %s"
  1005. (or (file-remote-p default-directory 'user)
  1006. user-real-login-name)
  1007. (or (file-remote-p default-directory 'host)
  1008. system-name)
  1009. (buffer-name)
  1010. (cond
  1011. (buffer-file-truename
  1012. (concat "(" buffer-file-truename ")"))
  1013. (dired-directory
  1014. (concat "{" dired-directory "}"))
  1015. (t
  1016. "[no file]")))))
  1017.  
  1018. (global-set-key (kbd "<mode-line> <mouse-2>") 'mouse-delete-window)
  1019. (global-set-key (kbd "<mode-line> <mouse-3>") 'mode-line-next-buffer)
  1020.  
  1021. (require 'modeline-posn nil 'noerror)
  1022.  
  1023. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1024. ;;; TRAMP
  1025.  
  1026. (defface find-file-root-header-face
  1027. '((t (:foreground "white" :background "red3")))
  1028. "*Face use to display header-lines for files opened as root.")
  1029.  
  1030. (defun find-file-root-header-warning ()
  1031. "*Display a warning in header line of the current buffer.
  1032. This function is suitable to add to `find-file-hook'."
  1033. (when (string-equal
  1034. (file-remote-p (or buffer-file-name default-directory) 'user)
  1035. "root")
  1036. (let* ((warning "WARNING: EDITING FILE AS ROOT!")
  1037. (space (+ 6 (- (window-width) (length warning))))
  1038. (bracket (make-string (/ space 2) ?-))
  1039. (warning (concat bracket warning bracket)))
  1040. (setq header-line-format
  1041. (propertize warning 'face 'find-file-root-header-face)))))
  1042.  
  1043. (defun find-alternative-file-with-sudo ()
  1044. (interactive)
  1045. (let ((bname (expand-file-name (or buffer-file-name
  1046. default-directory)))
  1047. (pt (point)))
  1048. (setq bname (or (file-remote-p bname 'localname)
  1049. (concat "/sudo::" bname)))
  1050. ;; FIXME mostly works around, but not quite
  1051. (flet ((server-buffer-done
  1052. (buffer &optional for-killing)
  1053. nil))
  1054. (find-alternate-file bname))
  1055. (goto-char pt)))
  1056.  
  1057. ;; normally this is bound to find-file-read-only
  1058. ;; use M-x toggle-read-only instead
  1059. (global-set-key (kbd "C-x C-r") 'find-alternative-file-with-sudo)
  1060.  
  1061. (add-hook 'find-file-hook 'find-file-root-header-warning)
  1062. (add-hook 'dired-mode-hook 'find-file-root-header-warning)
  1063.  
  1064. ;; Basically what this does is connect through ssh and then sudo on
  1065. ;; the remote machine (except localhost). You can use
  1066. ;; "/sudo:remote-host:/path/to/file" to open a remote file as root.
  1067. (eval-after-load "tramp"
  1068. '(progn
  1069. (add-to-list 'tramp-default-proxies-alist
  1070. '(nil "\\`root\\'" "/ssh:%h:"))
  1071. (add-to-list 'tramp-default-proxies-alist
  1072. '((regexp-quote (system-name)) nil nil))
  1073. ))
  1074.  
  1075. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1076. ;;; Mouse
  1077. (with-library 'mouse+
  1078. (global-set-key (kbd "<down-mouse-2>") 'mouse-flash-position)
  1079. (global-set-key (kbd "S-<down-mouse-2>") 'mouse-scan-lines))
  1080.  
  1081. ;; move mouse pointer away when the cursor gets near
  1082. (mouse-avoidance-mode 'cat-and-mouse)
  1083.  
  1084. ;; it's really annoying when the frame raises by itself
  1085. (defadvice mouse-avoidance-set-mouse-position (around disable-raise activate)
  1086. (flet ((raise-frame (&optional frame) t))
  1087. ad-do-it))
  1088.  
  1089. (global-set-key (kbd "<mouse-2>") 'mouse-yank-primary)
  1090.  
  1091. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1092. ;;; Windows
  1093.  
  1094. ;; automatically save window configurations and cycle through them
  1095. (with-library 'window-config-history
  1096. (window-config-history-mode 1))
  1097.  
  1098. (defun split-windows-in-quarters (arg)
  1099. "Configure a frame to have 4 similarly sized windows. Splits
  1100. the selected window with prefix arg."
  1101. (interactive "P")
  1102. (when (not arg)
  1103. (delete-other-windows))
  1104. (let ((this-window (selected-window)))
  1105. (split-window-horizontally)
  1106. (other-window 1)
  1107. (split-window-vertically)
  1108. (select-window this-window)
  1109. (split-window-vertically)))
  1110.  
  1111. ;; default bindings are too long, make single keystrokes
  1112. (defun previous-window ()
  1113. (interactive)
  1114. (other-window -1))
  1115. (global-set-key (kbd "M-1") 'previous-window)
  1116. (global-set-key (kbd "C-x O") 'previous-window)
  1117. (global-set-key (kbd "M-2") 'other-window)
  1118. ;; default is the unwieldy C-x 4 C-o
  1119. (global-set-key (kbd "<f6>") 'display-buffer)
  1120.  
  1121. ;; default is C-x <left> and C-x <right>
  1122. (global-set-key (kbd "M-<up>") 'previous-buffer)
  1123. (global-set-key (kbd "M-<down>") 'next-buffer)
  1124. (global-set-key (kbd "C-M-1") 'previous-buffer)
  1125. (global-set-key (kbd "C-M-2") 'next-buffer)
  1126.  
  1127. (dolist (func '(buf-move-up
  1128. buf-move-down
  1129. buf-move-left
  1130. buf-move-right))
  1131. (autoload func "buffer-move.el"
  1132. "Move buffers to different windows." t))
  1133.  
  1134. ;; Save point position per-window instead of per-buffer.
  1135. (with-library 'winpoint
  1136. (winpoint-mode 1))
  1137.  
  1138. ;; I hate it when my windows get deleted.
  1139. (defvar confirm-delete-window nil
  1140. "Ask the user before deleting a window. This is used in
  1141. around-advice for delete-window.")
  1142. (defvar never-delete-window nil
  1143. "Never allow windows to be deleted. This is used in
  1144. around-advice for delete-window.")
  1145.  
  1146. (defadvice delete-window (around confirm activate)
  1147. (if (and (not never-delete-window)
  1148. (if confirm-delete-window
  1149. (y-or-n-p "Delete window? ")
  1150. t))
  1151. ad-do-it
  1152. ;; delete-window raises an error if the window shouldn't be
  1153. ;; deleted
  1154. (error "Not deleting window")))
  1155.  
  1156. (defadvice delete-windows-on (around confirm activate)
  1157. (if (and (not never-delete-window)
  1158. (if confirm-delete-window
  1159. (y-or-n-p "Delete window? ")
  1160. t))
  1161. ad-do-it
  1162. ;; delete-windows-on switches to other-buffer if the window
  1163. ;; shouldn't be deleted
  1164. (switch-to-buffer (other-buffer))))
  1165.  
  1166. ;; prevent these functions from killing the selected window
  1167. (defadvice-list
  1168. '(finder-exit View-quit log-edit-done
  1169. vc-revert vc-rollback)
  1170. 'before 'no-window-delete
  1171. '(lambda ()
  1172. (let ((never-delete-window t))
  1173. 'ad-do-it)))
  1174.  
  1175. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1176. ;;; VC mode
  1177.  
  1178. (defvar hg-graphlog-re "^[\\\\|/o@ +-]*"
  1179. "Matches the junk Mercurial's graphlog extension puts at the
  1180. beginning of the line")
  1181.  
  1182. (defun jpk/vc-hg-log-view-mode-hook ()
  1183. (visual-line-mode 1)
  1184. ;; ignore graphlog stuff
  1185. (setq log-view-message-re
  1186. (replace-regexp-in-string "^\\^" hg-graphlog-re
  1187. log-view-message-re)))
  1188.  
  1189. (add-hook 'vc-hg-log-view-mode-hook 'jpk/vc-hg-log-view-mode-hook)
  1190.  
  1191. (eval-after-load "vc-hg"
  1192. '(progn
  1193. ;; graphlog
  1194. (add-to-list 'vc-hg-log-switches "-G")
  1195.  
  1196. (font-lock-add-keywords
  1197. 'vc-hg-log-view-mode
  1198. `((,(concat hg-graphlog-re "files:[ \t]+\\(.+\\)")
  1199. (1 'change-log-file))
  1200. (,(concat hg-graphlog-re "\\(description:\\)[ \t]+\\(.+\\)")
  1201. (1 'log-view-message)
  1202. (2 'log-view-message))
  1203. (,(concat hg-graphlog-re "user:[ \t]+\\(.+\\)")
  1204. (1 'change-log-name))
  1205. (,(concat hg-graphlog-re "date:[ \t]+\\(.+\\)")
  1206. (1 'change-log-date)))
  1207. 'set)
  1208. ))
  1209.  
  1210. (eval-after-load "vc-dir"
  1211. '(progn
  1212.  
  1213. (defun vc-dir-toggle ()
  1214. (interactive)
  1215. (let (line col)
  1216. (setq line (line-number-at-pos))
  1217. ;; This automatically moves to the next line, but that isn't
  1218. ;; as useful for toggling (I think), so we work around it.
  1219. (vc-dir-mark-unmark 'vc-dir-toggle-mark-file)
  1220. (setq col (current-column))
  1221. (goto-line line)
  1222. (move-to-column col)))
  1223. (define-key vc-dir-mode-map
  1224. (kbd "SPC") 'vc-dir-toggle)
  1225.  
  1226. ;; incoming/outgoing
  1227. (defun vc-hg-outgoing ()
  1228. (interactive)
  1229. (let ((bname "*Hg outgoing*"))
  1230. (vc-hg-command bname nil nil "outgoing" "-n")
  1231. (switch-to-buffer bname)
  1232. (vc-hg-outgoing-mode)))
  1233. (defun vc-hg-incoming ()
  1234. (interactive)
  1235. (let ((bname "*Hg incoming*"))
  1236. (vc-hg-command bname nil nil "incoming" "-n")
  1237. (switch-to-buffer bname)
  1238. (vc-hg-incoming-mode)))
  1239. (global-set-key (kbd "C-x v I") 'vc-hg-incoming)
  1240. (global-set-key (kbd "C-x v O") 'vc-hg-outgoing)
  1241. (add-hook 'vc-hg-log-view-mode-hook (lambda () (toggle-read-only 1)))
  1242. (define-key vc-hg-log-view-mode-map
  1243. (kbd "q") (lambda () (interactive) (kill-buffer (buffer-name))))
  1244.  
  1245. ))
  1246.  
  1247. (setq vc-log-short-style nil)
  1248.  
  1249. ;; annotate (blame) customizations: I don't like the default (the date
  1250. ;; is too verbose and there's no user name).
  1251.  
  1252. (defconst vc-hg-annotate-re
  1253. "^[ \t]*[[:alnum:]]+ \\([0-9]+\\) \\(.\\{10\\}\\)\\(?:\\(: \\)\\|\\(?: +\\(.+\\): \\)\\)")
  1254.  
  1255. (defun vc-hg-annotate-command (file buffer &optional revision)
  1256. "Execute \"hg annotate\" on FILE, inserting the contents in BUFFER.
  1257. Optional arg REVISION is a revision to annotate from."
  1258. (vc-hg-command buffer 0 file "annotate" "-d" "-q" "-u" "-n"
  1259. (when revision (concat "-r" revision))))
  1260.  
  1261. (defun vc-hg-annotate-time ()
  1262. (when (looking-at vc-hg-annotate-re)
  1263. (goto-char (match-end 0))
  1264. (vc-annotate-convert-time
  1265. (date-to-time (concat (match-string-no-properties 2) " 00:00:00")))))
  1266.  
  1267. ;; TODO: submit patch for graphlog stuff
  1268. (defun vc-hg-print-log (files buffer &optional shortlog start-revision limit)
  1269. "Get change log associated with FILES."
  1270. ;; `vc-do-command' creates the buffer, but we need it before running
  1271. ;; the command.
  1272. (vc-setup-buffer buffer)
  1273. ;; If the buffer exists from a previous invocation it might be
  1274. ;; read-only.
  1275. (let ((inhibit-read-only t))
  1276. (with-current-buffer
  1277. buffer
  1278. (apply 'vc-hg-command buffer 0 files "log"
  1279. (append
  1280. (when start-revision (list (format "-r%s" start-revision)))
  1281. (when limit (list "-l" (format "%s" limit)))
  1282. (when shortlog '("--style" "compact"))
  1283. vc-hg-log-switches)))))
  1284.  
  1285. ;; toggle-read-only prints an annoying message
  1286. (defadvice toggle-read-only (around suppress-vc-message activate)
  1287. (with-temp-message ""
  1288. ad-do-it))
  1289.  
  1290. ;; TODO
  1291. ;;
  1292. ;; vc-revert bug
  1293.  
  1294. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1295. ;;; diff
  1296.  
  1297. (autoload 'commit-patch-buffer "commit-patch-buffer.el"
  1298. "Use diff-mode buffers as commits for VC." t)
  1299.  
  1300. (defun jpk/diff-mode-hook ()
  1301. (local-set-key (kbd "C-c C-k") 'diff-hunk-kill)
  1302. (local-set-key (kbd "C-c C-S-k") 'diff-file-kill)
  1303. (local-set-key (kbd "C-c C-c") 'commit-patch-buffer)
  1304. (local-set-key (kbd "C-c C-j") 'diff-add-trailing-CR-in-hunk)
  1305. (local-set-key (kbd "C-c C-o") 'diff-goto-source))
  1306.  
  1307. (add-hook 'diff-mode-hook 'jpk/diff-mode-hook)
  1308.  
  1309. ;; don't bother me about previously manipulated hunks
  1310. (defvar ediff-copy-diff-silent t
  1311. "Do not ask if a previously copied hunk should be changed.")
  1312. (defadvice ediff-test-save-region (around always-true activate)
  1313. (if ediff-copy-diff-silent
  1314. (flet ((yes-or-no-p (prompt) t))
  1315. ad-do-it)
  1316. ad-do-it))
  1317.  
  1318. ;;;;;;;;;;;;;;;;;;;;;;;;
  1319. ;; commit-patch-buffer is very picky about the patch buffer.
  1320. ;; Apparently, it needs the line endings to match the original file,
  1321. ;; but the diff metadata needs unix line endings.
  1322. ;;
  1323. ;; TODO
  1324. ;;
  1325. ;; make diff-add-trailing-CR-in-hunk more fool-proof and use it to
  1326. ;; operate on the whole diff buffer
  1327.  
  1328. (defun insert-CR-eol (b e)
  1329. (interactive "r")
  1330. (replace-regexp "\\([^
  1331. ]\\)$" "\\1
  1332. " nil b e))
  1333.  
  1334. (defun diff-add-trailing-CR-in-hunk ()
  1335. "Add trailing carriage returns in the current hunk."
  1336. (interactive)
  1337. (save-excursion
  1338. (diff-beginning-of-hunk)
  1339. (when (diff-unified-hunk-p)
  1340. (forward-line 1))
  1341. (let* ((start (point))
  1342. ;; Search the second match, since we're looking at the first.
  1343. (nexthunk (when (re-search-forward diff-hunk-header-re nil t 2)
  1344. (match-beginning 0)))
  1345. (firsthunk (ignore-errors
  1346. (goto-char start)
  1347. (diff-beginning-of-file) (diff-hunk-next) (point)))
  1348. (nextfile (ignore-errors (diff-file-next) (point)))
  1349. (inhibit-read-only t))
  1350. (goto-char start)
  1351. (diff-end-of-hunk)
  1352. (when (eobp)
  1353. (forward-line -1)
  1354. (end-of-line))
  1355. (insert-CR-eol start (point)))))
  1356.  
  1357. ;;;;;;;;;;;;;;;;;;;;;;;;
  1358.  
  1359. ;; Skip over whitespace-only differences in ediff mode. Still finds
  1360. ;; such regions, only changes navigation. Toggle with # # in ediff
  1361. ;; mode.
  1362. (setq-default ediff-ignore-similar-regions t)
  1363.  
  1364. (defun ediff-regions-linewise-this-buffer ()
  1365. (interactive)
  1366. (ediff-regions-linewise (buffer-name) (buffer-name)))
  1367.  
  1368. (defun ediff-regions-wordwise-this-buffer ()
  1369. (interactive)
  1370. (ediff-regions-wordwise (buffer-name) (buffer-name)))
  1371.  
  1372. ;;;;;;;;;;;;;;;;;;;;;;;;
  1373. ;; binary diff with hexl-mode
  1374. ;; http://trey-jackson.blogspot.com/2010/10/emacs-tip-38-automatically-diff-binary.html
  1375.  
  1376. (defvar ediff-do-hexl-diff nil
  1377. "variable used to store trigger for doing diff in hexl-mode")
  1378. (defadvice ediff-files-internal (around ediff-files-internal-for-binary-files activate)
  1379. "catch the condition when the binary files differ
  1380.  
  1381. the reason for catching the error out here (when re-thrown from the inner advice)
  1382. is to let the stack continue to unwind before we start the new diff
  1383. otherwise some code in the middle of the stack expects some output that
  1384. isn't there and triggers an error"
  1385. (let ((file-A (ad-get-arg 0))
  1386. (file-B (ad-get-arg 1))
  1387. ediff-do-hexl-diff)
  1388. (condition-case err
  1389. (progn
  1390. ad-do-it)
  1391. (error
  1392. (if ediff-do-hexl-diff
  1393. (let ((buf-A (find-file-noselect file-A))
  1394. (buf-B (find-file-noselect file-B)))
  1395. (with-current-buffer buf-A
  1396. (hexl-mode 1))
  1397. (with-current-buffer buf-B
  1398. (hexl-mode 1))
  1399. (ediff-buffers buf-A buf-B))
  1400. (error (error-message-string err)))))))
  1401.  
  1402. (defadvice ediff-setup-diff-regions (around ediff-setup-diff-regions-for-binary-files activate)
  1403. "when binary files differ, set the variable "
  1404. (condition-case err
  1405. (progn
  1406. ad-do-it)
  1407. (error
  1408. (setq ediff-do-hexl-diff
  1409. (and (string-match-p "^Errors in diff output. Diff output is in.*"
  1410. (error-message-string err))
  1411. (string-match-p "^\\(Binary \\)?[fF]iles .* and .* differ"
  1412. (buffer-substring-no-properties
  1413. (line-beginning-position)
  1414. (line-end-position)))
  1415. (y-or-n-p "The binary files differ, look at the differences in hexl-mode? ")))
  1416. (error (error-message-string err)))))
  1417.  
  1418. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1419. ;;; Comint - command interpreter
  1420.  
  1421. (defvar comint-eob-on-send t
  1422. "Like comint-eol-on-send, but moves to the end of buffer.")
  1423. (defadvice comint-send-input
  1424. (before move-to-end-of-buffer activate)
  1425. (when comint-eob-on-send
  1426. (goto-char (point-max))))
  1427.  
  1428. ;; used for interactive terminals
  1429. (eval-after-load "comint"
  1430. '(progn
  1431. (define-key comint-mode-map
  1432. (kbd "<up>") 'comint-previous-matching-input-from-input)
  1433. (define-key comint-mode-map
  1434. (kbd "<down>") 'comint-next-matching-input-from-input)
  1435. ))
  1436.  
  1437. (autoload 'ansi-color-for-comint-mode-on "ansi-color")
  1438.  
  1439. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1440. ;;; Terminals
  1441.  
  1442. ;; multi-term is much better than shell, eshell, term, or ansi-term
  1443. (dolist
  1444. (func '(multi-term
  1445. multi-term-prev
  1446. multi-term-shell))
  1447. (autoload func "multi-term.el"
  1448. "Package for creating and managing multiple terminal buffers" t))
  1449.  
  1450. (defun multi-term-shell (shell)
  1451. "Programmatically start a terminal with a non-default program."
  1452. (let ((multi-term-program shell))
  1453. (multi-term)))
  1454.  
  1455. (eval-after-load "multi-term"
  1456. '(progn
  1457. (defun term-send-quote ()
  1458. (interactive)
  1459. (term-send-raw-string "\C-v"))
  1460.  
  1461. (defun term-send-M-x ()
  1462. (interactive)
  1463. (term-send-raw-string "\ex"))
  1464.  
  1465. ;; These use strings like "\e0A" by default, and it's
  1466. ;; questionable which is better. IPython likes the '[' versions
  1467. ;; better, but most other things like the '0' version.
  1468. ;; (defun term-send-up () (interactive) (term-send-raw-string "\e[A"))
  1469. ;; (defun term-send-down () (interactive) (term-send-raw-string "\e[B"))
  1470. ;; (defun term-send-right () (interactive) (term-send-raw-string "\e[C"))
  1471. ;; (defun term-send-left () (interactive) (term-send-raw-string "\e[D"))
  1472.  
  1473. (defun term-send-backward-kill-word ()
  1474. (interactive)
  1475. (term-send-raw-string "\C-H"))
  1476.  
  1477. (dolist
  1478. (bind '(("C-<right>" . term-send-forward-word)
  1479. ("C-<left>" . term-send-backward-word)
  1480. ("C-<backspace>" . term-send-backward-kill-word)
  1481. ("C-<delete>" . term-send-forward-kill-word)
  1482. ("C-k" . term-send-raw)
  1483. ("C-y" . term-send-raw)
  1484. ("C-c C-z" . term-stop-subjob)
  1485. ("C-z" . term-stop-subjob)
  1486. ;; work like urxvt tabbed
  1487. ("<S-down>" . multi-term)
  1488. ("<S-left>" . multi-term-prev)
  1489. ("<S-right>" . multi-term-next)
  1490. ("C-v" . term-paste)
  1491. ))
  1492. (add-to-list 'term-bind-key-alist bind))
  1493. ))
  1494.  
  1495. (defun jpk/term-mode-hook ()
  1496. (setq cua--ena-cua-keys-keymap nil)
  1497. ;; use a different face if possible
  1498. (when (fboundp 'buffer-face-set)
  1499. (defvar fixed-pitch-face 'fixed-pitch)
  1500. (buffer-face-set fixed-pitch-face)))
  1501. (add-hook 'term-mode-hook 'jpk/term-mode-hook)
  1502.  
  1503. (global-set-key (kbd "C-c t") 'multi-term-prev)
  1504.  
  1505. ;; see also C-u M-|
  1506. (defun insert-from-shell-current-line ()
  1507. "Run the current line as a shell command, and put the output
  1508. immediately after it. If the region is active, use for the
  1509. command."
  1510. (interactive "*")
  1511. (let ((beg (if (region-active-p)
  1512. (region-beginning)
  1513. (line-beginning-position)))
  1514. (end (if (region-active-p)
  1515. (region-end)
  1516. (line-end-position))))
  1517. (save-excursion
  1518. (goto-char end)
  1519. (insert "\n")
  1520. (insert (shell-command-to-string
  1521. (buffer-substring beg end))))))
  1522.  
  1523. (global-set-key (kbd "C-<kp-enter>") 'insert-from-shell-current-line)
  1524. (global-set-key (kbd "C-!") 'insert-from-shell-current-line)
  1525.  
  1526. ;; TODO make this a emacs function
  1527. ;; copy the terminfo files for eterm-color to a remote host
  1528. ;; ssh remote mkdir -p .terminfo/e/
  1529. ;; scp (concat data-directory "e/eterm-color") (concat data-directory "e/eterm-color.ti") remote:.terminfo/e/
  1530.  
  1531. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1532. ;;; file functions
  1533.  
  1534. ;; move-buffer-file, copy-buffer-file-name-as-kill,
  1535. ;; rename-file-and-buffer, and other useful commands.
  1536. (require 'buffer-extension nil 'noerror)
  1537.  
  1538. (defalias 'delete-this-buffer-and-file 'kill-this-buffer-and-file
  1539. "I always think that this should be called 'delete'. It's not
  1540. getting saved to the kill-ring...")
  1541.  
  1542. (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
  1543.  
  1544. ;; set-fill-column is dumb
  1545. (global-set-key (kbd "C-x f") 'find-file-at-point)
  1546.  
  1547. (defun get-file-name-in-path (dirs suffixes)
  1548. "Use completing-read to select a file DIRS is a list of strings
  1549. that are directory names (like `load-path'). SUFFIXES is a
  1550. list of strings that the files must end with, e.g. '(\".h\"
  1551. \".hpp\")."
  1552. (let ((def (thing-at-point 'symbol)))
  1553. (when def
  1554. (setq def (and (locate-file-completion-table
  1555. dirs suffixes def nil 'lambda)
  1556. def)))
  1557. (completing-read (if def (format "File name (default %s): " def)
  1558. "File name: ")
  1559. (apply-partially 'locate-file-completion-table
  1560. dirs suffixes)
  1561. (if suffixes
  1562. (lambda (x) (string-match (concat (regexp-opt suffixes t) "$") x)))
  1563. nil nil nil def)))
  1564.  
  1565. (defun find-file-in-path (dirs suffixes)
  1566. "Find a file with a certain extension in a list of directories.
  1567. See `get-file-name-in-path' for more info."
  1568. (let* ((library (get-file-name-in-path dirs suffixes))
  1569. (buf (find-file-noselect (locate-file library dirs))))
  1570. (condition-case nil (switch-to-buffer buf) (error (pop-to-buffer buf)))))
  1571.  
  1572. (defun find-user-init-file ()
  1573. "Finds ~/.emacs, or equivalent"
  1574. (interactive)
  1575. (find-file user-init-file))
  1576.  
  1577. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1578. ;;; Dired
  1579.  
  1580. (eval-after-load "dired"
  1581. '(progn
  1582. (with-library 'dired-isearch
  1583. (define-key dired-mode-map (kbd "C-s") 'dired-isearch-forward)
  1584. (define-key dired-mode-map (kbd "C-r") 'dired-isearch-backward)
  1585. (define-key dired-mode-map (kbd "C-M-s") 'dired-isearch-forward-regexp)
  1586. (define-key dired-mode-map (kbd "C-M-r") 'dired-isearch-backward-regexp))
  1587.  
  1588. (with-library 'dired+
  1589. (toggle-dired-find-file-reuse-dir 1)
  1590. (define-key dired-mode-map (kbd "<mouse-1>")
  1591. 'diredp-mouse-mark/unmark)
  1592. (define-key dired-mode-map (kbd "C-<down-mouse-1>") 'ignore)
  1593. (define-key dired-mode-map (kbd "C-<mouse-1>")
  1594. 'diredp-mouse-mark-region-files)
  1595. (define-key dired-mode-map (kbd "<mouse-2>")
  1596. 'diredp-mouse-find-file-reuse-dir-buffer))
  1597.  
  1598. (with-library 'dired-x
  1599. (define-key dired-mode-map (kbd "C-c C-o") 'dired-omit-mode)
  1600. (add-hook 'dired-mode-hook 'dired-omit-mode))
  1601.  
  1602. (define-key dired-mode-map (kbd "S-<return>")
  1603. 'dired-find-file-other-window)
  1604. (define-key dired-mode-map (kbd "S-<down-mouse-2>")
  1605. 'dired-mouse-find-file-other-window)
  1606.  
  1607. (setq dired-deletion-confirmer 'y-or-n-p)
  1608.  
  1609. (define-key dired-mode-map (kbd "e") 'wdired-change-to-wdired-mode)
  1610.  
  1611. (require 'wuxch-dired-copy-paste nil 'noerror)
  1612. ))
  1613.  
  1614. ;; word wrap looks terrible in dired buffers
  1615. (add-hook 'dired-before-readin-hook (lambda () (setq word-wrap nil
  1616. truncate-lines t)))
  1617.  
  1618. (setq dired-image-viewer "geeqie"
  1619. dired-pdf-viewer "okular"
  1620. dired-media-player "vlc"
  1621. dired-office-suite "ooffice")
  1622.  
  1623. (setq dired-guess-shell-alist-user
  1624. '(("\\.mpe?g$\\|\\.avi$" dired-media-player)
  1625. ("\\.wmv$" dired-media-player)
  1626. ("\\.mp4" dired-media-player)
  1627. ("\\.ogg$" dired-media-player)
  1628. ("\\.mp3$" dired-media-player)
  1629. ("\\.wav$" dired-media-player)
  1630. ("\\.xbm$" dired-image-viewer)
  1631. ("\\.p[bgpn]m$" dired-image-viewer)
  1632. ("\\.gif$" dired-image-viewer)
  1633. ("\\.tif$" dired-image-viewer)
  1634. ("\\.png$" dired-image-viewer)
  1635. ("\\.jpe?g$" dired-image-viewer)
  1636. ("\\.pdf$" dired-pdf-viewer)
  1637. ("\\.doc$" dired-office-suite)
  1638. ("\\.xls$" dired-office-suite)
  1639. ("\\.ppt$" dired-office-suite)
  1640. ("\\.od[tsgp]$" dired-office-suite)
  1641. ))
  1642.  
  1643. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1644. ;;; IBuffer
  1645. (eval-after-load "ibuffer"
  1646. '(progn
  1647.  
  1648. (define-ibuffer-sorter pathname
  1649. "Sort by pathname"
  1650. (:description "path")
  1651. (flet ((get-pathname
  1652. (data)
  1653. (with-current-buffer (car data)
  1654. (or buffer-file-name
  1655. (if (eq major-mode 'dired-mode)
  1656. (expand-file-name dired-directory))
  1657. ;; so that all non pathnames are at the end
  1658. "~"))))
  1659. (string-lessp (get-pathname a) (get-pathname b))))
  1660. (define-key ibuffer-mode-map (kbd "s p")
  1661. 'ibuffer-do-sort-by-pathname)
  1662.  
  1663. (define-ibuffer-sorter major-then-pathname
  1664. "Sort the buffers by their major-mode, then by pathname if
  1665. major modes are equal."
  1666. (:description "major-then-path")
  1667. (flet ((get-major
  1668. (data)
  1669. (downcase
  1670. (symbol-name (with-current-buffer
  1671. (car data)
  1672. major-mode))))
  1673. (get-pathname
  1674. (data)
  1675. (with-current-buffer (car data)
  1676. (or buffer-file-name
  1677. (if (eq major-mode 'dired-mode)
  1678. (expand-file-name dired-directory))
  1679. ;; so that all non pathnames are at the end
  1680. "~"))))
  1681. (if (string-equal (get-major a) (get-major b))
  1682. (string-lessp (get-pathname a) (get-pathname b))
  1683. (string-lessp (get-major a) (get-major b)))))
  1684. (define-key ibuffer-mode-map (kbd "s M")
  1685. 'ibuffer-do-sort-by-major-then-pathname)
  1686.  
  1687. (define-key ibuffer-mode-map
  1688. (kbd "/ M") 'ibuffer-set-filter-groups-by-mode)
  1689. (define-key ibuffer-mode-map
  1690. (kbd "C-<down>") 'ibuffer-forward-filter-group)
  1691. (define-key ibuffer-mode-map
  1692. (kbd "C-<up>") 'ibuffer-backward-filter-group)
  1693.  
  1694. (define-key ibuffer-mode-map
  1695. (kbd "<up>")
  1696. (lambda (arg) (interactive "P") (ibuffer-backward-line arg t)))
  1697. (define-key ibuffer-mode-map
  1698. (kbd "<down>")
  1699. (lambda (arg) (interactive "P") (ibuffer-forward-line arg t)))
  1700.  
  1701. (defun ibuffer-mark-toggle (arg)
  1702. (interactive "P")
  1703. (ibuffer-forward-line 0)
  1704. (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
  1705. ;; on a group name
  1706. (ibuffer-toggle-marks) ;; buggy, but not my fault
  1707. ;; on a buffer name
  1708. (if (eq (ibuffer-current-mark) ibuffer-marked-char)
  1709. (ibuffer-mark-interactive arg ?\s 0)
  1710. (ibuffer-mark-interactive arg ibuffer-marked-char 0))))
  1711. (define-key ibuffer-mode-map
  1712. (kbd "SPC") 'ibuffer-mark-toggle)
  1713. ))
  1714.  
  1715. ;; run when ibuffer buffer is created
  1716. (defun jpk/ibuffer-mode-hook ()
  1717. (ibuffer-auto-mode 1)
  1718. (setq truncate-lines t))
  1719. (add-hook 'ibffer-mode-hook 'jpk/ibuffer-mode-hook)
  1720.  
  1721. ;; run when ibuffer command is invoked
  1722. (defun jpk/ibuffer-hook ()
  1723. (ibuffer-set-filter-groups-by-mode)
  1724. (setq ibuffer-sorting-mode 'pathname))
  1725. (add-hook 'ibuffer-hook 'jpk/ibuffer-hook)
  1726.  
  1727. ;; jump to most recent buffer
  1728. (defadvice ibuffer (around ibuffer-point-to-most-recenct activate)
  1729. (let ((recent-buffer-name (buffer-name)))
  1730. ad-do-it
  1731. (unless (string-match-p "*Ibuffer*" recent-buffer-name)
  1732. (ibuffer-jump-to-buffer recent-buffer-name))))
  1733.  
  1734. (global-set-key (kbd "C-x C-b") 'ibuffer)
  1735.  
  1736. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1737. ;;; *scratch*
  1738. ;; if *scratch* is killed, recreate it
  1739.  
  1740. (defun make-scratch-buffer ()
  1741. (interactive)
  1742. (save-excursion
  1743. (set-buffer (get-buffer-create "*scratch*"))
  1744. (lisp-interaction-mode)
  1745. (message "") ;; remove message from above command
  1746. ))
  1747.  
  1748. (defun scratch-respawns-when-killed ()
  1749. (interactive)
  1750. (if (not (string= (buffer-name (current-buffer)) "*scratch*"))
  1751. t ;; return t so the caller may kill it
  1752. (let ((kill-buffer-query-functions kill-buffer-query-functions))
  1753. (remove-hook 'kill-buffer-query-functions 'scratch-respawns-when-killed)
  1754. (set-buffer (get-buffer-create "*scratch*"))
  1755. (kill-buffer (current-buffer)))
  1756. (make-scratch-buffer)
  1757. nil)) ;; return nil so the caller doesn't try to kill it
  1758.  
  1759. (add-hook 'kill-buffer-query-functions 'scratch-respawns-when-killed)
  1760.  
  1761. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1762. ;;; figlet
  1763. (dolist
  1764. (func '(figlet
  1765. figlet-comment
  1766. figlet-figletify-region
  1767. figlet-figletify-region-comment))
  1768. (autoload func "figlet.el"
  1769. "Figlet interface for Emacs." t))
  1770. (eval-after-load "figlet.el"
  1771. '(progn
  1772. (add-to-list 'figlet-options "-k"))) ;; kerning
  1773.  
  1774. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1775. ;;; Hi Lock
  1776.  
  1777. ;; Hi Lock provides on-demand keyword highlighting. It uses
  1778. ;; font-lock-mode to do the work. Unfortunately, this is overridden
  1779. ;; by hl-line mode, so it looks bad when the point is on the line that
  1780. ;; has hi locked words. This forces it to use overlays too, which is
  1781. ;; a performance hit, but it works with hl-line.
  1782. (defadvice hi-lock-set-pattern (around use-overlays activate)
  1783. (let ((font-lock-fontified nil))
  1784. ad-do-it))
  1785.  
  1786. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1787. ;;; Pretty mode
  1788.  
  1789. ;; https://github.com/mattharrison/pretty-mode.git
  1790. ;; interesting, although it kind of messes up indenting
  1791. (autoload 'pretty-mode "pretty-mode.el"
  1792. "Display certain keywords as pretty unicode glyphs" t)
  1793.  
  1794. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1795. ;;; compile
  1796.  
  1797. (defun kill-compile-buffer-if-successful (buffer string)
  1798. " kill a compilation buffer if succeeded without warnings "
  1799. (if (and
  1800. (string-match "compilation" (buffer-name buffer))
  1801. (string-match "finished" string)
  1802. (not
  1803. (with-current-buffer buffer
  1804. (search-forward "warning" nil t))))
  1805. (run-with-timer 1 nil
  1806. 'kill-buffer
  1807. buffer)))
  1808. (add-hook 'compilation-finish-functions 'kill-compile-buffer-if-successful)
  1809.  
  1810. (global-set-key (kbd "C-c b") 'compile)
  1811. (global-set-key (kbd "C-x ~") 'previous-error)
  1812.  
  1813. (defun doxygen-compile ()
  1814. (interactive)
  1815. (compile "doxygen 2>&1 1>/dev/null | sed s%`pwd`/%%"))
  1816. (global-set-key (kbd "C-c B") 'doxygen-compile)
  1817.  
  1818. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1819. ;;; fixme-mode
  1820.  
  1821. (with-library 'fixme-mode
  1822. (setq fixme-highlighted-words '("FIXME" "TODO" "BUG" "XXX" "DEBUG"))
  1823. (dolist (m '(matlab-mode verilog-mode lisp-interaction-mode lisp-mode))
  1824. (add-to-list 'fixme-modes m))
  1825.  
  1826. (fixme-mode 1))
  1827.  
  1828. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1829. ;;; Generic Programming
  1830.  
  1831. (defun insert-comment-bar (arg &optional len)
  1832. (interactive "*P")
  1833. (let ((num (or arg 72))
  1834. (to-insert ""))
  1835. (cond
  1836. ((memq major-mode '(c-mode cc-mode c++-mode java-mode))
  1837. (setq to-insert (concat "/*"
  1838. (make-string (- num 4) ?*)
  1839. "*/")))
  1840. ((memq major-mode '(emacs-lisp-mode lisp-mode lisp-interaction-mode))
  1841. (setq to-insert (make-string num ?\;)))
  1842. ((memq major-mode '(latex-mode))
  1843. (setq to-insert (make-string num ?%)))
  1844. (t
  1845. (setq to-insert (make-string num ?#))))
  1846.  
  1847. (beginning-of-line)
  1848. (if (looking-at "^[[:space:]]*$")
  1849. (end-of-line)
  1850. (setq to-insert (concat to-insert "\n")))
  1851. (insert to-insert)))
  1852.  
  1853. ;; extra syntax highlighting
  1854. (defface font-lock-bracket-face
  1855. '((t (:foreground "cyan3")))
  1856. "Font lock mode face for brackets, e.g. '(', ']', etc."
  1857. :group 'font-lock-faces)
  1858. (defvar font-lock-bracket-face 'font-lock-bracket-face
  1859. "Font lock mode face for backets. Changing this directly
  1860. affects only new buffers.")
  1861.  
  1862. (defvar operators-regexp
  1863. (regexp-opt '("+" "-" "*" "/" "%" "!"
  1864. "&" "^" "~" "|"
  1865. "=" "<" ">"
  1866. "." "," ";" ":" "?"))
  1867. "Regexp matching symbols that are operators in most programming
  1868. languages.")
  1869.  
  1870. (setq operators-font-lock-spec
  1871. (cons operators-regexp
  1872. (list
  1873. 0 ;; use whole match
  1874. 'font-lock-builtin-face
  1875. 'keep ;; OVERRIDE
  1876. )))
  1877.  
  1878. (defvar brackets-regexp
  1879. (regexp-opt '("(" ")" "[" "]" "{" "}"))
  1880. "Regexp matching symbols that are grouping operators in most
  1881. programming languages.")
  1882.  
  1883. (setq brackets-font-lock-spec
  1884. (cons brackets-regexp
  1885. (list
  1886. 0 ;; use whole match
  1887. 'font-lock-bracket-face
  1888. 'keep ;; OVERRIDE
  1889. )))
  1890.  
  1891. (defun jpk/programming-mode-hook ()
  1892. ;;(smart-tab-mode 0) ;; default to using spaces
  1893.  
  1894. ;; for doxygen
  1895. (with-library 'doxymacs
  1896. (doxymacs-mode 1)
  1897. (doxymacs-font-lock))
  1898. (with-library 'filladapt
  1899. (filladapt-mode 1))
  1900.  
  1901. ;; check spelling on the fly, but only in comments and strings
  1902. (with-library 'flyspell
  1903. (flyspell-mode 0)
  1904. (flyspell-prog-mode))
  1905.  
  1906. ;; e.g. insert '(' and ')' around the region if it is active and '('
  1907. ;; is typed; works for other delimiters too
  1908. (with-library 'wrap-region
  1909. (wrap-region-mode 1))
  1910.  
  1911. ;; highlight nested parens
  1912. (with-library 'highlight-parentheses
  1913. (highlight-parentheses-mode 1))
  1914.  
  1915. (local-set-key (kbd "C-M-;") 'insert-comment-bar)
  1916.  
  1917. (with-library 'pretty-mode
  1918. (pretty-mode 1))
  1919.  
  1920. (add-hook 'after-save-hook 'imenu-force-rescan 'append 'local)
  1921. )
  1922.  
  1923. (defun imenu-force-rescan ()
  1924. "Doesn't rescan, but forces a rescan the next time imenu is invoked."
  1925. (interactive)
  1926. (save-excursion
  1927. (imenu--cleanup)
  1928. (setq imenu--index-alist nil)))
  1929.  
  1930. (eval-after-load "doxymacs"
  1931. '(progn
  1932. (load "doxymacs-hacks.el")
  1933. ))
  1934.  
  1935. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1936. ;;; C programming language
  1937.  
  1938. (defun cpp-highlight-if-0/1 ()
  1939. "Modify the face of things in between #if 0 ... #endif."
  1940. (interactive)
  1941. (setq cpp-known-face '(background-color . "dim gray"))
  1942. (setq cpp-unknown-face 'default)
  1943. (setq cpp-face-type 'dark)
  1944. (setq cpp-known-writable 't)
  1945. (setq cpp-unknown-writable 't)
  1946. (setq cpp-edit-list
  1947. '((#("1" 0 1
  1948. (fontified nil))
  1949. nil
  1950. (background-color . "dim gray")
  1951. both nil)
  1952. (#("0" 0 1
  1953. (fontified nil))
  1954. (background-color . "dim gray")
  1955. nil
  1956. both nil)))
  1957. (cpp-highlight-buffer t))
  1958.  
  1959. (setq c-types-regexp
  1960. (concat
  1961. "\\<[_a-zA-Z][_a-zA-Z0-9]*_t\\>" "\\|"
  1962. (regexp-opt '("unsigned" "int" "char" "float" "void") 'words)))
  1963.  
  1964. (eval-after-load "cc-mode"
  1965. '(progn
  1966. (font-lock-add-keywords
  1967. 'c-mode
  1968. (list
  1969. operators-font-lock-spec
  1970. brackets-font-lock-spec
  1971. (cons c-types-regexp 'font-lock-type-face)))
  1972. (font-lock-add-keywords
  1973. 'c++-mode
  1974. (list
  1975. operators-font-lock-spec
  1976. brackets-font-lock-spec
  1977. (cons c-types-regexp 'font-lock-type-face)))
  1978.  
  1979. ;; TODO find a better way to do this
  1980. (with-library 'ffap
  1981. (add-to-list 'ffap-c-path "/usr/lib/avr/include/"))
  1982. ))
  1983.  
  1984. (defun setup-simple-compile ()
  1985. "Sets compile-command to something like `gcc -o foo foo.c' if
  1986. there is no Makefile in the directory"
  1987. (interactive)
  1988. (when (and buffer-file-name (file-name-nondirectory buffer-file-name))
  1989. (unless (file-exists-p "Makefile")
  1990. (set (make-local-variable 'compile-command)
  1991. (let* ((file (file-name-nondirectory buffer-file-name))
  1992. (compiler (if (string-equal "c" (file-name-extension file))
  1993. "gcc" "g++")))
  1994. (format "%s -o %s %s %s %s" ;; "%s -c -o %s.o %s %s %s"
  1995. (or (getenv "CC") compiler)
  1996. (file-name-sans-extension file)
  1997. (or (getenv "CPPFLAGS") "-DDEBUG=9")
  1998. (or (getenv "CFLAGS") (if (string= compiler "gcc")
  1999. "-ansi -Wall -g3 -std=c99"
  2000. "-ansi -Wall -g3"))
  2001. file))))))
  2002.  
  2003. (defun jpk/c-mode-hook ()
  2004. (smart-tab-mode 1)
  2005. (setq tab-width 4)
  2006. (setup-simple-compile)
  2007. (imenu-add-to-menubar "IMenu")
  2008. ;;(cpp-highlight-if-0/1)
  2009. ;;(add-hook 'after-save-hook 'cpp-highlight-if-0/1 'append 'local)
  2010. )
  2011.  
  2012. (add-hook 'c-mode-common-hook 'jpk/programming-mode-hook)
  2013. (add-hook 'c-mode-common-hook 'jpk/c-mode-hook)
  2014.  
  2015. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2016. ;;; C#
  2017. (autoload 'csharp-mode "csharp-mode.el"
  2018. "Major mode for editing C# source. Derives from c-mode." t)
  2019. (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode))
  2020.  
  2021. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2022. ;;; Perl
  2023.  
  2024. (eval-after-load "cperl-mode"
  2025. '(progn
  2026. (font-lock-add-keywords
  2027. 'cperl-mode
  2028. (list
  2029. operators-font-lock-spec
  2030. brackets-font-lock-spec))
  2031. ))
  2032.  
  2033. (add-hook 'cperl-mode-hook 'jpk/programming-mode-hook)
  2034. (add-hook 'cperl-mode-hook
  2035. (lambda ()
  2036. (cperl-set-style "BSD")
  2037. ))
  2038.  
  2039. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2040. ;;; PHP
  2041. (autoload 'php-mode "php-mode.el"
  2042. "Major mode for editing PHP source." t)
  2043. (add-to-list 'auto-mode-alist '("\\.php\\'" . php-mode))
  2044.  
  2045. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2046. ;;; Python
  2047.  
  2048. (eval-after-load "python"
  2049. '(progn
  2050. ;; syntax highlighting of operators
  2051. (font-lock-add-keywords
  2052. 'python-mode
  2053. (list
  2054. operators-font-lock-spec
  2055. brackets-font-lock-spec))
  2056. ))
  2057.  
  2058. (defun python-send-region-or-line (beg en)
  2059. "Like `python-send-region', but automatically send the current
  2060. line if region is not active."
  2061. (interactive "r")
  2062. (if (use-region-p)
  2063. (python-send-region beg en)
  2064. (python-send-region (line-beginning-position)
  2065. (line-end-position))))
  2066.  
  2067. (defun jpk/python-mode-hook ()
  2068. (when (condition-case nil
  2069. (load-library "pylint")
  2070. (error nil))
  2071. (local-set-key (kbd "C-c C-w") 'pylint)
  2072. (local-set-key (kbd "C-c C-v") 'pylint))
  2073. (local-set-key (kbd "S-<return>") 'python-send-region-or-line)
  2074. (when (condition-case nil
  2075. (imenu-add-to-menubar "Imenu")
  2076. (error nil))))
  2077.  
  2078. (add-hook 'python-mode-hook 'jpk/programming-mode-hook)
  2079. (add-hook 'python-mode-hook 'jpk/python-mode-hook)
  2080.  
  2081. ;; a better debugger
  2082. (add-to-list 'load-path "/usr/share/emacs/site-lisp/pydb")
  2083. (autoload 'pydb "pydb.el"
  2084. "Python debugger" t)
  2085.  
  2086. ;; get pylint into the python.el menu
  2087. (defvaralias 'py-mode-map 'python-mode-map)
  2088.  
  2089. (defun python-path ()
  2090. "Returns a list of strings containing all the directories in Python's path."
  2091. (split-string (shell-command-to-string
  2092. "python -c 'import sys; print \"+++\".join(sys.path)'")
  2093. "+++"))
  2094.  
  2095. (defun find-python-library ()
  2096. (interactive)
  2097. (find-file-in-path (python-path) '(".py")))
  2098.  
  2099. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2100. ;;; Octave/Matlab
  2101. (add-to-list 'auto-mode-alist
  2102. '("\\.m\\'" . matlab-mode))
  2103.  
  2104. ;; transpose (') is still unhighlighted
  2105. ;; any syntax highlighting must take into account strings
  2106. ;; it seems like any operators, etc. inside a string fucks it all up
  2107. ;; (setq matlab-operators-regexp
  2108. ;; (regexp-opt '("+" "-" "*" "/" "!"
  2109. ;; "&" "^" "~" "|"
  2110. ;; "=" "<" ">"
  2111. ;; "." "," ";" ":" "?")))
  2112.  
  2113. (eval-after-load "matlab"
  2114. '(progn
  2115. (font-lock-add-keywords
  2116. 'matlab-mode
  2117. (list
  2118. ;;(cons matlab-brackets-regexp 'font-lock-bracket-face)
  2119. ;;brackets-font-lock-spec
  2120. ))
  2121. ))
  2122.  
  2123. (defun jpk/matlab-hook ()
  2124. (interactive)
  2125. (define-key matlab-mode-map (kbd "M-;") 'comment-dwim)
  2126.  
  2127. ;; not that simple
  2128. ;; (modify-syntax-entry ?\" "\"" matlab-mode-syntax-table)
  2129.  
  2130. ;; block style comments "%{ ... %}", "#{ ... #}"
  2131. ;; (modify-syntax-entry ?\# ". 13" matlab-mode-syntax-table)
  2132. ;; (modify-syntax-entry ?\% ". 13" matlab-mode-syntax-table)
  2133. ;; (modify-syntax-entry ?\{ ". 2" matlab-mode-syntax-table)
  2134. ;; (modify-syntax-entry ?\} ". 4" matlab-mode-syntax-table)
  2135. ;; (modify-syntax-entry ?\n " " matlab-mode-syntax-table)
  2136.  
  2137. ;; single-line comments "% ...", "# ..."
  2138. ;; (add-to-list 'octave-font-lock-keywords '("[%#].*$" . 'font-lock-comment-face))
  2139. )
  2140.  
  2141. (add-hook 'matlab-mode-hook 'jpk/programming-mode-hook)
  2142. (add-hook 'matlab-mode-hook 'jpk/matlab-hook)
  2143.  
  2144. ;; hack for octave mode "end" keyword
  2145. ;; (eval-after-load "octave-mod"
  2146. ;; (progn
  2147. ;; (add-to-list 'octave-end-keywords "end[[:space:]]*\\([%#].*\\|$\\)")
  2148. ;; (setq octave-block-end-regexp
  2149. ;; (concat "\\<\\("
  2150. ;; (mapconcat 'identity octave-end-keywords "\\|")
  2151. ;; "\\)\\>"))
  2152. ;; ))
  2153.  
  2154. (defun octave-send-buffer ()
  2155. (interactive)
  2156. (octave-send-region (point-min) (point-max)))
  2157.  
  2158. (defun jpk/octave-mode-hook ()
  2159. (interactive)
  2160. (local-set-key (kbd "C-c C-s") 'octave-send-buffer)
  2161. (local-set-key (kbd "C-c C-l") 'octave-send-line)
  2162. (local-set-key (kbd "C-c C-r") 'octave-send-region))
  2163.  
  2164. (add-hook 'octave-mode-hook 'jpk/octave-mode-hook)
  2165.  
  2166. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2167. ;;; Verilog
  2168.  
  2169. (setq verilog-bitspec-regexp "\\<[0-9]+'[bdh]")
  2170.  
  2171. (eval-after-load "verilog-mode"
  2172. '(progn
  2173. (font-lock-add-keywords
  2174. 'verilog-mode
  2175. (list
  2176. operators-font-lock-spec
  2177. brackets-font-lock-spec
  2178. (cons verilog-bitspec-regexp 'font-lock-type-face)))
  2179. ))
  2180.  
  2181. (add-to-list 'auto-mode-alist
  2182. '("\\.vams\\'" . verilog-mode))
  2183.  
  2184. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2185. ;;; Lisp
  2186.  
  2187. (defun lisp-set-up-extra-font-lock (mode)
  2188. (font-lock-add-keywords
  2189. mode
  2190. (list
  2191. brackets-font-lock-spec)))
  2192.  
  2193. (defun jpk/lisp-modes-hook ()
  2194. (eldoc-mode 1)
  2195. (local-set-key (kbd "C-M-S-x") 'eval-region))
  2196.  
  2197. (eval-after-load "lisp-mode"
  2198. '(progn
  2199. (dolist (mode '(lisp-mode
  2200. emacs-lisp-mode
  2201. lisp-interaction-mode))
  2202. (lisp-set-up-extra-font-lock mode))
  2203. (dolist (hook '(lisp-mode-hook
  2204. emacs-lisp-mode-hook
  2205. lisp-interaction-mode-hook))
  2206. (add-hook hook 'jpk/programming-mode-hook)
  2207. (add-hook hook 'jpk/lisp-modes-hook))
  2208. ))
  2209.  
  2210. (defun jpk/ielm-mode-hook ()
  2211. (with-library 'auto-complete
  2212. (setq ac-sources '(ac-source-functions
  2213. ac-source-variables
  2214. ac-source-features
  2215. ac-source-symbols
  2216. ac-source-words-in-same-mode-buffers))
  2217. (add-to-list 'ac-modes 'inferior-emacs-lisp-mode)
  2218. (auto-complete-mode 1)))
  2219. (add-hook 'ielm-mode-hook 'jpk/ielm-mode-hook)
  2220.  
  2221. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2222. ;;; Lua
  2223.  
  2224. (autoload 'lua-mode "lua-mode.el"
  2225. "Major mode for editing Lua source code." t)
  2226. (add-to-list 'auto-mode-alist
  2227. '("\\.lua\\'" . lua-mode))
  2228.  
  2229. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2230. ;;; Scheme
  2231.  
  2232. ;; geiser is a nice REPL and other interaction to a scheme interpreter
  2233. (add-to-list 'load-path (concat user-emacs-directory "geiser/elisp"))
  2234. (require 'geiser nil 'noerror) ;; this is just autoloads
  2235.  
  2236. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2237. ;;; FVWM
  2238. (autoload 'fvwm-mode "fvwm-mode.el"
  2239. "Major mode for Fvwm config files." t)
  2240.  
  2241. ;; fvwm config file major mode
  2242. (eval-after-load "fvwm-mode"
  2243. '(progn
  2244. (setq fvwm-fvwmcommand-path "FvwmCommand")
  2245. ;; this may be slow
  2246. (setq fvwm-preload-completions nil)))
  2247.  
  2248. (defun jpk/fvwm-mode-hook ()
  2249. ;;(fvwm-enable-indentation)
  2250. (local-set-key (kbd "RET") 'newline)
  2251. (setq indent-line-function 'indent-relative-dwim)
  2252. (setq tab-width 4))
  2253.  
  2254. (add-hook 'fvwm-mode-hook 'jpk/fvwm-mode-hook)
  2255.  
  2256. ;; fvwm major mode
  2257. (add-to-list 'auto-mode-alist
  2258. '("\\`FvwmApplet-" . fvwm-mode))
  2259. (add-to-list 'auto-mode-alist
  2260. '("\\`FvwmScript-" . fvwm-mode))
  2261. (add-to-list 'auto-mode-alist
  2262. '("\\.fvwm\\'" . fvwm-mode))
  2263.  
  2264. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2265. ;;; HTML/XML
  2266.  
  2267. (fset 'xml-mode 'nxml-mode)
  2268. (fset 'html-mode 'nxml-mode)
  2269. (fset 'sgml-mode 'nxml-mode)
  2270.  
  2271. ;; Not really HTML editing related, but this will make an HTML file of
  2272. ;; the buffer, with all the syntax highlighting.
  2273. (with-library 'htmlize-view
  2274. (htmlize-view-add-to-files-menu))
  2275. ;; fix a bug in htmlize from emacs-goodies-el
  2276. (eval-after-load "htmlize"
  2277. '(progn
  2278. (defun htmlize-face-size (face)
  2279. ;; The size (height) of FACE, taking inheritance into account.
  2280. ;; Only works in Emacs 21 and later.
  2281. (let ((size-list
  2282. (loop
  2283. for f = face then (face-attribute f :inherit)
  2284. until (or (not f) (eq f 'unspecified))
  2285. for h = (face-attribute f :height)
  2286. collect (if (eq h 'unspecified) nil h))))
  2287. (reduce 'htmlize-merge-size (cons nil size-list))))
  2288. ))
  2289.  
  2290. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2291. ;;; config files
  2292.  
  2293. (defun jpk/conf-mode-hook ()
  2294. (local-set-key (kbd "C-m") 'newline))
  2295. (add-hook 'conf-mode-hook 'jpk/conf-mode-hook)
  2296.  
  2297. (dolist (re '("\\.list\\'" ;; apt sources files
  2298. "\\.hgrc" "\\.hgignore" ;; mercurial files
  2299. "Doxyfile" ;; Doxygen
  2300. ))
  2301. (add-to-list 'auto-mode-alist `(,re . conf-mode)))
  2302.  
  2303. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2304. ;;; MEDIAWIKI MODE
  2305.  
  2306. (autoload 'wikipedia-mode "wikipedia-mode.el"
  2307. "Major mode for editing documents in Wikipedia markup." t)
  2308.  
  2309. (add-to-list 'auto-mode-alist
  2310. '("\\.wiki\\'" . wikipedia-mode))
  2311.  
  2312. (defun jpk/wikipedia-mode-hook ()
  2313. (local-unset-key (kbd "C-<right>"))
  2314. (local-unset-key (kbd "C-<left>"))
  2315. (local-unset-key (kbd "C-<up>"))
  2316. (local-unset-key (kbd "C-<down>")))
  2317. (add-hook 'wikipedia-mode-hook 'jpk/wikipedia-mode-hook)
  2318.  
  2319. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2320. ;;; text-mode
  2321.  
  2322. (defun jpk/text-mode-hook ()
  2323. (setq indent-line-function 'indent-relative-dwim)
  2324. (with-library 'flyspell
  2325. (flyspell-mode 1))
  2326. )
  2327.  
  2328. (add-hook 'text-mode-hook 'jpk/text-mode-hook)
  2329.  
  2330. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2331. ;;; LaTeX (AUCTeX mode)
  2332.  
  2333. (defun jpk/LaTeX-mode-hook ()
  2334. (visual-line-mode 1)
  2335. (with-library 'flyspell
  2336. (flyspell-mode 1))
  2337. (setq fill-column 80)
  2338. (local-set-key (kbd "C-M-;") 'insert-comment-bar))
  2339.  
  2340. (add-hook 'LaTeX-mode-hook 'jpk/LaTeX-mode-hook)
  2341.  
  2342. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2343. ;;; LINE NUMBERS
  2344. ;; toggle line numbering
  2345. (autoload 'linum-mode "linum.el"
  2346. "Display line numbers in the left margin." t)
  2347.  
  2348. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2349. ;;; UNDO/REDO
  2350.  
  2351. ;; treat edit history like the tree it is
  2352. (with-library 'undo-tree
  2353. (global-undo-tree-mode 1)
  2354. (global-set-key (kbd "C-z") 'undo-tree-undo)
  2355. (global-set-key (kbd "C-S-z") 'undo-tree-redo))
  2356.  
  2357. ;; C-x u starts the undo-tree visualizer
  2358. (defvar undo-tree-visualize-window-state nil
  2359. "Stores the window state before undo-tree-visualize is called,
  2360. so that it can be restored by undo-tree-visualizer-quit")
  2361. (defadvice undo-tree-visualize
  2362. (before restore-window-layout activate)
  2363. (setq undo-tree-visualize-window-state (current-window-configuration)))
  2364. (defadvice undo-tree-visualizer-quit
  2365. (after restore-window-layout activate)
  2366. (when undo-tree-visualize-window-state
  2367. (set-window-configuration undo-tree-visualize-window-state)))
  2368.  
  2369. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2370. ;;; isearch
  2371.  
  2372. (defun recenter-no-redraw (&optional arg)
  2373. (interactive "P")
  2374. (let ((recenter-redisplay nil))
  2375. (recenter arg)))
  2376.  
  2377. ;; minor improvements to isearch
  2378. (require 'isearch+ nil 'noerror)
  2379.  
  2380. ;; Allow page up/down, C-l, and anything else that doesn't move the
  2381. ;; point during isearch.
  2382. (setq isearch-allow-scroll t)
  2383. (put 'recenter-top-bottom 'isearch-scroll t)
  2384. (put 'force-scroll-left-8 'isearch-scroll t)
  2385. (put 'force-scroll-right-8 'isearch-scroll t)
  2386.  
  2387. ;; make C-y and C-v do what you expect in ISearch mode
  2388. (define-key isearch-mode-map (kbd "C-y") 'isearch-yank-kill)
  2389. (define-key isearch-mode-map (kbd "C-v") 'isearch-yank-kill)
  2390.  
  2391. ;; normally M-<tab> which is obviously not going to work
  2392. ;; get a literal tab with C-q <tab>
  2393. (define-key isearch-mode-map (kbd "<tab>") 'isearch-complete)
  2394.  
  2395. ;; recenter the cursor after finding a match
  2396. (defadvice isearch-search (after isearch-recenter activate)
  2397. (when isearch-success
  2398. (recenter-no-redraw)))
  2399.  
  2400. ;; make backspace behave in a more intuitive way
  2401. (define-key isearch-mode-map (kbd "<backspace>") 'isearch-del-char)
  2402.  
  2403. ;; move cursor to the beginning of the match when searching forward
  2404. (defun jpk/isearch-end-hook ()
  2405. (when (and isearch-forward
  2406. isearch-other-end)
  2407. (goto-char isearch-other-end)))
  2408. (add-hook 'isearch-mode-end-hook 'jpk/isearch-end-hook)
  2409.  
  2410. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2411. ;;; flex isearch
  2412.  
  2413. (with-library 'flex-isearch
  2414. (flex-isearch-mode 1))
  2415.  
  2416. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2417. ;;; grep
  2418.  
  2419. ;; editable grep results
  2420. (require 'wgrep nil 'noerror)
  2421.  
  2422. ;; TODO
  2423. ;; (defun rgrep-context (arg)
  2424. ;; (interactive "p")
  2425. ;; (let ((grep-template (concat "grep <X> <C> -C " (number-to-string arg)
  2426. ;; " -nH -e <R> <F>")))
  2427. ;; (message "grep-template: %s" grep-template)
  2428. ;; (call-interactively 'rgrep)))
  2429.  
  2430. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2431. ;;; Search and replace
  2432.  
  2433. (define-key query-replace-map (kbd "b") 'backup)
  2434. (define-key query-replace-map (kbd "B") 'backup)
  2435. (define-key query-replace-map (kbd "RET") 'act-and-show)
  2436.  
  2437. ;; Findr - find and operate on files recursively
  2438. (autoload 'findr-query-replace "findr.el" "Replace text in files." t)
  2439.  
  2440. (defun query-exchange (string-1 string-2)
  2441. "Exchange string-1 and string-2 interactively.
  2442. The user is prompted at each instance like query-replace."
  2443. (interactive "sString 1: \nsString 2: ")
  2444. (perform-replace
  2445. (concat "\\(" string-1 "\\)\\|" string-2)
  2446. '(replace-eval-replacement replace-quote
  2447. (if (match-string 1) string-2 string-1))
  2448. t t nil))
  2449.  
  2450. (defun search-forward-and-center (string &optional bound noerror count)
  2451. "Just like `search-forward', but centers the point in the window."
  2452. (let ((ret (search-forward regexp bound noerror count)))
  2453. (recenter-no-redraw)
  2454. ret))
  2455. (setq replace-search-function 'search-forward-and-center)
  2456.  
  2457. (defun re-search-forward-and-center (regexp &optional bound noerror count)
  2458. "Just like `re-search-forward', but centers the point in the window."
  2459. (let ((ret (re-search-forward regexp bound noerror count)))
  2460. (recenter-no-redraw)
  2461. ret))
  2462. (setq replace-re-search-function 're-search-forward-and-center)
  2463.  
  2464. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2465. ;;; Ack is a better grep
  2466.  
  2467. ;; TODO look at easy-mmode-define-navigation
  2468.  
  2469. (autoload 'ack "full-ack.el"
  2470. "Emacs frontend for ack" t)
  2471. (autoload 'ack-same "full-ack.el"
  2472. "Emacs frontend for ack" t)
  2473.  
  2474. (defun anchor-regexp (re)
  2475. "Simply wrap RE with `^' and `$', like so: `foo' -> `^foo$'"
  2476. (when (stringp re) (concat "^" re "$")))
  2477.  
  2478. (eval-after-load "full-ack.el"
  2479. '(progn
  2480.  
  2481. (defsubst ack-read (regexp)
  2482. (read-from-minibuffer
  2483. (if regexp "ack pattern: " "ack literal search: ")
  2484. (if (featurep 'thingatpt)
  2485. (let ((str (thing-at-point 'symbol)))
  2486. (set-text-properties 0 (length str) nil str)
  2487. str))
  2488. nil nil
  2489. (if regexp 'ack-regexp-history 'ack-literal-history)))
  2490.  
  2491. (defadvice ack-next-match (after recenter activate)
  2492. (recenter-no-redraw))
  2493.  
  2494. (defadvice ack-previous-match (after recenter activate)
  2495. (recenter-no-redraw))
  2496.  
  2497. (defun ack-next-file (pos arg)
  2498. (interactive "d\np")
  2499. (setq arg (* 2 arg))
  2500. (unless (get-text-property pos 'ack-file)
  2501. (setq arg (1- arg)))
  2502. (assert (> arg 0))
  2503. (dotimes (i arg)
  2504. (setq pos (next-single-property-change pos 'ack-file))
  2505. (unless pos
  2506. (error "Moved past last file")))
  2507. (goto-char pos)
  2508. (recenter-no-redraw)
  2509. pos)
  2510.  
  2511. (defun ack-previous-file (pos arg)
  2512. (interactive "d\np")
  2513. (assert (> arg 0))
  2514. (dotimes (i (* 2 arg))
  2515. (setq pos (previous-single-property-change pos 'ack-file))
  2516. (unless pos
  2517. (error "Moved back before first file")))
  2518. (goto-char pos)
  2519. (recenter-no-redraw)
  2520. pos)
  2521.  
  2522. (add-to-list 'debug-ignored-errors
  2523. (anchor-regexp (regexp-opt '("Moved back before first file"
  2524. "Moved past last file"))))
  2525.  
  2526. (define-key ack-mode-map (kbd "TAB") 'ack-next-match)
  2527. (define-key ack-mode-map (kbd "<backtab>") 'ack-previous-match)
  2528. (define-key ack-mode-map (kbd "N") 'ack-next-file)
  2529. (define-key ack-mode-map (kbd "P") 'ack-previous-file)
  2530. (define-key ack-mode-map (kbd "q") 'quit-window)
  2531. ))
  2532.  
  2533. ;; for grep-mode
  2534. (add-to-list 'debug-ignored-errors
  2535. (anchor-regexp (regexp-opt '("Moved past last grep hit"
  2536. "Moved back before first grep hit"))))
  2537.  
  2538. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2539. ;;; Paren insertion
  2540.  
  2541. (add-to-list 'load-path (concat user-emacs-directory "wrap-region"))
  2542. (with-library 'wrap-region
  2543. (defun jpk/wrap-region-after-hook ()
  2544. (goto-char (1+ wrap-region-end)))
  2545. (add-hook 'wrap-region-after-hook 'jpk/wrap-region-after-hook))
  2546.  
  2547. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2548. ;;; Paren Highlighting
  2549. ;; see also highlight-parentheses-mode
  2550.  
  2551. (with-library 'mic-paren
  2552. (paren-activate))
  2553.  
  2554. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2555. ;;; Thing at point
  2556.  
  2557. ;; bounce between matching parens
  2558. (defun goto-match-paren ()
  2559. "Go to the matching parenthesis if on parenthesis. Else go to the
  2560. opening parenthesis one level up."
  2561. (interactive)
  2562. (if (looking-at "\\s\(")
  2563. (forward-list 1)
  2564. (backward-char 1)
  2565. (if (looking-at "\\s\)")
  2566. (progn (forward-char 1) (backward-list 1))
  2567. (while (not (looking-at "\\s("))
  2568. (backward-char 1)
  2569. (when (looking-at "\\s\)")
  2570. (message "->> )")
  2571. (forward-char 1)
  2572. (backward-list 1)
  2573. (backward-char 1))))))
  2574. ;; (put 'goto-match-paren 'CUA 'move)
  2575.  
  2576. (defun bounce-thing-boundary (thing &optional tweak-beginning tweak-end n)
  2577. "Move point to beginning or end of THING.
  2578. If in the middle of THING, go to the beginning. If at the
  2579. beginning, go to end. If at the end, go to beginning. If not in
  2580. a THING, search forward N THINGs (negative N searches backward).
  2581. The optional TWEAK-BEGINNING and TWEAK-END are added to THING's
  2582. beginning or end position, respectively, before moving the
  2583. point."
  2584. (interactive)
  2585. (unless tweak-beginning
  2586. (setq tweak-beginning 0))
  2587. (unless tweak-end
  2588. (setq tweak-end 0))
  2589. (let ((bounds (bounds-of-thing-at-point thing)))
  2590. (if (not bounds)
  2591. (progn
  2592. (when n
  2593. (forward-thing thing n))
  2594. (unless (thing-at-point thing)
  2595. (error "No %s here." thing)))
  2596. (setq bounds (cons (+ (car bounds) tweak-beginning)
  2597. (+ (cdr bounds) tweak-end)))
  2598. (cond
  2599. ((eq (point) (car bounds))
  2600. (goto-char (cdr bounds)))
  2601. ((eq (point) (cdr bounds))
  2602. (goto-char (car bounds)))
  2603. (t
  2604. (goto-char (car bounds)))))))
  2605.  
  2606. (defun bounce-string-or-list ()
  2607. (interactive)
  2608. (if (> (length (thing-at-point 'string)) 0)
  2609. (bounce-thing-boundary 'string)
  2610. (goto-match-paren)))
  2611. (global-set-key (kbd "C-S-<iso-lefttab>") 'bounce-string-or-list)
  2612. (global-set-key (kbd "C-%") 'bounce-string-or-list)
  2613.  
  2614. ;; TODO move this stuff to thing-opt
  2615. ;; upward-mark-thing marks successively "bigger" things if it is
  2616. ;; invoked repeatedly. mark-thing prompts for which thing to mark.
  2617. (with-library 'thing-opt
  2618.  
  2619. (defun reset-upward-bounds-of-thing ()
  2620. (setq upward-bounds-of-thing-index 0
  2621. upward-bounds-of-thing-trial 0
  2622. upward-bounds-of-thing-original-position (point)
  2623. upward-bounds-of-thing-prev nil))
  2624.  
  2625. (defun upward-bounds-of-thing (list-of-things)
  2626. (interactive)
  2627. (let ((len (length list-of-things))
  2628. (index upward-bounds-of-thing-index)
  2629. bounds)
  2630. (while (and (null bounds)
  2631. (< index len))
  2632. (let ((thing (nth index list-of-things))
  2633. (limit '*))
  2634. (if (consp thing)
  2635. (setq limit (cdr thing)
  2636. thing (car thing)))
  2637. (setq bounds (bounds-of-thing-at-point thing))
  2638. (if (not (or (null bounds)
  2639. (and (not (eq limit '*)) (>= upward-bounds-of-thing-trial limit))
  2640. (eq (car bounds) (cdr bounds))
  2641. (and upward-bounds-of-thing-prev
  2642. (equal bounds upward-bounds-of-thing-prev))))
  2643. (setq upward-bounds-of-thing-name (format "%s" (symbol-name thing)))
  2644. (setq bounds nil
  2645. index (mod (1+ index) len)
  2646. upward-bounds-of-thing-index (mod (1+ upward-bounds-of-thing-index) len)
  2647. upward-bounds-of-thing-trial 0)
  2648. (goto-char upward-bounds-of-thing-original-position))))
  2649. (when bounds
  2650. (setq upward-bounds-of-thing-trial (1+ upward-bounds-of-thing-trial))
  2651. (setq upward-bounds-of-thing-prev bounds)
  2652. bounds)))
  2653.  
  2654. (defun upward-mark-thing ()
  2655. (interactive)
  2656. (unless (eq last-command this-command)
  2657. (reset-upward-bounds-of-thing))
  2658. (let ((bounds (upward-bounds-of-thing upward-mark-thing-list)))
  2659. (when bounds
  2660. (message "%s" upward-bounds-of-thing-name)
  2661. (goto-char (car bounds))
  2662. (push-mark (cdr bounds) t 'activate)
  2663. (setq deactivate-mark nil))))
  2664.  
  2665. (defun upward-isearch-thing ()
  2666. (interactive)
  2667. (unless (eq last-command this-command)
  2668. (reset-upward-bounds-of-thing))
  2669. (let ((bounds (upward-bounds-of-thing '(email url word symbol string filename))))
  2670. (when bounds
  2671. (setq isearch-initial-string (buffer-substring-no-properties
  2672. (car bounds) (cdr bounds)))
  2673. (setq isearch-string isearch-initial-string
  2674. isearch-message isearch-initial-string)
  2675. (isearch-update)
  2676. (isearch-highlight (car bounds) (cdr bounds)))))
  2677.  
  2678. (define-key isearch-mode-map (kbd "C-S-s") 'upward-isearch-thing)
  2679. (define-key isearch-mode-map (kbd "M-3") 'upward-isearch-thing)
  2680.  
  2681. (global-set-key (kbd "C-S-s") 'upward-mark-thing)
  2682. (global-set-key (kbd "M-3") 'upward-mark-thing)
  2683.  
  2684. (setq upward-mark-thing-list
  2685. '(email
  2686. url
  2687. word
  2688. symbol
  2689. string
  2690. (up-list . *)
  2691. paragraph
  2692. ))
  2693.  
  2694. )
  2695.  
  2696. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2697. ;;; Yasnippet (Yet Another Template Mode)
  2698.  
  2699. (setq jpk-snippet-directory (concat user-emacs-directory "snippets/"))
  2700. (setq yas-installed-directory (concat user-emacs-directory "yasnippet/"))
  2701. (setq yas-snippet-directory (concat yas-installed-directory "snippets/"))
  2702. (add-to-list 'load-path yas-installed-directory)
  2703.  
  2704. (with-library 'yasnippet
  2705. (yas/initialize)
  2706. (setq yas/root-directory (list yas-snippet-directory
  2707. jpk-snippet-directory))
  2708.  
  2709. (with-library 'yas-jit
  2710. (yas/jit-load))
  2711. )
  2712.  
  2713. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2714. ;;; MISCELLANEOUS KEYBINDINGS
  2715. ;; the best way to find the symbol for a key is to run C-h k <key>
  2716.  
  2717. ;; use M-{ijkl} and C-M-{ijkl} like arrows
  2718. ;; integrates with CUA mode so shifted keys extend the region
  2719. (with-library 'ergo-movement-mode
  2720. (ergo-movement-mode 1))
  2721.  
  2722. ;; normally bound to C-<mouse-3>
  2723. (global-set-key (kbd "<down-mouse-3>") 'mouse-popup-menubar-stuff)
  2724.  
  2725. ;; macro record/playback
  2726. ;; by default, F4 stops recording or plays the last macro
  2727. ;; S-F4 starts recording
  2728. ;; also see "C-x (" and "C-x )"
  2729. (global-set-key (kbd "S-<f4>") 'kmacro-start-macro)
  2730.  
  2731. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2732. ;;; Changing case (capitalization)
  2733.  
  2734. ;; enable the region case changing commands
  2735. (put 'upcase-region 'disabled nil)
  2736. (put 'downcase-region 'disabled nil)
  2737.  
  2738. (defun downcase-region-or-word ()
  2739. "Downcase the current word if the region is inactive, otherwise
  2740. downcase the region."
  2741. (interactive)
  2742. (let ((deactivate-mark nil))
  2743. (if (use-region-p)
  2744. (downcase-region (region-beginning) (region-end))
  2745. (let ((bounds (bounds-of-thing-at-point 'word)))
  2746. (if bounds
  2747. (downcase-region (car bounds) (cdr bounds))
  2748. (message "Nothing to downcase."))))))
  2749.  
  2750. (defun upcase-region-or-word ()
  2751. "Upcase the current word if the region is inactive, otherwise
  2752. upcase the region."
  2753. (interactive)
  2754. (let ((deactivate-mark nil))
  2755. (if (use-region-p)
  2756. (upcase-region (region-beginning) (region-end))
  2757. (let ((bounds (bounds-of-thing-at-point 'word)))
  2758. (if bounds
  2759. (upcase-region (car bounds) (cdr bounds))
  2760. (message "Nothing to upcase."))))))
  2761.  
  2762. (defun capitalize-region-or-word ()
  2763. "Capitalize the current word if the region is inactive, otherwise
  2764. capitalize the region."
  2765. (interactive)
  2766. (let ((deactivate-mark nil))
  2767. (if (use-region-p)
  2768. (capitalize-region (region-beginning) (region-end))
  2769. (let ((bounds (bounds-of-thing-at-point 'word)))
  2770. (if bounds
  2771. (capitalize-region (car bounds) (cdr bounds))
  2772. (message "Nothing to capitalize."))))))
  2773.  
  2774. (global-set-key (kbd "C-x C-u") 'upcase-region-or-word)
  2775. (global-set-key (kbd "C-x C-i") 'capitalize-region-or-word)
  2776. (global-set-key (kbd "C-x C-l") 'downcase-region-or-word)
  2777. ;; (global-set-key (kbd "C-c c u") 'upcase-region-or-word)
  2778. ;; (global-set-key (kbd "C-c c c") 'capitalize-region-or-word)
  2779. ;; (global-set-key (kbd "C-c c d") 'downcase-region-or-word)
  2780. ;; (global-set-key (kbd "C-6") 'downcase-region-or-word)
  2781. ;; (global-set-key (kbd "M-6") 'capitalize-region-or-word)
  2782. ;; (global-set-key (kbd "C-^") 'upcase-region-or-word)
  2783.  
  2784. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2785. ;;; delete things
  2786.  
  2787. (require 'delete-things)
  2788.  
  2789. (with-library 'ergo-movement-mode
  2790. (global-set-key (kbd "C-S-d") (make-run-keybind-func "DEL" 'move))
  2791. (global-set-key (kbd "M-D") (make-run-keybind-func "C-<backspace>" 'move))
  2792. (global-set-key (kbd "M-d") (make-run-keybind-func "C-<delete>" 'move)))
  2793.  
  2794. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2795. ;;; Indentation
  2796.  
  2797. (defun indent-relative-dwim ()
  2798. "Indent the current line to either: the beginning of last
  2799. preceding line with text, the next tab stop (as determined by
  2800. tab-width, not tab-stop-list) after the previous indent, or the
  2801. beginning of the line. Repeatedly calling this function cycles
  2802. between these 3 actions."
  2803. (interactive)
  2804.  
  2805. (let ((last-line-indent 0)
  2806. (next-indent 0))
  2807.  
  2808. (save-excursion
  2809. (save-match-data
  2810. (beginning-of-line)
  2811. (when (re-search-backward "[^\t ]" nil t)
  2812. (beginning-of-line)
  2813. (re-search-forward "[^\t ]" nil t)
  2814. (goto-char (match-beginning 0))
  2815. (setq last-line-indent (current-column)))))
  2816. (setq next-indent (* (1+ (/ last-line-indent tab-width)) tab-width))
  2817.  
  2818. (cond
  2819. ((= (current-column) last-line-indent)
  2820. (indent-line-to next-indent))
  2821. ((= (current-column) next-indent)
  2822. (indent-line-to 0))
  2823. (t
  2824. (indent-line-to last-line-indent)))))
  2825.  
  2826. (setq-default indent-line-function 'indent-relative-dwim)
  2827.  
  2828. (global-set-key (kbd "C-m") 'newline-and-indent)
  2829.  
  2830. (defun set-tab-width (arg)
  2831. (interactive "nSet tab width: ")
  2832. (set-variable 'tab-width arg))
  2833.  
  2834. ;; in Emacs23, you can indent the region with a simple TAB
  2835. (unless (fboundp 'region-active-p)
  2836. ;; use-region-p is not built-in in emacs22 or earlier
  2837. (defun region-active-p ()
  2838. "Return t if Transient Mark mode is enabled and the mark is active.
  2839.  
  2840. Most commands that act on the region if it is active and
  2841. Transient Mark mode is enabled, and on the text near point
  2842. otherwise, should use `use-region-p' instead. That function
  2843. checks the value of `use-empty-active-region' as well."
  2844. (and transient-mark-mode mark-active))
  2845. (defcustom use-empty-active-region nil
  2846. "Whether \"region-aware\" commands should act on empty regions.
  2847. If nil, region-aware commands treat empty regions as inactive.
  2848. If non-nil, region-aware commands treat the region as active as
  2849. long as the mark is active, even if the region is empty.
  2850.  
  2851. Region-aware commands are those that act on the region if it is
  2852. active and Transient Mark mode is enabled, and on the text near
  2853. point otherwise."
  2854. :type 'boolean
  2855. :version "23.1"
  2856. :group 'editing-basics)
  2857. (defun use-region-p ()
  2858. "Return t if the region is active and it is appropriate to act on it.
  2859. This is used by commands that act specially on the region under
  2860. Transient Mark mode. It returns t if and only if Transient Mark
  2861. mode is enabled, the mark is active, and the region is non-empty.
  2862. If `use-empty-active-region' is non-nil, it returns t even if the
  2863. region is empty.
  2864.  
  2865. For some commands, it may be appropriate to disregard the value
  2866. of `use-empty-active-region'; in that case, use `region-active-p'."
  2867. (and (region-active-p)
  2868. (or use-empty-active-region (> (region-end) (region-beginning)))))
  2869.  
  2870. (defadvice indent-for-tab-command (around indent-dwim activate)
  2871. "If the region is active, run indent-region-function instead."
  2872. (if (use-region-p)
  2873. (let ((deactivate-mark nil))
  2874. (funcall indent-region-function (region-beginning) (region-end)))
  2875. ad-do-it))
  2876. )
  2877.  
  2878. ;; new buffers default to using 4 spaces for indent
  2879. (setq-default tab-width 8)
  2880. (setq-default indent-tabs-mode nil)
  2881.  
  2882. ;; mostly use spaces for indent, but sometimes you need tabs
  2883. (define-minor-mode smart-tab-mode
  2884. "Switches between using tabs and spaces for indenting."
  2885. :init-value nil
  2886. :lighter " Tab" ;; modeline indicator
  2887. (cond
  2888. (smart-tab-mode
  2889. (progn
  2890. ;;(setq indent-tabs-mode t)
  2891. ;;(setq tab-width 4)
  2892. (message "Tab mode")))
  2893.  
  2894. ((not smart-tab-mode)
  2895. (progn
  2896. ;;(setq indent-tabs-mode nil)
  2897. ;;(setq tab-width 8)
  2898. (message "Space mode")))))
  2899.  
  2900. (defmacro smart-tabs-advise (function offset)
  2901. "Wraps an indentation function to make it handle tabs in a
  2902. rational way. See http://www.emacswiki.org/emacs/SmartTabs"
  2903. `(progn
  2904. (defadvice ,function (around smart-tabs activate)
  2905. ;; honor per-buffer minor mode
  2906. (if (not smart-tab-mode)
  2907. ad-do-it
  2908. (save-excursion
  2909. (beginning-of-line)
  2910. (while (looking-at "\t*\\( +\\)\t+")
  2911. (replace-match "" nil nil nil 1)))
  2912. (setq tab-width tab-width)
  2913. (let ((indent-tabs-mode t)
  2914. (tab-width fill-column)
  2915. (,offset fill-column))
  2916. ad-do-it)))
  2917. ))
  2918.  
  2919. (smart-tabs-advise cperl-indent-line cperl-indent-level)
  2920. (smart-tabs-advise c-indent-line c-basic-offset)
  2921. (smart-tabs-advise c-indent-region c-basic-offset)
  2922. (smart-tabs-advise php-cautious-indent-region c-basic-offset)
  2923. (smart-tabs-advise php-cautious-indent-line c-basic-offset)
  2924.  
  2925. ;; shift-tab should undo what tab does
  2926. (global-set-key (kbd "<backtab>") 'delete-indentation)
  2927.  
  2928. ;; rigidly indent
  2929. ;; see EmacsWiki://MovingRegionHorizontally
  2930. (defun move-horizontally (beg en arg)
  2931. "Move the region defined by (beg en) by arg characters.
  2932. Positive arg means right; negative means left"
  2933. (save-excursion
  2934. (let ((deactivate-mark nil)
  2935. beg-bol)
  2936. (goto-char beg)
  2937. (setq beg-bol (line-beginning-position))
  2938. (goto-char en)
  2939. ;;(move-beginning-of-line nil)
  2940. (indent-rigidly beg-bol en arg)
  2941. (push-mark beg t t))))
  2942. (defun move-horizontally-dwim (beg en arg)
  2943. "If there is an active region, move the whole region arg
  2944. columns. Otherwise, move the cursor line arg columns."
  2945. (interactive "r")
  2946. (if (use-region-p)
  2947. (move-horizontally beg en arg)
  2948. (move-horizontally (line-beginning-position) (line-end-position) arg)))
  2949. (global-set-key (kbd "C-9")
  2950. (lambda (beg en)
  2951. "move region left by one"
  2952. (interactive "r")
  2953. (move-horizontally-dwim beg en -1)))
  2954. (global-set-key (kbd "C-0")
  2955. (lambda (beg en)
  2956. "move region right by one"
  2957. (interactive "r")
  2958. (move-horizontally-dwim beg en 1)))
  2959. (global-set-key (kbd "C-(")
  2960. (lambda (beg en)
  2961. "move region left by four"
  2962. (interactive "r")
  2963. (move-horizontally-dwim beg en -4)))
  2964. (global-set-key (kbd "C-)")
  2965. (lambda (beg en)
  2966. "move region right by four"
  2967. (interactive "r")
  2968. (move-horizontally-dwim beg en 4)))
  2969.  
  2970. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2971. ;;; drag-stuff
  2972.  
  2973. ;; drag things (words, regions, lines) with arrow keys
  2974. (add-to-list 'load-path (concat user-emacs-directory "drag-stuff"))
  2975. (with-library 'drag-stuff
  2976. (setq drag-stuff-modifier '(meta shift)))
  2977.  
  2978. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2979. ;;; Fill
  2980.  
  2981. ;; a smarter fill
  2982. ;; this can't be autoloaded, apparently
  2983. (require 'filladapt nil 'noerror)
  2984.  
  2985. ;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
  2986. (defun unfill-paragraph ()
  2987. "Takes a multi-line paragraph and makes it into a single line
  2988. of text."
  2989. (interactive)
  2990. (let ((fill-column (point-max)))
  2991. (fill-paragraph nil)))
  2992.  
  2993. (global-set-key (kbd "M-Q") 'unfill-paragraph)
  2994.  
  2995. (defadvice fill-paragraph (after scroll-to-left activate)
  2996. (scroll-right (window-hscroll)))
  2997.  
  2998. (defun align-regexp-repeated (start stop regexp)
  2999. "Like align-regexp, but repeated for multiple columns. See
  3000. http://www.emacswiki.org/emacs/AlignCommands"
  3001. (interactive "r\nsAlign regexp: ")
  3002. (let ((spacing 1)
  3003. (old-buffer-size (buffer-size)))
  3004. ;; If our align regexp is just spaces, then we don't need any
  3005. ;; extra spacing.
  3006. (when (string-match regexp " ")
  3007. (setq spacing 0))
  3008. (align-regexp start stop
  3009. ;; add space at beginning of regexp
  3010. (concat "\\([[:space:]]*\\)" regexp)
  3011. 1 spacing t)
  3012. ;; modify stop because align-regexp will add/remove characters
  3013. (align-regexp start (+ stop (- (buffer-size) old-buffer-size))
  3014. ;; add space at end of regexp
  3015. (concat regexp "\\([[:space:]]*\\)")
  3016. 1 spacing t)))
  3017.  
  3018. ;; see also fill-individual-paragraphs
  3019.  
  3020. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3021. ;;; scrolling
  3022.  
  3023. ;; pager makes scrolling makes scroll-up and scroll-down inverses (the
  3024. ;; point is in the same place after doing one and then the other).
  3025. (with-library 'pager
  3026. (global-set-key (kbd "<next>") 'pager-page-down)
  3027. (global-set-key (kbd "<prior>") 'pager-page-up)
  3028. (unless cua-enable-cua-keys
  3029. (global-set-key (kbd "C-v") 'pager-page-down)
  3030. (global-set-key (kbd "M-v") 'pager-page-up)))
  3031.  
  3032. ;; makes scrolling less jittery
  3033. (setq auto-window-vscroll nil
  3034. scroll-conservatively most-positive-fixnum
  3035. redisplay-dont-pause t
  3036. ;;smooth-scroll-margin 1 ;; what is this? was in custom.el
  3037. ;;scroll-step 0 ;; default
  3038. )
  3039.  
  3040. (put 'scroll-left 'disabled nil)
  3041. (setq auto-hscroll-mode-default auto-hscroll-mode)
  3042. (make-local-variable 'auto-hscroll-mode)
  3043.  
  3044. (setq hscroll-point-previous 0)
  3045. (make-local-variable 'hscroll-point-previous)
  3046.  
  3047. (defun detect-cursor-movement ()
  3048. (with-temp-message (current-message)
  3049. (let ((pt (point)))
  3050. (unless (= pt hscroll-point-previous)
  3051. (setq hscroll-point-previous pt)
  3052. (setq auto-hscroll-mode auto-hscroll-mode-default)
  3053. ;; a hack to make it apply on the first movement
  3054. (message nil)
  3055. ))))
  3056.  
  3057. (defvar cursor-movement-detector-timer nil
  3058. "Periodic timer that checks for cursor movement.")
  3059.  
  3060. (define-minor-mode smart-hscroll-mode
  3061. :init-value nil
  3062. :lighter nil
  3063.  
  3064. (when cursor-movement-detector-timer
  3065. (cancel-timer cursor-movement-detector-timer))
  3066. (when smart-hscroll-mode
  3067. (save-current-buffer
  3068. (dolist (buf (buffer-list))
  3069. (set-buffer buf)
  3070. (setq hscroll-point-previous (point))))
  3071. (setq cursor-movement-detector-timer
  3072. (run-with-idle-timer 0.1 t 'detect-cursor-movement))
  3073. ))
  3074. (smart-hscroll-mode 1)
  3075.  
  3076. (defun beginning-of-line-dwim (arg)
  3077. (interactive "p")
  3078. (if (bolp)
  3079. (beginning-of-line-text arg)
  3080. (move-beginning-of-line arg)))
  3081. (put 'beginning-of-line-dwim 'CUA 'move)
  3082. ;; <home> is still bound to move-beginning-of-line
  3083. (global-set-key (kbd "C-a") 'beginning-of-line-dwim)
  3084.  
  3085. (defun end-of-code-or-line ()
  3086. "Move to EOL. If already there, to EOL sans comments.
  3087. That is, the end of the code, ignoring any trailing comment
  3088. or whitespace. Note this does not handle 2 character
  3089. comment starters like // or /*. Such will not be skipped."
  3090. (interactive)
  3091. (if (not (eolp))
  3092. (end-of-line)
  3093. (skip-chars-backward " \t")
  3094. (let ((pt (point))
  3095. (lbp (line-beginning-position))
  3096. (comment-start-re (concat (regexp-quote
  3097. (replace-regexp-in-string
  3098. "[[:space:]]*" "" comment-start))
  3099. "\\|\\s<"))
  3100. (comment-stop-re "\\s>")
  3101. (lim))
  3102. (when (re-search-backward comment-start-re lbp t)
  3103. (setq lim (point))
  3104. (if (re-search-forward comment-stop-re (1- pt) t)
  3105. (goto-char pt)
  3106. (goto-char lim) ; test here ->
  3107. (while (looking-back comment-start-re (1- (point)))
  3108. (backward-char))
  3109. (skip-chars-backward " \t"))))))
  3110. (put 'end-of-code-or-line 'CUA 'move)
  3111. ;; <end> is still bound to end-of-visual-line
  3112. (global-set-key (kbd "C-e") 'end-of-code-or-line)
  3113.  
  3114. (defun force-scroll-left (&optional amount window)
  3115. "Disable auto-hscroll-mode when scrolling. This means that if
  3116. you use this function to scroll, the view will not snap back to
  3117. the cursor unless it moves."
  3118. (interactive)
  3119. (unless amount
  3120. (setq amount 4))
  3121. (unless window
  3122. (setq window (selected-window)))
  3123. (setq auto-hscroll-mode nil)
  3124. (scroll-left amount))
  3125.  
  3126. (defun force-scroll-left-8 ()
  3127. (interactive)
  3128. (force-scroll-left 8))
  3129.  
  3130. (defun force-scroll-right-8 ()
  3131. (interactive)
  3132. (force-scroll-left -8))
  3133.  
  3134. (require 'mwheel)
  3135. (defvar mouse-wheel-horiz-scroll-amount
  3136. '(4 ((shift) . 1) ((control) . 0.25))
  3137. "Amount to scroll windows by when spinning the mouse wheel.
  3138. Similar to `mouse-wheel-scroll-amount'. This is an alist mapping
  3139. the modifier key to the amount to scroll when the wheel is moved
  3140. with the modifier key depressed. Elements of the list have the
  3141. form (MODIFIERS . AMOUNT) or just AMOUNT if MODIFIERS is nil.
  3142. Meta has no effect.")
  3143.  
  3144. (defun mwheel-scroll-horiz (event)
  3145. "Scroll left or right according to the EVENT.
  3146. This should only be bound to mouse buttons 4 and 5."
  3147. (interactive (list last-input-event))
  3148. (let* ((mousewin (mwheel-event-window event))
  3149. (curwin (when mouse-wheel-follow-mouse
  3150. (prog1 (selected-window)
  3151. (select-window mousewin))))
  3152. (buffer (window-buffer curwin))
  3153. (opoint (with-current-buffer buffer
  3154. (when (eq (car-safe transient-mark-mode) 'only)
  3155. (point))))
  3156. (mods
  3157. (delq 'meta (delq 'click (delq 'double (delq 'triple (event-modifiers event))))))
  3158. (amt (assoc mods mouse-wheel-horiz-scroll-amount)))
  3159. ;; Extract the actual amount or find the element that has no modifiers.
  3160. (if amt (setq amt (cdr amt))
  3161. (let ((list-elt mouse-wheel-horiz-scroll-amount))
  3162. (while (consp (setq amt (pop list-elt))))))
  3163. (if (floatp amt) (setq amt (1+ (truncate (* amt (window-width))))))
  3164. (unwind-protect
  3165. (let ((button (mwheel-event-button event)))
  3166. (cond ((eq button mouse-wheel-down-event)
  3167. (condition-case nil (force-scroll-left (- amt))))
  3168. ((eq button mouse-wheel-up-event)
  3169. (condition-case nil (force-scroll-left amt)))
  3170. (t (error "Bad binding in mwheel-scroll-horiz"))))
  3171. (if curwin (select-window curwin)))
  3172. ;; If there is a temporarily active region, deactivate it iff
  3173. ;; scrolling moves point.
  3174. (when opoint
  3175. (with-current-buffer buffer
  3176. (when (/= opoint (point))
  3177. (deactivate-mark)))))
  3178. (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time)
  3179. (if mwheel-inhibit-click-event-timer
  3180. (cancel-timer mwheel-inhibit-click-event-timer)
  3181. (add-hook 'pre-command-hook 'mwheel-filter-click-events))
  3182. (setq mwheel-inhibit-click-event-timer
  3183. (run-with-timer mouse-wheel-inhibit-click-time nil
  3184. 'mwheel-inhibit-click-timeout))))
  3185.  
  3186. (global-set-key (kbd "<M-mouse-4>") 'mwheel-scroll-horiz)
  3187. (global-set-key (kbd "<M-mouse-5>") 'mwheel-scroll-horiz)
  3188. (global-set-key (kbd "<C-M-mouse-4>") 'mwheel-scroll-horiz)
  3189. (global-set-key (kbd "<C-M-mouse-5>") 'mwheel-scroll-horiz)
  3190. (global-set-key (kbd "<S-M-mouse-4>") 'mwheel-scroll-horiz)
  3191. (global-set-key (kbd "<S-M-mouse-5>") 'mwheel-scroll-horiz)
  3192.  
  3193. ;; these are generally the horizontal nudges on a scroll wheel
  3194. (global-set-key (kbd "<mouse-7>") 'force-scroll-left-8)
  3195. (global-set-key (kbd "<mouse-6>") 'force-scroll-right-8)
  3196.  
  3197. (global-set-key (kbd "C-<next>") 'force-scroll-left-8)
  3198. (global-set-key (kbd "C-<prior>") 'force-scroll-right-8)
  3199.  
  3200. ;; scroll the other buffer
  3201. (global-set-key (kbd "S-<next>") 'scroll-other-window)
  3202. (global-set-key (kbd "S-<prior>") 'scroll-other-window-down)
  3203.  
  3204. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3205. ;;; convert between different EOL modes
  3206.  
  3207. (defun dos2unix ()
  3208. "Convert a DOS file ('\\r\\n') to Unix ('\\n')"
  3209. (interactive)
  3210. (set-buffer-file-coding-system 'undecided-unix t))
  3211.  
  3212. (defun force-unix-line-endings ()
  3213. "Replace all occurances of \\r\\n with \\n."
  3214. (interactive)
  3215. (save-excursion
  3216. (goto-char (point-min))
  3217. (while (search-forward "\015\012" nil t)
  3218. (replace-match "\012" nil t))))
  3219.  
  3220. (defun unix2dos ()
  3221. "Convert a Unix ('\n') file to DOS ('\r\n')"
  3222. (interactive)
  3223. (set-buffer-file-coding-system 'undecided-dos t))
  3224.  
  3225. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3226. ;;; 123-menu
  3227.  
  3228. (autoload '123-menu-display-menu-root-menu "123-menu.el"
  3229. "Display a simple text menu in the minibuffer." t)
  3230. (global-set-key (kbd "C-`") '123-menu-display-menu-root-menu)
  3231.  
  3232. (eval-after-load "123-menu.el"
  3233. '(progn
  3234. (123-menu-defmenu
  3235. breadcrumb-menu
  3236. ("m" "[m] Make breadcrumb" 'bc-set)
  3237. ("p" "[p] Goto previous" 'bc-previous)
  3238. ("n" "[n] Goto next" 'bc-next)
  3239. ("P" "[P] Goto previous in this buffer" 'bc-local-previous)
  3240. ("N" "[N] Goto next in this buffer" 'bc-local-next)
  3241. ("c" "[c] Goto current" 'bc-goto-current)
  3242. ("l" "[l] List breadcrumbs" 'bc-list)
  3243. ("X" "[X] Clear All" 'bc-clear)
  3244. )
  3245.  
  3246. (123-menu-defmenu
  3247. display-menu
  3248. ("l" "[l] Toggle Line numbers" 'linum-mode)
  3249. ("s" "[s] Toggle visible whitespace" 'whitespace-mode)
  3250. ("w" "[w] Visual Line mode (word-wrap)" 'visual-line-mode)
  3251. ("m" "[m] Menu Bar mode" 'menu-bar-mode)
  3252. )
  3253.  
  3254. (123-menu-defmenu
  3255. misc-menu
  3256. ("r" "[r] remember" 'remember)
  3257. ("e" "[e] Find init.el" 'find-user-init-file)
  3258. ("i" "[i] Toggle input method" 'toggle-input-method)
  3259. ("c" "[c] Interactive ELisp console" 'ielm)
  3260. ("t" "[t] Start timer" 'elapsed-time-start)
  3261. ("T" "[T] Print elapsed time" (lambda () (interactive)
  3262. (message "Elapsed time: %0.3f s." (elapsed-time))))
  3263. ("v" "[v] Toggle save-visited-files-mode" 'save-visited-files-mode)
  3264. ("a" "[a] Toggle auto-complete-mode" 'auto-complete-mode)
  3265. )
  3266.  
  3267. (123-menu-defmenu
  3268. format-menu
  3269. ("t" "[t] Smart Tab mode" 'smart-tab-mode)
  3270. ("w" "[w] Set tab width" 'set-tab-width)
  3271. ("q" "[q] Autofill mode" 'auto-fill-mode)
  3272. )
  3273.  
  3274. (123-menu-defmenu-repeated
  3275. window-history-menu
  3276. ("p" "[p] Previous window configuration" 'window-config-history-backward)
  3277. ("n" "[n] Next window configuration" 'window-config-history-forward)
  3278. )
  3279.  
  3280. (123-menu-defmenu-repeated
  3281. buf-move-menu
  3282. ("i" "[i] Move buffer up" 'buf-move-up)
  3283. ("j" "[j] Move buffer right" 'buf-move-left)
  3284. ("k" "[k] Move buffer down" 'buf-move-down)
  3285. ("l" "[l] Move buffer left" 'buf-move-right)
  3286. )
  3287.  
  3288. (123-menu-defmenu-repeated
  3289. nav-menu
  3290. ("i" "[i] up line" 'previous-line)
  3291. ("j" "[j] left char" 'backward-char)
  3292. ("k" "[k] down line" 'next-line)
  3293. ("l" "[l] right char" 'forward-char)
  3294. ("u" "[u] scroll up" 'cua-scroll-down)
  3295. ("o" "[o] scroll down" 'cua-scroll-up)
  3296. ("C-i" "[C-i] up para" 'backward-paragraph)
  3297. ("C-j" "[C-j] left word" 'c-backward-subword)
  3298. ("C-k" "[C-k] down para" 'forward-paragraph)
  3299. ("C-l" "[C-l] right word" 'c-forward-subword)
  3300. ("C-u" "[C-u] scroll left" 'force-scroll-right-8)
  3301. ("C-o" "[C-o] scroll right" 'force-scroll-left-8)
  3302. )
  3303.  
  3304. (123-menu-defmenu
  3305. root-menu
  3306. ("b" "[b] Breadcrumbs" '123-menu-display-menu-breadcrumb-menu)
  3307. ("d" "[d] Display options" '123-menu-display-menu-display-menu)
  3308. ("f" "[f] Formatting" '123-menu-display-menu-format-menu)
  3309. ("h" "[h] Window Config History" '123-menu-display-menu-window-history-menu)
  3310. ("m" "[m] Miscellaneous" '123-menu-display-menu-misc-menu)
  3311. ("n" "[n] Navigation" '123-menu-display-menu-nav-menu)
  3312. ("w" "[w] Move Buffers in Windows" '123-menu-display-menu-buf-move-menu)
  3313. )
  3314. ))
  3315.  
  3316. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3317. ;;; host-specific stuff
  3318. (load (concat user-emacs-directory "host.el") 'noerror)
  3319.  
  3320. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3321.  
  3322. (message "jpkotta's init.el loaded")
  3323. (message "init.el loaded in %0.3f s." (toc init-el-time))
Add Comment
Please, Sign In to add comment