/ emacs
emacs
  1  ;;;
  2  ;;; sjs' emacs config
  3  ;;;
  4  
  5  
  6  ;; feel out the system
  7  (defvar macosx-p (string-match "darwin" (symbol-name system-type)))
  8  (defvar linux-p (string-match "gnu/linux" (symbol-name system-type)))
  9  
 10  
 11  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 12  ;; setup load paths 
 13  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 14  
 15  (defun add-to-load-path (file)
 16    "Add FILE to `load-path' if it is readable."
 17    (if (file-readable-p file)
 18        (add-to-list 'load-path file)))
 19  
 20  (add-to-load-path "~/config/emacs.d")
 21  
 22  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 23  ;; global config
 24  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 25  
 26  (setq inhibit-startup-message t)
 27  (setq make-backup-files nil)
 28  (global-subword-mode 1)
 29  
 30  (setq auto-revert-interval 2)
 31  (global-auto-revert-mode t)
 32  
 33  
 34  ;; map cmd to meta (Emacs.app 23.2)
 35  (when macosx-p
 36    (setq mac-option-key-is-meta nil)
 37    (setq mac-command-key-is-meta t)
 38    (setq mac-command-modifier 'meta)
 39    (setq mac-option-modifier 'super))
 40  
 41  ;; keep a list of recently visited files
 42  (require 'recentf)
 43  (recentf-mode 1)
 44  
 45  ;; remember my position in files
 46  (require 'saveplace)
 47  (setq-default save-place t)
 48  
 49  ;; always highlight syntax
 50  (global-font-lock-mode t)
 51  (setq font-lock-maximum-decoration t)   ; highlight liberally
 52  
 53  (autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
 54  (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
 55  
 56  ;; always start emacs server
 57  (server-start)
 58  
 59  ;; setup tramp mode
 60  ;; (setq tramp-default-method "ssh")
 61  
 62  ;; complete like zsh's complete-in-word option (p-b expands to print-buffer)
 63  (load "complete")
 64  
 65  ;; show the date & time in the mode line
 66  (setq display-time-day-and-date t)
 67  (display-time)
 68  
 69  (setq track-eol t)               ; When at EOL, C-n and C-p move to EOL on other lines
 70  (setq indent-tabs-mode nil)      ; never insert tabs
 71  
 72  ;; nav - awesome filesystem navigation, sort of like TextMate's project drawer
 73  (add-to-load-path "~/config/emacs.d/emacs-nav")
 74  (require 'nav)
 75  
 76  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 77  ;; peepopen and textmate mode
 78  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 79  
 80  (add-to-list 'load-path "~/.emacs.d/vendor/")
 81  (require 'textmate)
 82  (require 'peepopen)
 83  (textmate-mode)
 84  
 85  ;; open files in current frame
 86  (setq ns-pop-up-frames nil)
 87  
 88  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 89  ;; minimap
 90  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 91  
 92  (require 'minimap)
 93  
 94  
 95  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 96  ;; undo-tree
 97  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 98  
 99  (require 'undo-tree)
100  (global-undo-tree-mode)
101  
102  
103  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104  ;; c
105  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106  
107  (setq c-mode-hook
108      (function (lambda ()
109                  (setq indent-tabs-mode nil)
110                  (setq c-indent-level 4))))
111  
112  (setq objc-mode-hook
113      (function (lambda ()
114                  (setq indent-tabs-mode nil)
115                  (setq c-indent-level 4))))
116  
117  ;; Make a non-standard key binding.  We can put this in
118  ;; c-mode-base-map because c-mode-map, c++-mode-map, and so on,
119  ;; inherit from it.
120  (defun sjs-c-initialization-hook ()
121    (define-key c-mode-base-map "\r" 'newline-and-indent)) ; auto indent after inserting newline
122  (add-hook 'c-initialization-hook 'sjs-c-initialization-hook)
123  
124  ;; Create my personal style.
125  (defconst my-c-style
126    '("linux"
127      (c-tab-always-indent        . t)
128      (c-basic-offset             . 4)
129      (c-cleanup-list             . (brace-else-brace
130      				   brace-elseif-brace
131      				   brace-catch-brace
132      				   defun-close-semi)))
133    "how sjs likes his C")
134  (c-add-style "sjs" my-c-style)
135  
136  ;; Customizations for all modes in CC Mode.
137  (defun sjs-c-mode-common-hook ()
138    ;; set my personal style for the current buffer
139    (c-set-style "sjs")
140    ;; other customizations
141    (setq tab-width 4
142          ;; this will make sure spaces are used instead of tabs
143          indent-tabs-mode nil
144  	c-syntactic-indentation t
145          c-tab-always-indent t)
146    (c-toggle-auto-newline 1))
147  ;;   (setq skeleton-pair t)
148  ;;   (setq skeleton-autowrap t)
149  ;;   (let ((chars '("'" "\"" "(" "[" "{")))
150  ;;     (mapcar (lambda (char)
151  ;; 	      (local-set-key char 'skeleton-pair-insert-maybe)) chars))
152  (add-hook 'c-mode-common-hook 'sjs-c-mode-common-hook)
153  
154  
155  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
156  ;; shell
157  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
158  
159  ;; chmod u+x files that have a shebang line
160  (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
161  
162  (add-to-list 'auto-mode-alist '("zshenv$" . sh-mode))
163  (add-to-list 'auto-mode-alist '("zshrc$" . sh-mode))
164  
165  
166  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
167  ;; ruby
168  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
169  
170  ;; Based on http://infolab.stanford.edu/~manku/dotemacs.html
171  (autoload 'ruby-mode "ruby-mode"
172      "Mode for editing ruby source files")
173  (autoload 'ruby-electric-mode "ruby-electric"
174      "Mode for automatically inserting end and such for Ruby")
175  (add-to-list 'auto-mode-alist '("\\.rb$" . ruby-mode))
176  (add-to-list 'interpreter-mode-alist '("ruby" . ruby-mode))
177  (autoload 'run-ruby "inf-ruby"
178      "Run an inferior Ruby process")
179  (autoload 'inf-ruby-keys "inf-ruby"
180      "Set local key defs for inf-ruby in ruby-mode")
181  (add-hook 'ruby-mode-hook
182       '(lambda ()
183           (inf-ruby-keys)
184  	 (ruby-electric-mode)))
185  (autoload 'rubydb "rubydb3x" "Ruby debugger" t)
186  
187  (add-to-list 'auto-mode-alist '(".irbrc$" . ruby-mode))
188  
189  
190  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
191  ;; haskell
192  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
193  
194  (if (file-readable-p "~/.emacs.d/haskell/haskell-site-file.el")
195    (load "~/.emacs.d/haskell/haskell-site-file.el" nil t))
196  
197  
198  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
199  ;; rails
200  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
201  
202  ;(require 'rails)
203  
204  
205  ;; wraps selected text with the given tag or inserts the tag if nothing selected
206  (require 'tagify)
207  
208  
209  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
210  ;; javascript
211  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
212  
213  ;; js-mode (espresso)
214  ;; Espresso mode has sane indenting so we use that.
215  (setq js-indent-level 2)
216  
217  ;; Customize JS2
218  (setq js2-basic-offset 2)
219  (setq js2-cleanup-whitespace t)
220  
221  (autoload 'js2-mode "js2-mode" nil t)
222  (add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
223  (add-to-list 'auto-mode-alist '("Jakefile$" . js2-mode))
224  (add-hook 'js2-mode-hook (lambda () (slime-js-minor-mode 1)))
225  (global-set-key [f5] 'slime-js-reload)
226  
227  ;; Custom indentation function since JS2 indenting is terrible.
228  ;; Uses js-mode's (espresso-mode) indentation semantics.
229  ;;
230  ;; Based on: http://mihai.bazon.net/projects/editing-javascript-with-emacs-js2-mode
231  ;; (Thanks!)
232  (defun my-js2-indent-function ()
233    (interactive)
234    (save-restriction
235      (widen)
236      (let* ((inhibit-point-motion-hooks t)
237             (parse-status (save-excursion (syntax-ppss (point-at-bol))))
238             (offset (- (current-column) (current-indentation)))
239             (indentation (js--proper-indentation parse-status))
240             node)
241  
242        (save-excursion
243  
244          ;; I like to indent case and labels to half of the tab width
245          (back-to-indentation)
246          (if (looking-at "case\\s-")
247              (setq indentation (+ indentation (/ js-indent-level 2))))
248  
249          ;; consecutive declarations in a var statement are nice if
250          ;; properly aligned, i.e:
251          ;;
252          ;; var foo = "bar",
253          ;;     bar = "foo";
254          (setq node (js2-node-at-point))
255          (when (and node
256                     (= js2-NAME (js2-node-type node))
257                     (= js2-VAR (js2-node-type (js2-node-parent node))))
258            (setq indentation (+ 4 indentation))))
259  
260        (indent-line-to indentation)
261        (when (> offset 0) (forward-char offset)))))
262  
263  (defun my-js2-mode-hook ()
264    (if (not (boundp 'js--proper-indentation))
265        (progn (js-mode)
266               (remove-hook 'js2-mode-hook 'my-js2-mode-hook)
267               (js2-mode)
268               (add-hook 'js2-mode-hook 'my-js2-mode-hook)))
269    (set (make-local-variable 'indent-line-function) 'my-js2-indent-function)
270    (define-key js2-mode-map [(return)] 'newline-and-indent)
271    (define-key js2-mode-map [(backspace)] 'c-electric-backspace)
272    (define-key js2-mode-map [(control d)] 'c-electric-delete-forward)
273    (local-set-key "\C-m" 'newline)
274    (setq indent-tabs-mode nil)
275    (message "JS2 mode hook ran."))
276  
277  ;; Add the hook so this is all loaded when JS2-mode is loaded
278  (add-hook 'js2-mode-hook 'my-js2-mode-hook)
279  
280  (autoload #'espresso-mode "espresso" "Start espresso-mode" t)
281  (add-to-list 'auto-mode-alist '("\\.json$" . espresso-mode))
282  
283  
284  ;; coffee script
285  (require 'coffee-mode)
286  
287  ;; mustache
288  (require 'mustache-mode)
289  
290  
291  ;; css
292  (setq css-mode-hook (lambda () (setq indent-tabs-mode nil)))
293  
294  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
295  ;; mojo (webos)
296  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
297  
298  ;(require 'mojo)
299  
300  ;; enable Mojo for CSS, HTML, JS, and JSON files within a Mojo project
301  ;; root.  Did I forget anything?
302  ;(mojo-setup-mode-hooks 'css-mode-hook 'js2-mode-hook 'espresso-mode-hook 'html-mode-hook)
303  
304  
305  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
306  ;; inferior javascript
307  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
308  
309  (require 'js-comint)
310  ;(setq inferior-js-program-command "/usr/local/bin/v8")
311  (setq inferior-js-program-command "/opt/local/bin/js -v 1.8")
312  (add-hook 'js2-mode-hook '(lambda ()
313  			    (local-set-key "\C-x\C-e" 'js-send-last-sexp)
314  			    (local-set-key "\C-\M-x" 'js-send-last-sexp-and-go)
315  			    (local-set-key "\C-cb" 'js-send-buffer)
316  			    (local-set-key "\C-c\C-b" 'js-send-buffer-and-go)
317  			    (local-set-key "\C-cl" 'js-load-file-and-go)
318  			    ))
319  
320  
321  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
322  ;; python
323  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
324  
325  ;; handy but ugly as fuck
326  (autoload 'whitespace-mode "whitespace"
327    "Toggle whitespace visualization." t)
328  
329  
330  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
331  ;; erlang
332  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
333  
334  (when (file-exists-p "/opt/local/lib/erlang")
335    (setq load-path (cons "/opt/local/lib/erlang/lib/tools-2.6.5/emacs" load-path))
336    (setq erlang-root-dir "/opt/local/lib/erlang/otp")
337    (setq exec-path (cons "/opt/local/lib/erlang/bin" exec-path))
338    (require 'erlang-start))
339  
340  
341  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
342  ;; markup
343  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
344  
345  ;; (require 'textile-mode)
346  ;; (add-to-list 'auto-mode-alist '("\\.textile\\'" . textile-mode))
347  
348  (require 'yaml-mode)
349  (add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))
350  
351  
352  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
353  ;; lisp and scheme
354  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
355  
356  ;; recognize my non-standard emacs config location
357  (add-to-list 'auto-mode-alist '("config/emacs$" . emacs-lisp-mode))
358  
359  ;; use ElSchemo as the default scheme
360  (setq scheme-program-name "~/Projects/elschemo/elschemo")
361  
362  ;; use sbcl for lisp
363  (setq inferior-lisp-program "/usr/bin/env sbcl")
364  
365  ;; setup slime
366  (when (file-exists-p "~/.slime")
367    (add-to-list 'load-path "~/.slime")
368    (require 'slime)
369    (slime-setup '(slime-repl slime-js))
370    (add-hook 'lisp-mode-hook (lambda () (slime-mode t)))
371    (add-hook 'scheme-mode-hook (lambda () (slime-mode t)))
372    (add-hook 'inferior-lisp-mode-hook (lambda () (inferior-slime-mode t)))
373    (add-hook 'inferior-scheme-mode-hook (lambda () (inferior-slime-mode t))))
374  
375  
376  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
377  ;; key bindings
378  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
379  
380  ;; Unhijack Cmd-H
381  (global-set-key [(super h)] 'mark-paragraph)
382  (global-set-key "\M-h" 'ns-do-hide-emacs)
383  
384  ;; always use regexp searching
385  (global-set-key "\C-s" 'isearch-forward-regexp)
386  (global-set-key "\C-r" 'isearch-backward-regexp)
387  
388  ;; custom key bindings under a common prefix
389  ;; (Suspend is useless. Give me C-z!)
390  (global-unset-key "\C-z")
391  (global-set-key "\C-z" nil)
392  (global-set-key "\C-zc" 'compile)
393  (global-set-key "\C-zf" 'find-file-at-point)
394  (global-set-key "\C-zg" 'goto-line)
395  (global-set-key "\C-zj" 'run-js)
396  (global-set-key "\C-zl" 'duplicate-line)
397  (global-set-key "\C-zm" 'minimap-create)
398  (global-set-key "\C-zM" 'minimap-kill)
399  (global-set-key "\C-zr" 'query-replace-regexp)
400  (global-set-key "\C-zs" 'run-scheme)
401  (global-set-key "\C-zt" 'tagify-region-or-insert-tag)
402  (global-set-key "\C-zz" 'shell)         ; z for zsh
403  (global-set-key "\C-z\C-r" 'reload-dot-emacs)
404  (global-set-key "\C-z\C-t" 'totd)
405  
406  ;; extend Emacs' default key binding space
407  (global-set-key [(super b)] 'bs-show)    ; use the buffer list buffer menu
408  (global-set-key "\C-x\C-r" 'recentf-find-files-compl) ; unused, remove?
409  
410  ;; use the X clipboard for cut/copy/paste
411  (global-set-key "\C-w" 'clipboard-kill-region)
412  (global-set-key "\M-w" 'clipboard-kill-ring-save)
413  (global-set-key "\C-y" 'clipboard-yank)
414  
415  ;; wrap a region with an HTML/XML tag
416  (global-set-key "<"  'tagify-region-or-insert-self)
417  
418  ;; Select the enclosed parens/brackets/braces
419  (global-set-key "\M-B" 'select-enclosing-pair)
420  
421  (when macosx-p
422    ;; nice OS X keyboard behaviors that save my pinky too
423    (defun save-the-pinky-buffer () (interactive) (message "Save your pinky! Use s-b (Opt-b) instead."))
424    (defun save-the-pinky-open   () (interactive) (message "Save your pinky! Use M-o (Cmd-o) instead."))
425    (defun save-the-pinky-save   () (interactive) (message "Save your pinky! Use M-s (Cmd-s) instead."))
426    (defun save-the-pinky-undo   () (interactive) (message "Save your pinky! Use M-z (Cmd-z) instead."))
427    (defun save-the-pinky-window () (interactive) (message "Save your pinky! Use M-` (Cmd-`) instead."))
428    (global-set-key "\C-_" 'save-the-pinky-undo)
429    (global-set-key "\C-x\C-f" 'save-the-pinky-open)
430    (global-set-key "\C-xo" 'save-the-pinky-window)
431    (global-set-key "\C-x\C-s" 'save-the-pinky-save)
432    (global-set-key "\C-x\C-b" 'save-the-pinky-buffer)
433    
434    (global-set-key "\M-n" 'new-frame)
435    (global-set-key "\M-o" 'find-file)
436    (global-set-key "\M-s" 'save-buffer)
437    (global-set-key "\M-z" 'undo)
438    (global-set-key [(meta down)] 'end-of-buffer)
439    (global-set-key [(meta up)] 'beginning-of-buffer)
440    (global-set-key [(meta right)] 'end-of-line)
441    (global-set-key [(meta left)] 'beginning-of-line)
442  
443    ;; can't seem to un-hijack cmd-`, so make it do something useful
444    (global-set-key "\M-`" 'other-window-in-any-frame)
445  
446    ;; find files like textmate
447    (global-set-key "\M-F" 'textmate-find-regex-in-project)
448  )
449  
450  
451  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
452  ;; utilities & customizations
453  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
454  
455  (defun duplicate-line (&optional arg)
456      "Duplicate the current line."
457      (interactive "p")
458      (save-excursion
459        (move-beginning-of-line nil)
460        (let ((beg (point)))
461  	(move-end-of-line nil)
462  	(let* ((end (point))
463  	       (txt (buffer-substring beg end)))
464  	  (newline)
465  	  (insert txt)))))
466  
467  ;; switch to the next window, in any visible frame
468  (defun other-window-in-any-frame (&optional arg)
469    "Switch to the next window using `next-window', with ALL-FRAMES
470  set to 'visible.  If the next window is on a different frame
471  switch to that frame first using `select-frame-set-input-focus'.
472  
473  If N is non-nil switch to the nth next window."
474    (interactive "p")
475    (setq arg (or arg 1))
476    (let ((gt-or-lt (if (> arg 0) #'> #'<))
477  	(sign (if (> arg 0) 1 -1)))
478      (while (apply gt-or-lt arg '(0))
479        (let ((window (if (= sign 1)
480  			(next-window (selected-window) nil 'visible)
481  		      (previous-window (selected-window) nil 'visible))))
482  	(when (not (member window (window-list)))
483  	  (dolist (frame (delq (selected-frame) (frame-list)))
484  	    (when (member window (window-list frame))
485  	      (select-frame-set-input-focus frame))))
486  	(select-window window))
487        (setq arg (- arg sign)))))
488  
489  ;; Reload the .emacs file with a minimum of effort,
490  ;; first saving histories with Persistent
491  (defun reload-dot-emacs () (interactive)
492    "If there is a buffer named .emacs save it. Reload ~/.emacs if it exists."
493    (if (get-buffer "emacs")
494      (save-excursion
495        (set-buffer "emacs")
496        (save-buffer)))
497    (if (file-exists-p "~/config/emacs")
498      (load-file "~/config/emacs")))
499  
500  ;; find recently visited files quickly
501  (defun recentf-find-files-compl ()
502    "Find a file that has recently been visited."
503    (interactive)
504    (let* ((all-files recentf-list)
505       (tocpl (mapcar (function
506       (lambda (x) (cons (file-name-nondirectory x) x))) all-files))
507       (prompt (append '("Recent file name: ") tocpl))
508       (fname (completing-read (car prompt) (cdr prompt) nil nil)))
509       (find-file (or (cdr (assoc fname tocpl))
510                      fname))))
511  
512  
513  ;; If it's not nailed down, steal it! This tries to mimic TextMate's
514  ;; select enclosing braces function. Very handy.
515  
516  ;; It would be nice to take quotes into account but the current
517  ;; algorithm doesn't play nice with pairs that are equal.
518  (defvar select-enclosing-pair-default-pairs
519    "Pairs of characters to look for when marking an enclosed region."
520    '((?( ?)) (?[ ?]) (?{ ?}) (?< ?>)))
521  
522  ;; Well, it's ugly as sin but it works in simple cases. Needs a
523  ;; smarter algorithm to work in more situations. One example that
524  ;; doesn't work with this algo: (something "<" 'other-stuff)
525  ;;
526  ;; FIXME there's at least one off-by-one error with the ignore-count
527  (defun select-enclosing-pair (&optional n pairs)
528    "Select text between the innermost pair of characters given in
529  PAIRS, defaults are: (), [], {}, <>."
530    (interactive "p")
531    ;; FIXME use the n parameter. recursion? iteration?
532    (let* ((pairs (or pairs select-enclosing-pair-default-pairs))
533           (opening-chars (mapcar 'car pairs))
534           (closing-chars (mapcar 'cadr pairs))
535           (original-position (point))
536           (opening-index original-position)
537           (closing-index original-position)
538           (i (1- original-position))
539           (len (buffer-size))
540           (opening-char (char-after i))
541           (closing-char (char-after original-position))
542           (opening-char-pos (position opening-char opening-chars))
543           (closing-char-pos (position closing-char closing-chars))
544           (ignore-count (if (position opening-char closing-chars) 1 0)))
545      ;; (message "----")
546      (while (and opening-char
547                  (or (not opening-char-pos)
548                      (> ignore-count 0)))
549        ;; (message "char at %d is %c" i opening-char)
550        (when (and opening-char-pos (> ignore-count 0))
551          (decf ignore-count))
552        (decf i)
553        (setq opening-char (char-after i))
554        (setq opening-char-pos (position opening-char opening-chars))
555        (when (position opening-char closing-chars)
556          (incf ignore-count)))
557      ;; (message "opening-char: %c i: %d" opening-char i)
558      (when (and opening-char
559                 (position opening-char opening-chars))
560        (setq opening-index i))
561      ;;   (message "start: %d char: %c" i opening-char))
562      ;; (message "char at %d is %s" i opening-char)
563  
564      ;; (message "----")
565      ;; (message "closing-chars: %s" closing-chars)
566      (when (and opening-char opening-char-pos)
567        (setq i original-position)
568        (setq ignore-count (if (position closing-char opening-chars) 1 0))
569        (while (and closing-char
570                    (or (not closing-char-pos)
571                        (> ignore-count 0)
572                        (not (= opening-char-pos closing-char-pos))))
573          ;; (message "closing-char: %s (position closing-char closing-chars): %s" closing-char (position closing-char closing-chars))
574          ;; (message "char at %d is %c" i closing-char)
575          (when (and closing-char-pos (> ignore-count 0))
576            (decf ignore-count))
577          (incf i)
578          (setq closing-char (char-after i))
579          (setq closing-char-pos (position closing-char closing-chars))
580          (when (position closing-char opening-chars)
581            (incf ignore-count)))
582        ;; (message "closing-char: %s i: %d " closing-char i)
583        (when (and closing-char
584                   closing-char-pos
585                   (= opening-char-pos closing-char-pos))
586          (setq closing-index i))
587        ;;   (message "end: %d char: %c" i closing-char))
588        ;; (message "char at %d is %s" i closing-char)
589        ;; (message "----")
590        (when (and opening-char closing-char
591                   opening-char-pos closing-char-pos
592                   (not (= opening-index closing-index))
593                   (= opening-char-pos closing-char-pos))
594          ;; (message "doing it")
595          (push-mark opening-index 'nomsg t)
596          (goto-char (1+ closing-index))))))
597  
598  (cond ((file-readable-p "~/.emacs.d/color-theme")
599         (add-to-list 'load-path "~/.emacs.d/color-theme")
600         (require 'color-theme)
601  
602  ;; dark themes
603  ;; (color-theme-charcoal-black) ;; pastels, low contrast ***
604  ;; (color-theme-midnight)       ;; grey comments, so-so ***
605  ;; (color-theme-taylor)            ;; beige text, orange comments ****
606  (when (file-readable-p "~/.emacs.d/color-theme-tangotango.el")
607    (require 'color-theme-tangotango)
608    (color-theme-tangotango))            ;; beige text, orange comments ****
609  ))
610  
611  (defun totd ()
612    (interactive)
613    (with-output-to-temp-buffer "*Tip of the day*"
614      (let* ((commands (loop for s being the symbols
615                             when (commandp s) collect s))
616             (command (nth (random (length commands)) commands)))
617        (princ
618         (concat "Your tip for the day is:\n"
619                 "========================\n\n"
620                 (describe-function command)
621                 "\n\nInvoke with:\n\n"
622                 (with-temp-buffer
623                   (where-is command t)
624                   (buffer-string)))))))
625  
626  
627  (custom-set-variables
628    ;; custom-set-variables was added by Custom.
629    ;; If you edit it by hand, you could mess it up, so be careful.
630    ;; Your init file should contain only one such instance.
631    ;; If there is more than one, they won't work right.
632   '(c-hanging-semi&comma-criteria (quote set-from-style))
633   '(case-fold-search t)
634   '(column-number-mode t)
635   '(current-language-environment "UTF-8")
636   '(default-input-method "rfc1345")
637   '(display-time-mode t)
638   '(face-font-family-alternatives (quote (("bistream vera sans mono" "courier" "fixed") ("helv" "helvetica" "arial" "fixed"))))
639   '(global-font-lock-mode t nil (font-lock))
640   '(icicle-reminder-prompt-flag 5)
641   '(js2-bounce-indent-p t)
642   '(js2-highlight-level 3)
643   '(js2-mode-escape-quotes nil)
644   '(js2-strict-inconsistent-return-warning nil)
645   '(js2-strict-missing-semi-warning nil)
646   '(minimap-always-recenter nil)
647   '(minimap-display-semantic-overlays t)
648   '(mojo-build-directory "~/Projects/brighthouse/webOS/build")
649   '(mojo-debug nil)
650   '(mojo-project-directory "~/Projects/brighthouse/webOS")
651   '(remote-shell-program "/usr/bin/ssh")
652   '(save-place t nil (saveplace))
653   '(scroll-bar-mode nil)
654   '(shell-file-name "/bin/zsh")
655   '(show-paren-mode t nil (paren))
656   '(tool-bar-mode nil))
657  
658  (if linux-p
659      (custom-set-faces
660       ;; custom-set-faces was added by Custom.
661       ;; If you edit it by hand, you could mess it up, so be careful.
662       ;; Your init file should contain only one such instance.
663       ;; If there is more than one, they won't work right.
664  
665       '(default ((t (:stipple nil :background "black" :foreground "grey85" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 90 :width normal :family "bitstream-bitstream vera sans mono"))))))
666  
667  (put 'upcase-region 'disabled nil)
668  (put 'downcase-region 'disabled nil)
669  (custom-set-faces
670    ;; custom-set-faces was added by Custom.
671    ;; If you edit it by hand, you could mess it up, so be careful.
672    ;; Your init file should contain only one such instance.
673    ;; If there is more than one, they won't work right.
674   '(minimap-font-face ((default (:height 30 :family "DejaVu Sans Mono")) (nil nil))))