Source

.emacs.d / init.el

Full commit
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
;; Stuff to research
;; Quicksilver for Emacs: anything.el http://bc.tech.coop/blog/070711.html
;; icicles.el
;; a way to control in which window *Help* appears
;; a way to display the full path of the current buffer's file
;; a way to browse the kill ring: http://www.emacswiki.org/emacs/BrowseKillRing
;; project management (where a project is a list of files and a list of commands and is associated with a directory) (consider eproject)
;; Emacs macros
;; learning Emacs Lisp (http://xahlee.org/emacs/elisp.html)
;; a frontend to Ack http://www.emacswiki.org/emacs/Ack and http://www.emacswiki.org/emacs/GrepMode
;; change the indentation offset of nXhtml to 4 spaces
;; install Django template snippets: https://github.com/theju/my_yasnippets
;; investigate mode-line-frame.el: http://www.emacswiki.org/emacs/mode-line-frame.el
;; upgrade flymake-cursor.el: http://www.emacswiki.org/emacs/FlymakeCursor
;; read http://www.emacswiki.org/emacs/EmacsNiftyTricks
;; read http://www.emacswiki.org/emacs/DotMode
;; use pydbgr with emacs-dbgr: http://code.google.com/p/pydbgr/wiki/Tutorial https://github.com/rocky/emacs-dbgr
;; read http://www.emacswiki.org/emacs/TrampMode
;; this line seems not to work: (setq ibuffer-default-sorting-mode 'filename/processfilename)
;; investigate interfaces to Mercurial
;; investigate using Emacs as a merge programme for Mercurial: http://mercurial.selenic.com/wiki/MergingWithEmacs
;; a way to put arbitrary files into a category in ibuffer
;; install about ECB: http://ecb.sourceforge.net/

(defconst site-lisp-dir (cond
  ((equal system-type 'darwin) (concat "/usr/local/Cellar/emacs/" (number-to-string emacs-major-version) "." (number-to-string emacs-minor-version) "/share/emacs/site-lisp/"))
  ((equal system-type 'gnu/linux) "/usr/share/emacs/site-lisp/")
  (t "/usr/local/emacs/site-lisp/")))

(add-to-list 'load-path "~/.emacs.d/")
(add-to-list 'load-path "~/.emacs.d/vendor/")
(add-to-list 'load-path "~/.emacs.d/vendor/themes/")
(add-to-list 'load-path (expand-file-name "~/.emacs.d/"))

;; the menu bar is for losers
(menu-bar-mode nil)

;; I like the scroll bar
(scroll-bar-mode t)

;; the beep sound is annoying
(setq visible-bell t)

;; start the server so that emacsclient can connect
(server-start)

;; check every 1 second if the file on disk has changed
(setq auto-revert-interval 1)
;; automatically reload files that have been modified
(global-auto-revert-mode t)

;; make the help buffer appear in its own frame
(push "*Help*" special-display-buffer-names)

;; BEGIN TERMINAL KEY BINDINGS =====================
;; Setting key bindings for certain key sequences (e.g. C-left) in terminal Emacs depends on what character strings the terminal emulator is sending to Emacs when that sequence is entered. The key bindings must be bound to those strings. To figure out what character strings are being sent, type C-q followed by the key sequence. This will insert the literal character string after the point.
;; The following map maps key sequences to the actual character string that are sent by the terminal emulator.

(defvar real-keyboard-keys
  '(("M-<up>"        . "\0333A")
    ("M-<down>"      . "\0333B")
    ("M-<right>"     . "\0333C")
    ("M-<left>"      . "\0333D")
    ("C-<up>"        . "\033[5A")
    ("C-<down>"      . "\033[5B")
    ("C-<right>"     . "\033[5C")
    ("C-<left>"      . "\033[5D"))
  "An assoc list of pretty key strings
and their terminal equivalents.")

(defun real-keyboard-key (desc)
  "Return the keyboard key after detecting if the environment is a terminal."
  (or (and window-system (read-kbd-macro desc))
      (or (cdr (assoc desc real-keyboard-keys))
          (read-kbd-macro desc))))
(defun global-set-key-real-and-terminal (desc func)
  "Set a global keybinding for window system and terminal environments."
  (global-set-key (read-kbd-macro desc) func)
  (global-set-key (cdr (assoc desc real-keyboard-keys)) func))
;; END TERMINAL KEY BINDINGS =====================

;; bind windmove commands
(global-set-key-real-and-terminal "C-<up>" 'windmove-up)
(global-set-key-real-and-terminal "C-<down>" 'windmove-down)
(global-set-key-real-and-terminal "C-<right>" 'windmove-right)
(global-set-key-real-and-terminal "C-<left>" 'windmove-left)
(setq windmove-wrap-around t)

(defun my-terminal-config (&optional frame)
  "Establish settings for the current terminal."
  ;; pass the frame so that display-graphic-p returns a value relevant to the new frame
  (unless (display-graphic-p frame)
    ;; enable mouse reporting for terminal emulators
    (xterm-mouse-mode 1)
    (global-set-key [mouse-4] '(lambda ()
                                 (interactive)
                                 (scroll-down 1)))
    (global-set-key [mouse-5] '(lambda ()
                                 (interactive)
                                 (scroll-up 1)))))
;; Evaluate both now (for non-daemon emacs) and upon frame creation (for new terminals via emacsclient).
(my-terminal-config)
(add-hook 'after-make-frame-functions 'my-terminal-config)

;; remap C-h (help-command) to C-x C-h so that C-h can be used for delete-backward-char
(global-set-key (kbd "C-h") 'delete-backward-char)
(global-set-key [?\C-x ?\C-h] 'help-command)

(delete-selection-mode 1)

;; tell me the relative path up to 2 directories of the buffer's file in the mode line
;; TODO: this doesn't work right because it doesn't consider what the name of the buffer is
;; if the buffer name is "profile/views.py" then the model line will read "apps/profile/profile/views.py"
;; the solution is to change the buffer name directly
(defun add-mode-line-dirtrack ()
  "When editing a file, show the last 2 directories of the current path in the mode line."
  (add-to-list 'mode-line-buffer-identification
               '(:eval (substring default-directory
                                  (+ 1 (string-match "/[^/]+/[^/]+/$" default-directory)) nil))))
(add-hook 'find-file-hook 'add-mode-line-dirtrack)

;; set the indent to be spaces instead of tabs
(setq-default indent-tabs-mode nil)
;; set the indent to be 4 spaces
(setq-default tab-width 4)
(setq indent-line-function 'insert-tab)

;; remove trailing whitespace before saving buffers
(add-hook 'before-save-hook 'delete-trailing-whitespace)

;; "y or n" instead of "yes or no"
(fset 'yes-or-no-p 'y-or-n-p)

;; configure world clock
;; access the world clock with M-x display-time-world
(setq display-time-world-list
      '(("America/Los_Angeles" "Me")
        ("Europe/Bucharest" "Alex Panait")
        ("Europe/Brussels" "Philippe Ombredanne")
        ("Asia/Manila" "Israel")))
(display-time-world)

;; dired-single.el settings
(require 'dired-single)
(defun my-dired-init ()
  "Bunch of stuff to run for dired, either immediately or when it's
   loaded."
  (message "====================== Setting custom dired keys")
  (local-set-key (kbd "RET") 'dired-single-buffer)
  (local-set-key [mouse-1] 'dired-single-buffer-mouse)
  (local-set-key (kbd "^") '(lambda nil (interactive) (dired-single-buffer ".."))))
(add-hook 'dired-mode-hook 'my-dired-init)

;; make Emacs treat all new files as modified
;; http://stackoverflow.com/questions/2592095/how-do-i-create-an-empty-file-in-emacs/2592108
(defun assume-new-is-modified ()
  (when (not (file-exists-p (buffer-file-name)))
    (set-buffer-modified-p t)))
(add-hook 'find-file-hooks 'assume-new-is-modified)

;; prefer ibuffer over buffer-menu
(defalias 'list-buffers 'ibuffer)
(add-hook 'ibuffer-mode-hook '(lambda () (ibuffer-auto-mode 1)))
(setq ibuffer-default-sorting-mode 'filename/processfilename)

;; configure GNU Flymake
;; I'm using an unofficial fork of flymake
(add-to-list 'load-path "~/.emacs.d/vendor/emacs-flymake")
(require 'flymake)
;; turn off GUI warnings from flymake because they (calls to message-box) cause Emacs to hang on OS X
(setq flymake-gui-warnings-enabled nil)
;; run flymake in the system temp directory
(setq flymake-run-in-place nil)
;; activate flymake-mode when files are opened
(add-hook 'find-file-hook 'flymake-mode)
(defun flymake-setup ()
  "Basic setup for flymake-mode"
  (local-set-key (kbd "M-N") 'flymake-goto-next-error)
  (local-set-key (kbd "M-P") 'flymake-goto-prev-error)
  (load-library "flymake-cursor"))
(add-hook 'flymake-mode-hook 'flymake-setup)
;; disable flymake for *.html files
(delete '("\\.html?\\'" flymake-xml-init) flymake-allowed-file-name-masks)

;; BEGIN PYTHON STUFF =======================
;; enable python-mode.el
(add-to-list 'load-path "~/.emacs.d/vendor/python-mode")
(setq py-install-directory "~/.emacs.d/vendor/python-mode")
(require 'python-mode)
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))

;; indenting functions
(defun indent-commands-python-mode-hook ()
 (local-set-key (kbd "M-?") 'py-shift-region-left)
 (local-set-key (kbd "M-+") 'py-shift-region-right)
)
(add-hook 'python-mode-hook 'indent-commands-python-mode-hook)

;; set ipython as the default shell for python-mode
(setq py-shell-name "ipython")
(require 'ipython)

;; set py-pychecker-command to run pychecker.sh
;; the key binding for py-pychecker-command is C-c C-w
(custom-set-variables
  '(py-pychecker-command "~/.emacs.d/vendor/pychecker.sh")
  '(py-pychecker-command-args (quote (""))))

;; enable flymake with pep8 and pyflakes
;; for flymake to work, pep8 and pyflakes must be installed
(when (load "flymake" t)
  (defun flymake-pychecker-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
                       (if (fboundp 'flymake-create-temp-copy)
                           'flymake-create-temp-copy
                         'flymake-create-temp-inplace)))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list "~/.emacs.d/vendor/pychecker.sh" (list local-file))))
  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.py\\'" flymake-pychecker-init)))

;; highlight breakpoints
(defun annotate-pdb ()
  (interactive)
  (highlight-lines-matching-regexp "import pdb")
  (highlight-lines-matching-regexp "pdb.set_trace()")
  (highlight-lines-matching-regexp "import ipdb")
  (highlight-lines-matching-regexp "ipdb.set_trace()")
  (highlight-lines-matching-regexp "import pudb")
  (highlight-lines-matching-regexp "pudb.set_trace()"))
(add-hook 'python-mode-hook 'annotate-pdb)

;; Django templates
(load "~/.emacs.d/vendor/nxhtml/autostart.el")
(setq mumamo-background-colors nil)
(add-to-list 'auto-mode-alist '("\\.html\\'" . django-html-mumamo-mode))
(add-to-list 'auto-mode-alist '("\\.htmf\\'" . django-html-mumamo-mode))
;; Mumamo is making emacs 23.3 freak out:
(when (and (equal emacs-major-version 23)
           (equal emacs-minor-version 3))
  (eval-after-load "bytecomp"
    '(add-to-list 'byte-compile-not-obsolete-vars
                  'font-lock-beginning-of-syntax-function))
  ;; tramp-compat.el clobbers this variable!
  (eval-after-load "tramp-compat"
    '(add-to-list 'byte-compile-not-obsolete-vars
                  'font-lock-beginning-of-syntax-function)))
;; nxhtml sets debug-on-error to t, so undo it
(setq debug-on-error nil)

;; PYLOOKUP ----
;; add pylookup to your loadpath, ex) ~/.emacs.d/pylookup
(setq pylookup-dir "~/.emacs.d/vendor/pylookup")
(add-to-list 'load-path pylookup-dir)

;; load pylookup when compile time
(eval-when-compile (require 'pylookup))

;; set executable file and db file
(setq pylookup-program (concat pylookup-dir "/pylookup.py"))
(setq pylookup-db-file (concat pylookup-dir "/pylookup.db"))

;; to speedup, just load it on demand
(autoload 'pylookup-lookup "pylookup"
  "Lookup SEARCH-TERM in the Python HTML indexes." t)

(autoload 'pylookup-update "pylookup"
  "Run pylookup-update and create the database at `pylookup-db-file'." t)
;; END PYLOOKUP ----

;; Pymacs
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-exec "pymacs" nil t)
(autoload 'pymacs-load "pymacs" nil t)

;; ropemacs
(defun load-ropemacs ()
    (interactive)
    (require 'pymacs)
    (pymacs-load "ropemacs" "rope-")
    ;; automatically save project python buffers before refactorings
    (setq ropemacs-confirm-saving nil)
    ;; autoimport doesn't work very well
    (setq ropemacs-enable-autoimport nil)

    ;; ropemacs by default without asking stupidly binds dabbrev-expand's default key binding to its own function rope-code-assist
    (local-set-key (kbd "M-/") 'dabbrev-expand)
)

;; enable code completion using pysmell
(add-hook 'python-mode-hook (lambda ()
    (require 'pysmell)
    (pysmell-mode 1)
    ;; pysmell-mode by default without asking stupidly binds dabbrev-expand's default key binding to its own function pysmell-complete
    ;; rebind pysmell-complete
    (define-key pysmell-mode-map (kbd "M-/") 'dabbrev-expand)
    (local-set-key (kbd "M-]") 'pysmell-complete)
))

;; enable autopair for python single and triple quotes
(add-hook 'python-mode-hook
          #'(lambda ()
              (push '(?' . ?')
                    (getf autopair-extra-pairs :code))
              (setq autopair-handle-action-fns
                    (list #'autopair-default-handle-action
                          #'autopair-python-triple-quote-action))))

;; treat *.mail files as Django templates
(add-to-list 'auto-mode-alist '("\\.mail\\'" . django-mode))

;; treat *.less files as CSS files
(add-to-list 'auto-mode-alist '("\\.less\\'" . css-mode))
;; END PYTHON STUFF =======================

;; BEGIN JAVASCRIPT STUFF =======================
;; use js2-mode for editing JavaScript
(autoload 'js2-mode "js2" nil t)
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))

;; set JavaScript global variables
(setq js2-global-externs '("window" "jQuery" "$" "OBNOB" "O" "logger" "_" "Backbone"))

;; enable flymake with jslint
;; for flymake to work, node.js must be installed
(when (load "flymake" t)
  (defun flymake-jslint-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
                       (if (fboundp 'flymake-create-temp-copy)
                           'flymake-create-temp-copy
                         'flymake-create-temp-inplace)))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
      (list "~/.emacs.d/vendor/jslint/jschecker.sh" (list local-file))))

  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.js\\'"
                 flymake-jslint-init
                 flymake-simple-cleanup
                 flymake-get-real-file-name))

  (add-to-list 'flymake-err-line-patterns
               '(".*: line \\(.+\\), character \\(.+\\), \\(.+\\)$"
                 nil 1 2 3)))
;; disable auto-mode in js2-mode because it does its own autopairing
(add-hook 'js2-mode-hook #'(lambda () (setq autopair-dont-activate t)))
(require 'js2-highlight-vars)
(add-hook 'js2-mode-hook 'js2-highlight-vars-mode)

;; CoffeeScript stuff
(require 'coffee-mode)
(add-to-list 'auto-mode-alist '("\\.coffee$" . coffee-mode))
(add-to-list 'auto-mode-alist '("Cakefile" . coffee-mode))
(defun coffee-custom ()
  "coffee-mode-hook"
  ;; idiomatic CoffeeScript uses two spaces for indentation
  (set (make-local-variable 'tab-width) 2))
(add-hook 'coffee-mode-hook '(lambda() (coffee-custom)))
;; END JAVASCRIPT STUFF =======================

;; ; enable anything
;; (add-to-list 'load-path "~/.emacs.d/vendor/anything-config")
;; (add-to-list 'load-path "~/.emacs.d/vendor/anything-config/extensions")
;; (require 'anything-startup)

; allow narrow-to-region
(put 'narrow-to-region 'disabled nil)

;; put line numbers on all buffers
(global-linum-mode t)
;; put a one-space separation between the line number display and the buffer contents
(setq linum-format "%d ")

;; show the column number in the mode line
(column-number-mode t)

;; set default mode to text-mode
(setq default-major-mode 'text-mode)

;; set visual-line-mode for text mode
;; it's not very useful outside of editing English text
;; Visual Line mode provides support for editing by visual lines. It turns on word-wrapping in the current buffer, and rebinds C-a, C-e, and C-k to commands that operate by visual lines instead of logical lines.
(add-hook 'text-mode-hook 'turn-on-visual-line-mode)

;; set show-paren-mode: Whenever point is before an opening delimiter or after a closing delimiter, both that delimiter and its opposite delimiter are highlighted.
(show-paren-mode t)

;; When the matching paren is offscreen, show-paren-mode highlights only the paren at point. It is more useful to show the line of matching paren in the minibuffer. Execute the following to get this behavior.
(defadvice show-paren-function
  (after show-matching-paren-offscreen activate)
  "If the matching paren is offscreen, show the matching line in the
    echo area. Has no effect if the character before point is not of
    the syntax class ')'."
  (interactive)
  (if (not (minibuffer-prompt))
      (let ((matching-text nil))
        ;; Only call `blink-matching-open' if the character before point
        ;; is a close parentheses type character. Otherwise, there's not
        ;; really any point, and `blink-matching-open' would just echo
        ;; "Mismatched parentheses", which gets really annoying.
        (if (char-equal (char-syntax (char-before (point))) ?\))
            (setq matching-text (blink-matching-open)))
        (if (not (null matching-text))
            (message matching-text)))))

;; set bold face for keywords and italics for comments
(set-face-bold-p 'font-lock-keyword-face t)
(set-face-italic-p 'font-lock-comment-face t)

;; sets the title of the frame to show the system name and full path of the current file
(setq frame-title-format
      (list (format "%s %%S: %%j " (system-name))
        '(buffer-file-name "%f" (dired-directory dired-directory "%b"))))

;; Set color theme
(require 'color-theme)
(color-theme-initialize)
(setq color-theme-is-global t)
(setq color-theme-is-cumulative t)
(setq color-theme-load-all-themes nil)
;; very good color themes
;; (color-theme-vibrant-ink)
;; (color-theme-vibrant-ink-kevin-tran)
(color-theme-clarity)
;; ok color themes
;; (color-theme-charcoal-black)
;; (color-theme-word-perfect)
;; (color-theme-ir-black)

;; enable loading the desktop at startup
(desktop-save-mode t)

;; enable saveplace
;; Purpose: When you visit a file, point goes to the last place where it was when you previously visited the same file.
(require 'saveplace)
(setq-default save-place t)

;; save bookmarks every time the bookmark list is modified
(setq bookmark-save-flag 1)

;; configure cursor
(require 'bar-cursor)
(bar-cursor-mode 1)
(blink-cursor-mode 1)

;; Load ido
(require 'ido)
(ido-mode t)
;; enable fuzzy matching
(setq ido-enable-flex-matching t)
;; use `maybe-frame' so that when visiting a file or buffer, ask if you you want to see the file in the same window of the current frame or in the other frame
(setq ido-default-file-method 'maybe-frame)
(setq ido-default-buffer-method 'maybe-frame)

;; minibuffer completion
(icomplete-mode t)

;; Load Uniquify
(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)

;; Load YASnippet
(add-to-list 'load-path "~/.emacs.d/vendor/yasnippet-0.6.1c")
(require 'yasnippet)
(yas/initialize)
(yas/load-directory "~/.emacs.d/vendor/yasnippet-0.6.1c/snippets")
(yas/load-directory "~/.emacs.d/vendor/snippets")
;; set yas/root-directory so that when yas/reload-all is called, all snippets are loaded
(setq yas/root-directory (list "~/.emacs.d/vendor/snippets" yas/root-directory))

;; Load Auto-complete
(add-to-list 'load-path "~/.emacs.d/vendor/auto-complete-install/")
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/vendor/auto-complete-install/ac-dict")
(ac-config-default)

;; TextMate Minor Mode
;; http://github.com/defunkt/textmate.el
(require 'textmate)
(textmate-mode)

;; autopair emulate's TextMate's automatic pairing of delimiter characters
(require 'autopair)
(autopair-global-mode) ;; enable autopair in all buffers

;; ;; Load Zen Coding
;; (require 'zencoding-mode)
;; (add-hook 'sgml-mode-hook 'zencoding-mode) ;; Auto-start on any markup modes

;; Load multi-term
(require 'multi-term)
(setq multi-term-program "/bin/bash")
(add-hook 'term-mode-hook #'(lambda () (setq autopair-dont-activate t)))
(defalias 'term 'multi-term)

;; Colour diffs
(custom-set-faces
 '(diff-added ((t (:foreground "Green"))) 'now)
 '(diff-removed ((t (:foreground "Red"))) 'now)
)

;; BEGIN AUTOINDENT ON YANK =====================
;; these advice functions modify yank and yank-pop so that the inserted text is indented relative to the surrounding code
(defadvice yank (after indent-region activate)
  (if (member major-mode
              '(emacs-lisp-mode scheme-mode lisp-mode python-mode js-mode
                                c-mode c++-mode objc-mode
                                latex-mode plain-tex-mode))
      (let ((mark-even-if-inactive transient-mark-mode))
        (indent-region (region-beginning) (region-end) nil))))

(defadvice yank-pop (after indent-region activate)
  (if (member major-mode
              '(emacs-lisp-mode scheme-mode lisp-mode python-mode js-mode
                                c-mode c++-mode objc-mode
                                latex-mode plain-tex-mode))
      (let ((mark-even-if-inactive transient-mark-mode))
        (indent-region (region-beginning) (region-end) nil))))
;; END AUTOINDENT ON YANK =====================

;; BEGIN CURRENT WORD SEARCH =====================
;; http://sachachua.com/blog/2008/07/emacs-keyboard-shortcuts-for-navigating-code/
;; these search functions work like n/N in vim
(defun sacha/search-word-backward ()
  "Find the previous occurrence of the current word."
  (interactive)
  (let ((cur (point)))
    (skip-syntax-backward "w_")
    (goto-char
     (if (re-search-backward (concat "\\_<" (current-word) "\\_>") nil t)
     (match-beginning 0)
       cur))))
(defun sacha/search-word-forward ()
  "Find the next occurrance of the current word."
  (interactive)
  (let ((cur (point)))
    (skip-syntax-forward "w_")
    (goto-char
     (if (re-search-forward (concat "\\_<" (current-word) "\\_>") nil t)
     (match-beginning 0)
       cur))))
(global-set-key (kbd "M-p") 'sacha/search-word-backward)
(global-set-key (kbd "M-n") 'sacha/search-word-forward)
;; END CURRENT WORD SEARCH =====================

(defun sacha/yank-push () (interactive) (yank-pop -1))
(global-set-key (kbd "C-M-y") 'sacha/yank-push)

;; enable highlight-symbol
;; Quickly highlight a symbol throughout the buffer and cycle through its locations.
(require 'highlight-symbol)
(global-set-key (kbd "<f4>") 'highlight-symbol-at-point)

;; BEGIN MAC COPY/PASTE =====================
;; http://blog.lathi.net/articles/2007/11/07/sharing-the-mac-clipboard-with-emacs
(if (string= system-type "darwin")
  (progn
    (defun copy-from-osx ()
      (shell-command-to-string "pbpaste"))

    (defun paste-to-osx (text &optional push)
      (let ((process-connection-type nil))
        (let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
          (process-send-string proc text)
          (process-send-eof proc))))

    (setq interprogram-cut-function 'paste-to-osx)
    (setq interprogram-paste-function 'copy-from-osx)))
;; END MAC COPY/PASTE =====================

;; use workgroups.el for saving window configurations
(add-to-list 'load-path "~/.emacs.d/vendor/workgroups.el/")
(require 'workgroups)
(workgroups-mode 1)
(wg-load "~/.emacs_workgroups")
;; turn off morphing animation when switching between wconfigs
(setq wg-morph-on nil)
(defun wg-update-workgroup-and-save ()
  "Call `wg-update-workgroup', then `wg-save'."
  (interactive)
  (call-interactively 'wg-update-workgroup)
  (call-interactively 'wg-save))
(global-set-key (kbd "C-z C-u") 'wg-update-workgroup-and-save)

;; use cua-mode because it has good rectangular selection support
(cua-selection-mode t)

;; a better way of dealing with ctags
(require 'etags-select)
;; override the default find-tag key binding
(global-set-key "\M-." 'etags-select-find-tag-at-point)
;; etags-select lacks bindings for RET which means that the return key does not work for tag selection when Emacs is run in a terminal emulator
(define-key etags-select-mode-map (kbd "RET") 'etags-select-goto-tag)
(define-key etags-select-mode-map (kbd "M-RET") 'etags-select-goto-tag-other-window)

;; use w3m
(add-to-list 'load-path (concat site-lisp-dir "w3m"))
(require 'w3m-load)
(setq browse-url-browser-function 'w3m-browse-url)
;; set the w3m executable
(setq w3m-command "/usr/local/bin/w3m")

;; use marmalade
(require 'package)
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))

(require 'undo-tree)
(global-undo-tree-mode)

;; use deft for taking notes
(require 'deft)
(global-set-key (kbd "<f5>") 'deft)
;; open deft on startup
(deft)

;; drag lines, regions, and words with M-<up|down|left|right>
(require 'drag-stuff)
(drag-stuff-global-mode t)

;; configure tramp
(require 'tramp)
(setq tramp-default-method "ssh")
(tramp-set-completion-function "ssh"
    '((tramp-parse-sconfig "/etc/ssh_config")
      (tramp-parse-sconfig "~/.ssh/config")
      (tramp-parse-shosts "~/.ssh/known_hosts")))

(require 'mercurial)

(defun copy-full-path-to-kill-ring ()
  "Copy the current buffer's full path to the kill ring"
  (interactive)
  (when buffer-file-name
    (kill-new (file-truename buffer-file-name))))