Updated the thermal and battery info display for the T450s
[elisp.git] / emacs.el
1 ;; -*- mode: Emacs-Lisp; mode: rainbow; -*-
2
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ;; This program is free software; you can redistribute it and/or         ;;
5 ;; modify it under the terms of the GNU General Public License as        ;;
6 ;; published by the Free Software Foundation; either version 3, or (at   ;;
7 ;; your option) any later version.                                       ;;
8 ;;                                                                       ;;
9 ;; This program is distributed in the hope that it will be useful, but   ;;
10 ;; WITHOUT ANY WARRANTY; without even the implied warranty of            ;;
11 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      ;;
12 ;; General Public License for more details.                              ;;
13 ;;                                                                       ;;
14 ;; You should have received a copy of the GNU General Public License     ;;
15 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.  ;;
16 ;;                                                                       ;;
17 ;; Written by and Copyright (C) Francois Fleuret                         ;;
18 ;; Contact <francois@fleuret.org> for comments & bug reports             ;;
19 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
21 ;; It's better to set the preferences in the .Xresources so that the
22 ;; window is not first displayed with the wrong options
23
24 ;; Emacs.menuBar:            off
25 ;; Emacs.verticalScrollBars: off
26 ;; Emacs.toolBar:            off
27 ;; Emacs.internalBorder:     1
28 ;; Emacs.FontBackend: xft
29 ;; Xft.dpi: 96
30 ;; Xft.hinting: true
31 ;; Xft.antialias: true
32 ;; Xft.rgba: rgb
33
34 ;; (set-default-font "Bitstream vera sans mono-12")
35 ;; (set-default-font "Liberation Mono-13")
36 (set-default-font "Inconsolata 15")
37 ;;(set-default-font "DejaVu sans mono 11")
38 ;;(set-default-font "Droid sans mono 13")
39 ;;(set-default-font "Opensans 10")
40
41 (when (fboundp 'horizontal-scroll-bar-mode)
42   (horizontal-scroll-bar-mode -1))
43
44 ;; This is where I put most of my emacs-related files
45 (setq ff/emacs-dir "~/private/emacs")
46 (unless (file-exists-p ff/emacs-dir)
47   (mkdir ff/emacs-dir t))
48
49 ;; Give the focus to the emacs window if we are under a windowing
50 ;; system
51
52 (when window-system
53   ;; (x-focus-frame nil)
54   (set-mouse-pixel-position (selected-frame) 4 4))
55
56 ;; Where I keep my own scripts
57
58 (add-to-list 'load-path "~/sources/gpl/elisp")
59 (add-to-list 'load-path "~/sources/elisp")
60 (add-to-list 'load-path "~/local/elisp")
61
62 ;; No, I do not like menus
63 (menu-bar-mode -1)
64
65 ;; Nor fringes
66 ;; (when (functionp 'fringe-mode) (fringe-mode '(0 . 0)))
67 ;; (when (functionp 'fringe-mode) (fringe-mode '(0 . 1)))
68 (when (functionp 'fringe-mode) (fringe-mode 10))
69
70 ;; And I do not like scrollbar neither
71 (when (functionp 'scroll-bar-mode) (scroll-bar-mode -1))
72
73 ;; Make all "yes or no" prompts be "y or n" instead
74 (fset 'yes-or-no-p 'y-or-n-p)
75
76 ;; The space bar acting as "yes" has been several times really
77 ;; problematic.
78 (define-key query-replace-map (kbd "SPC") nil)
79
80 ;; Show the matching parenthesis and do it immediately, we are in a
81 ;; hurry
82 (setq show-paren-delay 0)
83 (show-paren-mode t)
84
85 ;; use colorization for all modes
86 (global-font-lock-mode t)
87
88 (setq font-lock-maximum-decoration 3
89       ;;'((latex-mode . 2) (t . 2))
90       )
91
92 ;; Activate the dynamic completion of buffer names
93 (iswitchb-mode 1)
94
95 ;; Save the minibuffer history
96 (setq savehist-file (concat ff/emacs-dir "/savehist"))
97 (when (functionp 'savehist-mode) (savehist-mode 1))
98
99 ;; And allow minibuffer recursion
100 (setq enable-recursive-minibuffers t)
101 (minibuffer-depth-indicate-mode 1)
102
103 ;; I do not like tooltips
104 (when (functionp 'tooltip-mode) (tooltip-mode nil))
105
106 ;; Activate the dynamic completion in the mini-buffer
107 (icomplete-mode 1)
108
109 ;; (setq highlight-current-line-globally t
110 ;; highlight-current-line-ignore-regexp "Faces\\|Colors\\| \\*Mini\\|\\*media\\|INBOX")
111
112 ;; (highlight-current-line-minor-mode 1)
113 ;; (highlight-current-line-set-bg-color "gray75")
114
115 (defun ff/compile-when-needed (name)
116   "Compiles the given file only if needed. Adds .el if required, and
117 uses `load-path' to find it."
118   (if (not (string-match "\.el$" name))
119       (ff/compile-when-needed (concat name ".el"))
120     (mapc (lambda (dir)
121             (let* ((src (concat dir "/" name)))
122               (when (file-newer-than-file-p src (concat src "c"))
123                 (if (let ((byte-compile-verbose nil))
124                       (condition-case nil
125                           (byte-compile-file src)
126                         (error nil)))
127                     (message (format "Compiled %s" src ))
128                   (message (format "Failed compilation of %s" src))))))
129           load-path)))
130
131 ;; This is useful when using the same .emacs in many places
132
133 (defun ff/load-or-alert (name &optional compile-when-needed)
134   "Tries to load the specified file and insert a warning message in a
135 load-warning buffer in case of failure."
136
137   (when compile-when-needed (ff/compile-when-needed name))
138
139   (if (load name t nil) t
140     (let ((buf (get-buffer-create "*loading warnings*")))
141       (display-buffer buf)
142       (set-buffer buf)
143       (insert (propertize "Warning:" 'face 'font-lock-warning-face) " could not load '" name "'\n")
144       (fit-window-to-buffer (get-buffer-window buf))
145       (set-buffer-modified-p nil))
146     nil))
147
148 ;; This is the default in emacs 22.1 and later
149 ;; (auto-compression-mode 1)
150
151 ;; make emacs use the clipboard so that copy/paste works for other
152 ;; x-programs. I have no clue how all that clipboard thing works.
153
154 ;; (setq x-select-enable-clipboard t)
155 ;; (setq interprogram-paste-function 'x-cut-buffer-or-selection-value)
156 ;; (setq x-select-enable-primary t)
157 ;; (setq x-select-enable-clipboard t)
158 ;; (global-set-key "\C-y" 'clipboard-yank)
159
160 (setq
161
162  message-log-max 1000
163
164  ;; avoid GC as much as possible
165  gc-cons-threshold 2500000
166
167  ;; no startup message
168  inhibit-startup-screen t
169
170  ;; no message in the scratch buffer
171  initial-scratch-message nil
172
173  ;; do not fill my buffers, you fool
174  next-line-add-newlines nil
175
176  ;; keep the window focused on the messages during compilation
177  compilation-scroll-output t
178
179  ;; Keep the highlight on the compilation error
180  next-error-highlight t
181
182  ;; blink the screen instead of beeping
183  ;; visible-bell t
184
185  ;; take the CR when killing a line
186  kill-whole-line t
187
188  ;; I prefer to move between lines as defined in the buffer, not
189  ;; visually
190  line-move-visual nil
191
192  ;; I comment empty lines, too (does not seem to work, though)
193  comment-empty-lines t
194
195  ;; We want long lines to be truncated instead of displayed on several lines
196  ;; truncate-lines t
197  ;; Show all lines, even if the window is not as large as the frame
198  ;; truncate-partial-width-windows nil
199  ;; truncate-partial-width-windows t
200
201  ;; Do not keep tracks of the autosaved files
202  auto-save-list-file-prefix nil
203
204  ;; Show me empty lines at the end of the buffer
205  default-indicate-empty-lines t
206
207  ;; Show me the region until I do something on it
208  transient-mark-mode t
209
210  ;; Do not color stuff which are clickable when hovering over it
211  mouse-highlight nil
212
213  ;; Don't bother me with questions even if "unsafe" local variables
214  ;; are set
215  enable-local-variables :all
216
217  ;; I have no problem with small windows
218  window-min-height 1
219
220  ;; I am not a fan of develock
221  develock-auto-enable nil
222
223  ;; I do not like women to open windows
224  woman-use-own-frame nil
225
226  ;; I am not that paranoid, contrary to what you think
227  epa-file-cache-passphrase-for-symmetric-encryption t
228  ;; And I like ascii files
229  epa-armor t
230
231  ;; tramp-default-method "ssh"
232  tramp-default-method "scp"
233
234  ;; I have no problem with files having their own local variables
235  enable-local-eval t
236
237  mail-from-style 'angles
238  browse-url-mozilla-program "firefox"
239  mc-encrypt-for-me t
240  mc-use-default-recipients t
241
242  ;; browse-url-new-window-flag t
243
244  ;; I do not like compilation to automatically split the active window
245  ;; vertically, even when the said window is very wide
246  split-height-threshold 0
247  split-width-threshold nil
248
249  )
250
251 ;; The backups
252
253 (setq
254  temporary-file-directory "/tmp/"
255  vc-make-backup-files t
256  backup-directory-alist '((".*" . "~/misc/emacs.backups/"))
257  version-control t ;; Use backup files with numbers
258  kept-new-versions 10
259  kept-old-versions 2
260  delete-old-versions t
261  backup-by-copying-when-linked t
262  )
263
264 (setq tramp-backup-directory-alist backup-directory-alist)
265
266 (setq user-emacs-directory "~/misc/emacs.d/")
267
268 (setq
269  abbrev-file-name (concat user-emacs-directory "abbrev_defs")
270  server-auth-dir (concat user-emacs-directory "server/")
271  custom-theme-directory user-emacs-directory
272  )
273
274 ;; Stop this crazy blinking cursor
275 (blink-cursor-mode 0)
276
277 ;; (setq blink-cursor-delay 0.05
278 ;; blink-cursor-blinks 0
279 ;; blink-cursor-interval 0.25)
280
281 ;; (set-terminal-coding-system 'utf-8)
282
283 ;; (unless window-system
284 ;; (xterm-mouse-mode 1)
285 ;;   (if (string= (getenv "TERM") "xterm-256color")
286 ;;       (ff/load-or-alert "xterm-256color" t))
287 ;; )
288
289 (setq-default
290
291  ;; Show white spaces at the end of lines
292  show-trailing-whitespace t
293
294  ;; Do not show the cursor in non-active window
295  cursor-in-non-selected-windows nil
296
297  use-dialog-box nil
298  use-file-dialog nil
299
300  ;; when on a TAB, the cursor has the TAB length
301  x-stretch-cursor t
302
303  ;; This is the default coding system when toggle-input-method is
304  ;; invoked (C-\)
305  default-input-method "latin-1-prefix"
306
307  ;; do not put tabs when indenting
308  indent-tabs-mode nil
309  ;; Stop indenting automatically, that's annoying
310  electric-indent-chars nil
311
312  ;; And yes, we have a fast display / connection / whatever
313  baud-rate 524288
314  ;; baud-rate 10
315
316  ;; To keep the cursor always visible when it moves (thanks
317  ;; snogglethrop!)
318  redisplay-dont-pause t
319
320  ;; I want to see the keys I type instantaneously
321  echo-keystrokes 0.1
322  )
323
324 ;; Show the column number
325 (column-number-mode 1)
326
327 ;; What modes for what file extentions
328 (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
329
330 (require 'org-table)
331
332 (add-to-list 'auto-mode-alist '("\\.txt\\'" . (lambda()
333                                                 (text-mode)
334                                                 (orgtbl-mode)
335                                                 ;; (auto-fill-mode)
336                                                 (flyspell-mode))))
337
338 (add-hook 'c++-mode-hook 'flyspell-prog-mode)
339 (add-hook 'log-edit-mode-hook 'flyspell-mode)
340
341 ;; I am a power-user
342
343 (put 'narrow-to-region 'disabled nil)
344 (put 'upcase-region 'disabled nil)
345 (put 'downcase-region 'disabled nil)
346 ;; (put 'scroll-left 'disabled nil)
347 ;; (put 'scroll-right 'disabled nil)
348
349 ;; My selector is clearer than that
350 ;; (when (load "ido" t) (ido-mode t))
351
352 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
353
354 ;; Makes buffer names more explicit then <2>, <3> etc. when there are
355 ;; several identical filenames
356
357 (when (load "uniquify" t)
358   (setq uniquify-buffer-name-style 'post-forward-angle-brackets))
359
360 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
361 ;; Appearance
362 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
363
364 (when (boundp 'x-display-name)
365
366   (setq-default
367
368    ;; If the display is :0.0, we make the assumption that we are
369    ;; running the emacs locally, and we do not show the
370    ;; hostname. Otherwise, show @host.
371
372    frame-title-format (concat "emacs" ;;invocation-name
373                               (unless (string= x-display-name ":0.0")
374                                 (concat "@" system-name))
375                               " (%b)")
376
377    ;; Use the same for the icone
378
379    icon-title-format frame-title-format
380    ))
381
382 ;; "tool" bar? Are you kidding?
383 (when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
384
385 ;; ;; If my own letter icon is here, use it and change its color
386 ;; (when (file-exists-p "~/local/share/emacs/letter.xbm")
387 ;; (setq-default display-time-mail-icon
388 ;; (find-image
389 ;; '((:type xbm
390 ;; :file "~/local/share/emacs/letter.xbm"
391 ;; :ascent center)))))
392
393 ;; My funky setting of face colors. Basically, we switch to a sober
394 ;; look and darken a bit the colors which need to (because of the
395 ;; darker background)
396
397 (defun ff/configure-faces (fl)
398   "Set face attributes and create faces when necessary"
399   (mapc (lambda (f)
400           (unless (boundp (car f)) (make-empty-face (car f)))
401           (eval `(set-face-attribute (car f) nil ,@(cdr f))))
402         fl))
403
404 ;; Not the same in xterm (which is gray in my case) and in
405 ;; X-window
406
407 (unless window-system
408   ;;     (xterm-mouse-mode 1)
409   (ff/configure-faces
410    '((italic :underline nil)
411      (info-title-2 :foreground "green")
412      (font-lock-comment-delimiter-face :foreground "green")
413      (font-lock-comment-face :foreground "green")
414      (cperl-array-face :background "gray90" :foreground "blue" :weight 'bold)
415      (cperl-hash-face :background "gray90" :foreground "purple" :weight 'bold)
416      (diff-added :background "gray90" :foreground "green4" :weight 'bold)
417      (diff-removed :background "gray90" :foreground "red2" :weight 'bold)
418      (diff-changed :background "gray90" :foreground "blue" :weight 'bold)
419      (diff-file-header-face :background "white" :foreground "black"
420                             :weight 'bold)
421      (diff-header-face :background "white" :foreground "black")
422      (diff-hunk-header-face :background "white" :foreground "black")
423      (diff-indicator-removed :foreground "red" :weight 'bold)
424      (diff-removed :foreground "red" :weight 'bold)
425      (diff-indicator-added :foreground "blue" :weight 'bold)
426      (diff-added :foreground "blue" :weight 'bold)
427      (font-lock-string-face :foreground "green")
428      (font-lock-variable-name-face :foreground "blue")
429      (font-lock-constant-face :foreground "blue")
430      (font-lock-preprocessor-face :foreground "green")
431      (font-lock-function-name-face :foreground "cyan")
432      (flyspell-incorrect :foreground "red2")
433      (flyspell-duplicate :foreground "OrangeRed2")
434      (hl-line :background "white")
435      (sh-heredoc :foreground "black" :background "#fff0f0")
436      (sh-heredoc-face :foreground "black" :background "#fff0f0")
437      (font-lock-keyword-face :foreground "blue")
438      (highlight :background "darkseagreen3")
439      (isearch :background "orange" :foreground "black")
440      (isearch-lazy-highlight-face' :background "yellow" :foreground "black")
441      ;; (display-time-mail-face :background "white")
442      (show-paren-match-face :background "gold" :foreground "black")
443      (show-paren-mismatch-face :background "red" :foreground "black")
444      (trailing-whitespace :background "white")
445      (mode-line :background "cornflowerblue" :foreground "black" :box nil
446                 :inverse-video nil)
447      (header-line :background "cornflowerblue" :foreground "black" :box nil
448                   :inverse-video nil)
449      (mode-line-inactive :background "gray60" :foreground "black" :box nil
450                          :inverse-video nil)
451      (region :background "white" :foreground "black")
452      (ff/date-info-face :foreground "white" :weight 'bold)
453      (ff/mail-alarm-face :foreground "red" :weight 'bold)
454      (selector/selection :background "yellow")
455      (gui-button-face :background "green" :foreground "white")
456      (enotes/information-face :foreground "cyan")
457
458      (file-name-shadow :foreground "black")
459      (shadow :foreground "black")
460      (warning :foreground "black" :background "red")
461      ))
462   )
463
464 ;; (list-colors-display (mapcar 'car color-name-rgb-alist))
465
466 ;; (ff/configure-faces '((default :background "black" :foreground "gray80")))
467 ;; (ff/configure-faces '((default :background "gray80" :foreground "black")))
468
469 (when window-system
470   ;; (setq
471   ;; display-time-use-mail-icon t)
472
473   (ff/configure-faces
474    '(
475      ;; (escape-glyph :foreground "#c0c0c0" :weight 'bold)
476
477      (escape-glyph :foreground "green3" :weight 'bold)
478      (default :background "gray90" :foreground "black")
479      (cperl-array-face :background "gray90" :foreground "blue" :weight 'bold)
480      (cperl-hash-face :background "gray90" :foreground "purple" :weight 'bold)
481      (message-cited-text :foreground "red4")
482      (diff-mode :background "gray90" :weight 'bold)
483      (diff-added :background "gray90" :foreground "green4" :weight 'bold)
484      (diff-removed :background "gray90" :foreground "red2" :weight 'bold)
485      (diff-changed :background "gray90" :foreground "blue" :weight 'bold)
486      (diff-file-header :background "white" :foreground "black"
487                        :weight 'bold)
488      (diff-header :background "white" :foreground "black")
489      (diff-hunk-header :background "white" :foreground "black")
490      (font-lock-builtin-face :foreground "deeppink3")
491      (font-lock-string-face :foreground "dark olive green")
492      (font-lock-variable-name-face :foreground "sienna")
493      ;; (font-lock-function-name-face :foreground "blue" :weight 'bold)
494      (font-lock-function-name-face :foreground "blue")
495      ;; (font-lock-comment-delimiter-face :foreground "dark violet")
496      ;; (font-lock-comment-face :foreground "dark violet")
497      (flyspell-incorrect :background "#ff0000" :foreground "black")
498      (flyspell-duplicate :background "#ff9000" :foreground "black")
499      (hl-line :background "white")
500      (sh-heredoc :foreground "black" :background "#fff0f0")
501      (sh-heredoc-face :foreground "black" :background "#fff0f0")
502      (header-line :background "gray65")
503      (highlight :background "turquoise")
504      (message-cited-text-face :foreground "firebrick")
505      (isearch :background "yellow" :foreground "black")
506      (isearch-lazy-highlight-face' :background "yellow3" :foreground "black")
507      (region :background "#b8b8e0" :foreground "black")
508      ;; (region :background "plum" :foreground "black")
509      (show-paren-match-face :background "gold" :foreground "black")
510      (show-paren-mismatch-face :background "red" :foreground "black")
511      (trailing-whitespace :background "gray65")
512      (cursor :inverse-video t)
513      (enotes/list-title-face :foreground "blue" :weight 'bold)
514      (mode-line :background "#b0b0ff" :foreground "black" :box nil
515                 :inverse-video nil)
516      (header-line :background "cornflowerblue" :foreground "black" :box nil
517                   :inverse-video nil)
518      (mode-line-inactive :background "gray80" :foreground "black" :box nil
519                          :inverse-video nil)
520      ;; (fringe :background "black" :foreground "gray90")
521      (fringe :background "gray80")
522      (ff/date-info-face :foreground "white" :weight 'bold)
523      (ff/mail-alarm-face :foreground "white" :background "red2")
524      ;; (alarm-vc-face :foreground "black" :background "yellow" :weight 'normal)
525      (gui-button-face :background "green" :foreground "black")
526      ))
527   )
528
529 ;; When we are root, put the modeline in red
530
531 (when (string= (user-real-login-name) "root")
532   (ff/configure-faces
533    '((mode-line :background "red3" :foreground "black" :box nil
534                 :inverse-video nil))
535    ))
536
537 ;; Why should I have to do this?
538 (add-hook 'sh-mode-hook
539           (lambda ()
540             (set-face-attribute 'sh-heredoc nil
541                                 :foreground "#604000"
542                                 :background "white"
543                                 :italic t)
544             (set-face-attribute 'sh-heredoc-face nil
545                                 :foreground "#604000"
546                                 :background "white"
547                                 :italic t)
548             ))
549
550 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
551 ;; Move the window on the buffer without moving the cursor
552 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
553
554 (defun ff/scroll-down ()
555   "Scroll the buffer down one line and keep the cursor at the same location."
556   (interactive)
557   (condition-case nil
558       (scroll-down 1)
559     (error nil)))
560
561 (defun ff/scroll-up ()
562   "Scroll the buffer up one line and keep the cursor at the same location."
563   (interactive)
564   (condition-case nil
565       (scroll-up 1)
566     (error nil)))
567
568 (defun ff/scroll-left ()
569   "Scroll the buffer left one column and keep the cursor at the same location."
570   (interactive)
571   (condition-case nil
572       (scroll-left 2)
573     (error nil)))
574
575 (defun ff/scroll-right ()
576   "Scroll the buffer right one column and keep the cursor at the same location."
577   (interactive)
578   (condition-case nil
579       (scroll-right 2)
580     (error nil)))
581
582 (define-key global-map [(meta up)] 'ff/scroll-down)
583 (define-key global-map [(meta down)] 'ff/scroll-up)
584 (define-key global-map [(meta p)] 'ff/scroll-down)
585 (define-key global-map [(meta n)] 'ff/scroll-up)
586 (define-key global-map [(meta right)] 'ff/scroll-left)
587 (define-key global-map [(meta left)] 'ff/scroll-right)
588
589 (defun ff/delete-trailing-whitespaces-and-indent ()
590   (interactive)
591   (delete-trailing-whitespace)
592   (indent-region (point-min) (point-max) nil))
593
594 (define-key global-map [(control c) (control q)] 'ff/delete-trailing-whitespaces-and-indent)
595
596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
597 ;; Playing sounds
598 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
599
600 ;; (defun ff/esd-sound (file)
601 ;;   "Plays a sound with the Enlighted sound daemon."
602 ;;   (interactive)
603 ;;   (process-kill-without-query (start-process-shell-command "esdplay"
604 ;;                                                            nil
605 ;;                                                            "esdplay" file)))
606
607 (defun ff/alsa-sound (file)
608   "Plays a sound with ALSA."
609   (interactive)
610   (process-kill-without-query (start-process-shell-command "aplay"
611                                                            nil
612                                                            "aplay" "-q" file)))
613
614 (if (and (boundp 'x-display-name) (string= x-display-name ":0.0"))
615     (defalias 'ff/play-sound-async 'ff/alsa-sound)
616   (defalias 'ff/play-sound-async 'ding))
617
618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
619 ;; I comment stuff often, let's be efficient. shift + down comments
620 ;; the current line and goes down, and shift + up uncomments the line
621 ;; and goes up (they are not the dual of each other, but moving and
622 ;; then uncommenting would be very counter-intuitive).
623 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
624
625 (defun ff/comment-and-go-down (arg)
626   "Comments and goes down ARG lines."
627   (interactive "p")
628   (condition-case nil
629       (comment-region (point-at-bol) (point-at-eol)) (error nil))
630   (next-line 1)
631   (if (> arg 1) (ff/comment-and-go-down (1- arg))))
632
633 (defun ff/uncomment-and-go-up (arg)
634   "Uncomments and goes up ARG lines."
635   (interactive "p")
636   (condition-case nil
637       (uncomment-region (point-at-bol) (point-at-eol)) (error nil))
638   (next-line -1)
639   (if (> arg 1) (ff/uncomment-and-go-up (1- arg))))
640
641 (define-key global-map [(shift down)] 'ff/comment-and-go-down)
642 (define-key global-map [(shift up)] 'ff/uncomment-and-go-up)
643
644 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
645 ;; Counting various entities in text
646 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
647
648 (defun ff/word-occurences ()
649   "Display in a new buffer the list of words sorted by number of
650 occurrences "
651   (interactive)
652
653   (let ((buf (get-buffer-create "*word counting*"))
654         (map (make-sparse-keymap))
655         (nb (make-hash-table))
656         (st (make-hash-table))
657         (result nil))
658
659     ;; Collects all words in a hash table
660
661     (save-excursion
662       (goto-char (point-min))
663       (while (re-search-forward "\\([\\-a-zA-Z\\\\]+\\)" nil t)
664         (let* ((s (downcase (match-string-no-properties 1)))
665                (k (sxhash s)))
666           (puthash k s st)
667           (puthash k (1+ (gethash k nb 0)) nb))))
668
669     ;; Creates the result buffer
670
671     (define-key map "q" 'kill-this-buffer)
672     (display-buffer buf)
673     (set-buffer buf)
674     (setq show-trailing-whitespace nil)
675     (erase-buffer)
676
677     ;; Builds a list from the hash table
678
679     (maphash
680      (lambda (key value)
681        (setq result (cons (cons value (gethash key st)) result)))
682      nb)
683
684     ;; Sort and display it
685
686     (mapc (lambda (x)
687             (if (and (> (car x) 3)
688                      ;; No leading backslash and at least four characters
689                      (string-match "^[^\\]\\{4,\\}" (cdr x))
690                      )
691                 (insert (number-to-string (car x)) " " (cdr x) "\n")))
692           (sort result (lambda (a b) (> (car a) (car b)))))
693
694     ;; Adjust the window size and stuff
695
696     (fit-window-to-buffer (get-buffer-window buf))
697     (use-local-map map)
698     (set-buffer-modified-p nil))
699   )
700
701 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
702 ;; Printing
703 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
704
705 (load "ps-print")
706
707 (setq ps-print-color-p nil
708       ps-paper-type 'letter
709       ;; ps-paper-type 'a4
710       ;; ps-top-margin (* 1.75 56.692)
711       ;; ps-left-margin 56.692
712       ;; ps-bottom-margin 56.692
713       ;; ps-right-margin 56.692
714
715       ;; Simple header. Remove that silly frame shadow.
716       ps-print-header nil
717       ps-print-header-frame nil
718       ps-header-line-pad 0.3
719       ps-header-font-family 'Courier
720       ps-header-title-font-size '(8.5 . 10)
721       ;; ps-header-font-size '(6 . 7)
722       ps-header-font-size '(10 . 12)
723       ps-font-size '(7 . 8)
724       )
725
726 (ps-put 'ps-header-frame-alist 'back-color 1.0)
727 (ps-put 'ps-header-frame-alist 'shadow-color 1.0)
728 (ps-put 'ps-header-frame-alist 'border-color 0.0)
729 (ps-put 'ps-header-frame-alist 'border-width 0.0)
730
731 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
732
733 ;; http://blog.tuxicity.se/elisp/emacs/2010/03/26/rename-file-and-buffer-in-emacs.htm
734
735 (defun rename-file-and-buffer ()
736   "Renames current buffer and file it is visiting."
737   (interactive)
738   (let ((name (buffer-name))
739         (filename (buffer-file-name)))
740     (if (not (and filename (file-exists-p filename)))
741         (message "Buffer '%s' is not visiting a file!" name)
742       (let ((new-name (read-file-name "New name: " filename)))
743         (cond ((get-buffer new-name)
744                (message "A buffer named '%s' already exists!" new-name))
745               (t
746                (rename-file name new-name 1)
747                (rename-buffer new-name)
748                (set-visited-file-name new-name)
749                (set-buffer-modified-p nil)))))))
750
751 (global-set-key (kbd "C-c r") 'rename-file-and-buffer)
752
753 (defun ff/non-existing-filename (dir prefix suffix)
754   "Returns a filename of the form DIR/PREFIX[.n].SUFFIX whose file does
755 not exist"
756   (let ((n 0)
757         (f (concat prefix suffix)))
758     (while (file-exists-p (concat dir "/" f))
759       (setq n (1+ n)
760             f (concat prefix "." (prin1-to-string n) suffix)))
761     f))
762
763 (defun ff/print-buffer-or-region-with-faces (&optional file)
764
765   ;; I am fed up with spell checking highlights
766   (when (and flyspell-mode
767              ;; (or ispell-minor-mode flyspell-mode)
768              (not (y-or-n-p "The spell checking is on, still print ? ")))
769     (error "Printing cancelled, the spell-checking is on"))
770
771   (unless
772       (condition-case nil
773           (ps-print-region-with-faces (region-beginning) (region-end) file)
774         (error nil))
775     (ps-print-buffer-with-faces file)))
776
777 (defun ff/print-to-file (file)
778   "Prints the region if selected or the whole buffer in postscript
779 into FILE."
780   (interactive
781    (list
782     (read-file-name
783      "PS file: " "/tmp/" nil nil
784      (ff/non-existing-filename
785       "/tmp"
786       (replace-regexp-in-string "[^a-zA-Z0-9_.-]" "_" (file-name-nondirectory
787                                                        (buffer-name)))
788       ".ps"))
789     ))
790   (ff/print-buffer-or-region-with-faces file))
791
792 (defun ff/print-to-printer ()
793   "Prints the region if selected or the whole buffer to a postscript
794 printer."
795   (interactive)
796   (message "Printing to '%s'" (getenv "PRINTER"))
797   (ff/print-buffer-or-region-with-faces))
798
799 ;; Can you believe it? There is a "print" key on PC keyboards ...
800
801 (define-key global-map [(print)] 'ff/print-to-file)
802 (define-key global-map [(shift print)] 'ff/print-to-printer)
803
804 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
805 ;; Dealing with the laptop battery
806 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
807
808 (defcustom ff/battery-dirs '("/sys/class/power_supply/BAT0"
809                              "/sys/class/power_supply/BAT1")
810   "*Where to gather the battery information")
811
812 (defcustom ff/temperature-files '("/sys/class/thermal/thermal_zone0/temp"
813                                   "/sys/class/thermal/thermal_zone1/temp")
814   "*Where to gather the thermal information")
815
816 (defun ff/file-first-line (file)
817   (with-temp-buffer
818     (insert-file-contents-literally file)
819     (buffer-substring (point-at-bol) (point-at-eol))))
820
821 (defun ff/battery-discharging (l)
822   (and l (or (string= (ff/file-first-line (concat (car l) "/status")) "Discharging")
823              (ff/battery-discharging (cdr l)))))
824
825 ;; If there is one "Discharging" among the states of all the
826 ;; batteries, the global state is 'discharging. Otherwise, if there is
827 ;; a "Charging", the state is 'charging. If none is true, it is
828 ;; 'unknown
829 (defun ff/battery-state (l)
830   (if l
831       (let ((u (ff/file-first-line (concat (car l) "/status"))))
832         (if (string= u "Discharging") 'discharging
833           (let ((s (ff/battery-state (cdr l))))
834             (if (eq s 'discharging) 'discharging
835               (if (or (eq s 'charging) (string= u "Charging"))
836                   'charging
837                 'unknown))
838             )
839           )
840         )
841     'unknown))
842
843 (defun ff/sum-numbers (list-files prefix)
844   (apply '+
845          (mapcar
846           (lambda (f) (string-to-number (ff/file-first-line (format "%s/%s" f prefix))))
847           list-files)))
848
849 (defun ff/battery-percent ()
850   (condition-case nil
851       (/ (* 100 (ff/sum-numbers ff/battery-dirs "energy_now"))
852          (ff/sum-numbers ff/battery-dirs "energy_full"))
853     (error -1))
854   )
855
856 (defun ff/temp-and-battery-info-string () (interactive)
857        (condition-case nil
858            (concat
859
860             ;; The temperature
861
862             (let ((temp (/
863                          (apply 'max (mapcar
864                                       (lambda (f) (string-to-number (ff/file-first-line f)))
865                                       ff/temperature-files))
866                          1000)))
867               (if (> temp 50)
868                   (concat
869                    (let ((s (format "%dC " temp)))
870                      (if (> temp 70) (propertize s 'face
871                                                  'font-lock-warning-face)
872                        s))
873                    )
874                 )
875               )
876
877             ;; The battery
878
879             (pcase (ff/battery-state ff/battery-dirs)
880               (`charging (format "L%d%%" (ff/battery-percent)))
881               (`discharging (format "B%d%%" (ff/battery-percent)))
882               (code "L"))
883
884             )
885
886          (error nil))
887        )
888
889 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
890
891 (defun ff/system-info () (interactive)
892
893        (let ((buf (get-buffer-create "*system info*"))
894              (map (make-sparse-keymap)))
895
896          (define-key map "q" 'kill-this-buffer)
897          (display-buffer buf)
898          (set-buffer buf)
899          (setq show-trailing-whitespace nil)
900          (erase-buffer)
901
902          (let ((highlight nil))
903
904            (mapc (lambda (x)
905                    (insert
906                     (if (setq highlight (not highlight))
907                         (propertize
908                          (with-temp-buffer (apply 'call-process x)
909                                            (buffer-string))
910                          'face '(:background "#c0c0ff"))
911                       (with-temp-buffer (apply 'call-process x)
912                                         (buffer-string))
913                       ))
914                    )
915
916                  '(
917                    ("hostname" nil t nil "-v")
918                    ("acpi" nil t)
919                    ("df" nil t nil "-h")
920                    ;; ("mount" nil t)
921                    ("ifconfig" nil t)
922                    ("ssh-add" nil t nil "-l")
923                    )))
924
925          (goto-char (point-min))
926          (while (re-search-forward "^$" nil t) (backward-delete-char 1))
927
928          (fit-window-to-buffer (get-buffer-window buf))
929          (use-local-map map)
930          (set-buffer-modified-p nil)
931          ))
932
933 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
934 ;; Make a sound when there is new mail
935 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
936
937 ;; I do not like sounds anymore
938
939 ;; (setq ff/already-boinged-for-mail nil)
940
941 ;; (defun ff/boing-if-new-mail ()
942 ;; (if mail (when (not ff/already-boinged-for-mail)
943 ;; ;; (ff/play-sound-async "~/local/sounds/boing1.wav")
944 ;; ;; (ff/show-unspooled-mails)
945 ;; (setq ff/already-boinged-for-mail t))
946 ;; (setq ff/already-boinged-for-mail nil))
947 ;; )
948
949 ;; (add-hook 'display-time-hook 'ff/boing-if-new-mail)
950
951 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
952 ;; Display time
953 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
954
955 (setq
956
957  display-time-interval 15 ;; Check every 15s
958
959  display-time-string-forms `(
960
961                              ;; (if mail
962                              ;;     (concat " "
963                              ;;             (propertize " mail "
964                              ;;                         'face 'ff/mail-alarm-face)
965                              ;;             " ")
966                              ;;   )
967
968                              (propertize (concat 24-hours ":" minutes
969                                                  " "
970                                                  dayname " "
971                                                  monthname " "
972                                                  day)
973                                          'face 'ff/date-info-face)
974
975                              load
976
977                              ,(if (ff/temp-and-battery-info-string)
978                                   '(concat " " (ff/temp-and-battery-info-string)))
979
980                              )
981
982  ;; display-time-format "%b %a %e %H:%M"
983  ;; display-time-mail-face nil
984  )
985
986 ;; Show the time, mail and stuff
987 (display-time)
988
989 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
990 ;; Moving through buffers
991 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
992
993 (defun ff/next-buffer ()
994   "Switches to the next buffer in cyclic order."
995   (interactive)
996   (let ((buffer (current-buffer)))
997     (switch-to-buffer (other-buffer buffer))
998     (bury-buffer buffer)))
999
1000 (defun ff/prev-buffer ()
1001   "Switches to the previous buffer in cyclic order."
1002   (interactive)
1003   (let ((list (nreverse (buffer-list)))
1004         found)
1005     (while (and (not found) list)
1006       (let ((buffer (car list)))
1007         (if (and (not (get-buffer-window buffer))
1008                  (not (string-match "\\` " (buffer-name buffer))))
1009             (setq found buffer)))
1010       (setq list (cdr list)))
1011     (switch-to-buffer found)))
1012
1013 (define-key global-map [?\C-x right] 'ff/next-buffer)
1014 (define-key global-map [?\C-x left] 'ff/prev-buffer)
1015 (define-key global-map [?\C-'] 'ff/next-buffer)
1016 (define-key global-map [?\C-\;] 'ff/prev-buffer)
1017
1018 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1019 ;; There is actually a decent terminal emulator in emacs!
1020 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1021
1022 (load "term")
1023
1024 (defun ff/kill-associated-buffer (process str) (interactive)
1025        (let ((buffer (process-buffer process)))
1026          (kill-buffer buffer))
1027        (message "Process finished (%s)" (replace-regexp-in-string "\n$" "" str)))
1028
1029 (defun ff/kill-associated-buffer-and-delete-windows (process str) (interactive)
1030        (let ((buffer (process-buffer process)))
1031          (delete-windows-on buffer)
1032          (kill-buffer buffer))
1033        (message "Process finished (%s)" (replace-regexp-in-string "\n$" "" str)))
1034
1035 (defun ff/shell-new-buffer (buffername program &rest param)
1036   "Start a terminal-emulator in a new buffer with the shell PROGRAM,
1037 optionally invoked with the parameters PARAM. The process associated
1038 to the shell can be killed without query."
1039
1040   (interactive)
1041
1042   (let ((n 1)
1043         (bn buffername))
1044
1045     (while (get-buffer (concat "*" bn "*"))
1046       (setq n (1+ n)
1047             bn (format "%s<%d>" buffername n)))
1048
1049     (set-buffer (apply 'make-term (append (list bn program nil) param)))
1050
1051     (setq show-trailing-whitespace nil)
1052     (term-char-mode)
1053     (message "C-c C-k term-char-mode, C-c C-j term-line-mode. \
1054 In line mode: M-p previous line, M-n next line.")
1055
1056     ;; A standard setup of the face above is not enough, I have to
1057     ;; force them here. Since I have a gray90 background, I like
1058     ;; darker colors.
1059
1060     (when window-system
1061       (ff/configure-faces
1062        '((term-green :foreground "green3")
1063          (term-cyan :foreground "cyan3")
1064          (term-default-fg-inv :foreground "gray90" :background "black")
1065          )))
1066
1067     (term-set-escape-char ?\C-x)
1068
1069     ;; I like the shell buffer and windows to be deleted when the
1070     ;; shell process terminates. It's a bit of a mess to acheive this.
1071
1072     (let ((process (get-buffer-process (current-buffer))))
1073       (process-kill-without-query process)
1074       (set-process-sentinel process
1075                             ;; 'ff/kill-associated-buffer-and-delete-windows
1076                             'ff/kill-associated-buffer
1077                             ))
1078
1079     ;; (switch-to-buffer-other-window (concat "*" bn "*"))
1080     (switch-to-buffer (concat "*" bn "*"))
1081     ))
1082
1083 (defcustom ff/default-bash-commands '("ssh")
1084   "*List of commands to be used for completion when invoking a new
1085 bash shell with `ff/bash-new-buffer'.")
1086
1087 (defun ff/bash-new-buffer (universal)
1088   "Starts a bash in a new buffer. When invoked with a universal
1089 argument, asks for a command to execute in that bash shell. The list
1090 of commands in `ff/default-bash-commands' is used for auto-completion"
1091   (interactive "P")
1092
1093   (if universal
1094       (let ((cmd (completing-read
1095                   "Command: "
1096                   (mapcar (lambda (x) (cons x t)) ff/default-bash-commands))))
1097         (ff/shell-new-buffer cmd "/bin/bash" "-c" cmd))
1098
1099     (ff/shell-new-buffer "bash" "/bin/bash")))
1100
1101 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1102 ;; vc stuff for CVS
1103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1104
1105 (setq ;; Always follow links if the file is under version control
1106  vc-follow-symlinks t
1107  )
1108
1109 (when (load "vc-git" nil t)
1110   (add-to-list 'vc-handled-backends 'GIT))
1111
1112 ;; alarm-vc.el is one of my own scripts, check my web page
1113
1114 (when (ff/load-or-alert "alarm-vc" t)
1115   (setq alarm-vc-mode-exceptions "^VM"))
1116
1117 (when (ff/load-or-alert "git")
1118   (setq git-show-unknown nil)
1119   )
1120
1121 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1122 ;; Makes .sh and others files executable automagically
1123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1124
1125 ;; Please consider the security-related consequences of using it
1126
1127 ;; (defun ff/make-shell-scripts-executable (&optional filename)
1128 ;; (setq filename (or filename (buffer-name)))
1129 ;; (when (and (string-match "\\.sh$\\|\\.pl$\\|\\.rb" filename)
1130 ;; (not (file-executable-p filename))
1131 ;; )
1132 ;; (set-file-modes filename 493)
1133 ;; (message "Made %s executable" filename)))
1134
1135 ;; (add-hook 'after-save-hook 'ff/make-shell-scripts-executable)
1136
1137 (add-hook 'after-save-hook
1138           'executable-make-buffer-file-executable-if-script-p)
1139
1140 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1141 ;; Cool stuff to navigate in emacs-lisp sources
1142 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1143
1144 (load "find-func")
1145
1146 (defun ff/goto-function-definition (&optional goback)
1147   "Go directly to the definition of the function at point. With
1148 goback argument, go back where we were."
1149   (interactive "P")
1150   (if goback
1151       (if (not (and (boundp 'goto-function-history) goto-function-history))
1152           (error "We were nowhere, buddy")
1153         (message "Come back")
1154         (switch-to-buffer (car (car goto-function-history)))
1155         (goto-char (cdr (car goto-function-history)))
1156         (setq goto-function-history (cdr goto-function-history)))
1157
1158     (let ((function (function-called-at-point)))
1159       (when function
1160         (let ((location (find-function-search-for-symbol
1161                          function nil
1162                          (symbol-file function))))
1163           (setq goto-function-history
1164                 (cons (cons (current-buffer) (point))
1165                       (and (boundp 'goto-function-history)
1166                            goto-function-history)))
1167           (pop-to-buffer (car location))
1168           (goto-char (cdr location)))))))
1169
1170 (define-key global-map [(meta g)] 'ff/goto-function-definition)
1171 (define-key global-map [(meta G)] (lambda () (interactive)
1172                                     (ff/goto-function-definition t)))
1173
1174 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1175 ;; The big stuff (bbdb, mailcrypt, etc.)
1176 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1177
1178 ;; Failsafe version if we can't load bbdb
1179 (defun ff/explicit-name (email) email)
1180
1181 (load "vc-git")
1182
1183 (when (ff/load-or-alert "bbdb")
1184
1185   (setq
1186    ;; Stop asking (if not t or nil, will not ask)
1187    bbdb-offer-save 'never
1188    ;; I hate when bbdb decides to mess up my windows
1189    bbdb-use-pop-up nil
1190    ;; I have no problem with bbdb asking me if the sender email
1191    ;; does not match exactly the address we have in the database
1192    bbdb-quiet-about-name-mismatches 0
1193    ;; I have european friends, too
1194    bbdb-north-american-phone-numbers-p nil
1195    ;; To cycle through all possible addresses
1196    bbdb-complete-name-allow-cycling t
1197    ;; Cycle with full names only, not through all net-addresses alone too
1198    bbdb-dwim-net-address-allow-redundancy t
1199    ;; Do not add new addresses automatically
1200    bbdb-always-add-addresses nil
1201    )
1202
1203   (defface ff/known-address-face
1204     '((t (:foreground "blue2")))
1205     "The face to display known mail identities.")
1206
1207   (defface ff/unknown-address-face
1208     '((t (:foreground "gray50")))
1209     "The face to display unknown mail identities.")
1210
1211   (defun ff/explicit-name (email)
1212     "Returns a string identity for the first address in EMAIL. The
1213 identity is taken from bbdb if possible or from the address itself
1214 with mail-extract-address-components. The suffix \"& al.\" is added if
1215 there are more than one address.
1216
1217 If no bbdb record is found, the name is propertized with the face
1218 ff/unknown-address-face. If a record is found and contains a note
1219 'face, the associated face is used, otherwise
1220 ff/known-address-face is used."
1221
1222     (and email
1223          (let* ((data (mail-extract-address-components email))
1224                 (name (car data))
1225                 (net (cadr data))
1226                 (record (bbdb-search-simple nil net)))
1227
1228            (concat
1229
1230             (condition-case nil
1231                 (propertize (bbdb-record-name record)
1232                             'face
1233                             (or (cdr (assoc 'face
1234                                             (bbdb-record-raw-notes record)))
1235                                 'ff/known-address-face))
1236               (error
1237                (propertize (or (and data (concat "<" net ">"))
1238                                "*undefined*")
1239                            'face 'ff/unknown-address-face)
1240                ))
1241             (if (string-match "," (mail-strip-quoted-names email)) " & al.")
1242             )))
1243     )
1244
1245   (ff/configure-faces '((ff/robot-address-face :foreground "green4")
1246                         (ff/personal-address-face :foreground "dark magenta" :weight 'bold)
1247                         (ff/important-address-face :foreground "red3"
1248                                                    :weight 'bold
1249                                                    )))
1250
1251   )
1252
1253 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1254 ;; An encrypted file to put secure stuff (passwords, ...)
1255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1256
1257 (when (ff/load-or-alert "mailcrypt")
1258   (mc-setversion "gpg")
1259   ;; Keep the passphrase for 10min
1260   (setq mc-passwd-timeout 600
1261         ff/secure-note-file "~/private/secure-notes.gpg")
1262   )
1263
1264 (defface ff/secure-date
1265   '((t (:background "white" :weight bold)))
1266   "The face to display the dates in the modeline.")
1267
1268 (defun ff/secure-note-add () (interactive)
1269
1270        (unless
1271            (let ((b (find-buffer-visiting ff/secure-note-file)))
1272              (and b (switch-to-buffer b)))
1273          (find-file ff/secure-note-file)
1274          ;; Adds a new entry (i.e. date and a bunch of empty lines)
1275          (goto-char (point-min))
1276          (insert "-- "
1277                  (format-time-string "%Y %b %d %H:%M:%S" (current-time))
1278                  " --\n\n")
1279          (previous-line 1)
1280          )
1281
1282        ;; Colorizes the dates
1283
1284        (save-excursion
1285          (goto-char (point-min))
1286          (while (re-search-forward
1287                  "^-- [0-9]+ [a-z]+ [0-9]+ [0-9]+:[0-9]+:[0-9]+ -+$"
1288                  nil t)
1289            (add-text-properties
1290             (match-beginning 0) (1+ (match-end 0))
1291             '(face ff/secure-date rear-nonsticky t))))
1292
1293        (set-buffer-modified-p nil)
1294        (setq buffer-undo-list nil)
1295        )
1296
1297 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1298 ;; Spelling
1299 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1300
1301 (setq ;; For french, aspell is far better than ispell
1302  ispell-program-name "aspell"
1303  ;; To avoid ispell errors in figure filenames, labels, references.
1304  ;;       ispell-tex-skip-alists
1305  ;;       (list
1306  ;;        (append (car ispell-tex-skip-alists)
1307  ;;                '(("\\\\citep"           ispell-tex-arg-end) ;; JMLR
1308  ;;                  ("\\\\cite"            ispell-tex-arg-end)
1309  ;;                  ("\\\\nocite"          ispell-tex-arg-end)
1310  ;;                  ("\\\\includegraphics" ispell-tex-arg-end)
1311  ;;                  ("\\\\author"          ispell-tex-arg-end)
1312  ;;                  ("\\\\ref"             ispell-tex-arg-end)
1313  ;;                  ("\\\\label"           ispell-tex-arg-end)
1314  ;;                  ))
1315  ;;        (cadr ispell-tex-skip-alists))
1316
1317  ;; So that reftex follows the text when moving in the summary
1318  reftex-toc-follow-mode nil
1319  ;; So that reftex visits files to follow
1320  reftex-revisit-to-follow t
1321  )
1322
1323 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1324 ;; Used in a \includegraphics runs xfig with the corresponding .fig
1325 ;; file or gimp with the corresponding bitmap picture
1326 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1327
1328 (defun ff/run-eps-edition (prefix rules &optional force)
1329   (if rules
1330       (let ((filename (concat prefix (car (car rules)))))
1331         (if (or force (file-exists-p filename))
1332             (start-process "latex-eps-editor" nil (cdr (car rules)) filename)
1333           (ff/run-eps-edition prefix (cdr rules) force)))
1334     (message "No original file found for %seps" prefix)))
1335
1336 (defcustom ff/xdvi-for-latex-options nil
1337   "*Options to pass to xdvi when invoking `ff/run-viewer'")
1338
1339 (defun ff/run-viewer (universal)
1340
1341   "Starts an editor for the .eps at point (either xfig or gimp,
1342 depending with the original file it can find), or starts xdvi for
1343 the current .tex if no .eps is found at point. When run with a
1344 universal argument starts xfig even if the .fig does not exist"
1345
1346   (interactive "P")
1347
1348   (if (and (save-excursion
1349              (and (re-search-backward "{" (point-at-bol) t)
1350                   (or (re-search-forward "{\\([^{}]*.\\)eps}" (point-at-eol) t)
1351                       (re-search-forward "{\\([^{}]*.\\)pdf}" (point-at-eol) t)
1352                       (re-search-forward "{\\([^{}]*.\\)pdf_t}" (point-at-eol) t)
1353                       (re-search-forward "{\\([^{}]*.\\)png}" (point-at-eol) t)
1354                       (re-search-forward "{\\([^{}]*.\\)jpg}" (point-at-eol) t)
1355                       )))
1356            (and (<= (match-beginning 1) (point))
1357                 (>= (match-end 1) (- (point) 2))))
1358
1359       (ff/run-eps-edition (match-string-no-properties 1)
1360                           '(("fig" . "xfig")
1361                             ("jpg" . "gimp" )
1362                             ("png" . "gimp") ("pgm" . "gimp") ("ppm" . "gimp")
1363                             ("jpg" . "xv"))
1364                           universal)
1365
1366     (if (not (and (buffer-file-name) (string-match "\\(.*\\)\.tex$"
1367                                                    (buffer-file-name))))
1368         (message "Not a latex file!")
1369       (condition-case nil (kill-process xdvi-process) (error nil))
1370       (let ((dvi-name (concat (match-string 1 (buffer-file-name)) ".dvi")))
1371         (if (not (file-exists-p dvi-name)) (error "Can not find %s !" dvi-name)
1372           (message "Starting xdvi with %s" dvi-name)
1373           (setq xdvi-process (apply 'start-process
1374                                     (append '("xdvi-for-latex" nil "xdvi")
1375                                             ff/xdvi-for-latex-options
1376                                             (list dvi-name))))
1377           (process-kill-without-query xdvi-process))))
1378     ))
1379
1380 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1381 ;; Tex mode
1382
1383 ;; When working on a tex file with other people, I can just change
1384 ;; ff/tex-command in the -*- part of the file so that I don't mess up
1385 ;; other's people configuration.
1386
1387 (defadvice tex-file (around ff/set-my-own-tex-command () activate)
1388   (let ((tex-command
1389          (or (and (boundp 'ff/tex-command)
1390                   ff/tex-command)
1391              tex-command)))
1392     ad-do-it))
1393
1394 ;; This is a bit hardcore, but really I can't bear the superscripts in
1395 ;; my emacs window and could not find another way to deactivate them.
1396
1397 (load "tex-mode")
1398 (defun tex-font-lock-suscript (pos) ())
1399
1400 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1401 ;; Prevents many errors from beeping and makes the others play a nifty
1402 ;; sound
1403 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1404
1405 (defun ff/ring-bell ()
1406   (unless (memq this-command
1407                 '(isearch-abort
1408                   abort-recursive-edit
1409                   exit-minibuffer
1410                   keyboard-quit
1411                   backward-delete-char-untabify
1412                   delete-backward-char
1413                   minibuffer-complete-and-exit
1414                   previous-line next-line
1415                   backward-char forward-char
1416                   scroll-up scroll-down
1417                   enlarge-window-horizontally shrink-window-horizontally
1418                   enlarge-window shrink-window
1419                   minibuffer-complete
1420                   ))
1421     ;; (message "command [%s]" (prin1-to-string this-command))
1422     ;; (ff/play-sound-async "~/local/sounds/short_la.wav")
1423     ))
1424
1425 (setq ring-bell-function 'ff/ring-bell)
1426
1427 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1428 ;; Past the content of the url currently in the kill-ring with
1429 ;; shift-click 2
1430 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1431
1432 (defun ff/insert-url (&optional url)
1433   "Downloads an URL with lynx and inserts it after the point."
1434   (interactive "MUrl: ")
1435   (when url
1436     (message "Inserting %s" url)
1437     (insert (concat "from: " url "\n\n"))
1438     ;; (call-process "lynx" nil t nil "-nolist" "-dump" url))
1439     (call-process "w3m" nil t nil "-dump" url))
1440   )
1441
1442 (define-key global-map [(shift mouse-2)]
1443   (lambda () (interactive) (ff/insert-url (current-kill 0))))
1444
1445 ;; lookup-dict is one of my own scripts, check my web page
1446
1447 (when (ff/load-or-alert "lookup-dict" t)
1448   (define-key global-map [(control \?)] 'lookup-dict))
1449
1450 ;; (defun ff/generate-password () (interactive)
1451 ;; (let ((c "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"))
1452 ;; (nth (random (length c)) c))
1453
1454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1455 ;; Automatization of things I do often
1456 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1457
1458 (defun ff/snip () (interactive)
1459        (let ((start (condition-case nil (region-beginning) (error (point))))
1460              (end (condition-case nil (region-end) (error (point)))))
1461          (goto-char end)
1462          (insert "---------------------------- snip snip -------------------------------\n")
1463          (goto-char start)
1464          (insert "---------------------------- snip snip -------------------------------\n")
1465          ))
1466
1467 (defun ff/start-latex ()
1468   "Adds all that stuff to start a new LaTeX document."
1469   (interactive)
1470   (goto-char (point-min))
1471   (insert "%% -*- mode: latex; mode: reftex; mode: flyspell; coding: utf-8; tex-command: \"pdflatex.sh\" -*-
1472
1473 \\documentclass[12pt]{article}
1474 \\usepackage[a4paper,top=2.5cm,bottom=2cm,left=2.5cm,right=2.5cm]{geometry}
1475 \\usepackage[utf8]{inputenc}
1476 \\usepackage{amsmath}
1477 \\usepackage{amssymb}
1478 \\usepackage[pdftex]{graphicx}
1479 \\usepackage{microtype}
1480 \\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue,citecolor=blue]{hyperref}
1481
1482 \\setlength{\\parindent}{0cm}
1483 \\setlength{\\parskip}{12pt}
1484 \\renewcommand{\\baselinestretch}{1.3}
1485
1486 \\def\\argmax{\\operatornamewithlimits{argmax}}
1487 \\def\\argmin{\\operatornamewithlimits{argmin}}
1488
1489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1490 %% Open sans font
1491 %%\\usepackage[default]{opensans}
1492 %%\\usepackage{cmbright}
1493 %%\\renewcommand{\\familydefault}{fos}
1494 %%\\renewcommand{\\seriesdefault}{l}
1495 %%\\renewcommand{\\bfdefault}{sb}
1496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1497 %% The \\todo command
1498 \\newcounter{nbdrafts}
1499 \\setcounter{nbdrafts}{0}
1500 \\makeatletter
1501 \\newcommand{\\checknbdrafts}{
1502 \\ifnum \\thenbdrafts > 0
1503 \\@latex@warning@no@line{*WARNING* The document contains \\thenbdrafts \\space draft note(s)}
1504 \\fi}
1505 \\newcommand{\\todo}[1]{\\addtocounter{nbdrafts}{1}{\\color{red} #1}}
1506 \\makeatother
1507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1508
1509 \\begin{document}
1510
1511 ")
1512   (save-excursion
1513     (goto-char (point-max))
1514     (insert "
1515
1516 \\end{document}
1517 "))
1518   (latex-mode))
1519
1520 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1521
1522 (defun ff/add-copyrights ()
1523   "Adds two lines for the (C) at the beginning of current buffer."
1524   (interactive)
1525
1526   (let ((comment-style 'plain))
1527
1528     (goto-char (point-min))
1529
1530     ;; If this is a script, put the copyrights after the first line
1531
1532     (when (re-search-forward "^#!" nil t)
1533       (beginning-of-line)
1534       (next-line 1))
1535
1536     (let ((start (point))
1537           (comment-style 'box))
1538       (insert
1539        (concat
1540
1541         "\nSTART_IP_HEADER\n"
1542
1543         (when (boundp 'user-full-name)
1544           (concat "\nWritten by " user-full-name "\n"))
1545
1546         (when (boundp 'user-mail-address)
1547           (concat "Contact <" user-mail-address "> for comments & bug reports\n"))
1548
1549         "\nEND_IP_HEADER\n"
1550         ))
1551
1552       (comment-region start (point)))
1553
1554     ))
1555
1556 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1557
1558 (defun ff/remove-ip-header () (interactive)
1559        (save-excursion
1560          (goto-char (point-min))
1561          (when (and (re-search-forward "START_IP_HEADER" nil t)
1562                     (re-search-forward "END_IP_HEADER" nil t))
1563            (message "yep"))
1564          ))
1565
1566 (defun ff/add-gpl ()
1567   "Adds the GPL statements at the beginning of current buffer."
1568   (interactive)
1569   (let ((comment-style 'box)
1570         (gpl
1571          (concat
1572
1573           ;;           "
1574           ;; This program is free software; you can redistribute it and/or
1575           ;; modify it under the terms of the GNU General Public License
1576           ;; version 2 as published by the Free Software Foundation.
1577
1578           ;; This program is distributed in the hope that it will be useful, but
1579           ;; WITHOUT ANY WARRANTY\; without even the implied warranty of
1580           ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1581           ;; General Public License for more details.
1582           ;; "
1583
1584           "
1585 START_IP_HEADER
1586
1587 This program is free software: you can redistribute it and/or modify
1588 it under the terms of the version 3 of the GNU General Public License
1589 as published by the Free Software Foundation.
1590
1591 This program is distributed in the hope that it will be useful, but
1592 WITHOUT ANY WARRANTY; without even the implied warranty of
1593 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1594 General Public License for more details.
1595
1596 You should have received a copy of the GNU General Public License
1597 along with this program. If not, see <http://www.gnu.org/licenses/>.
1598
1599 "
1600           (when (boundp 'user-full-name)
1601             (concat "Written by and Copyright (C) " user-full-name "\n"))
1602
1603           (when (boundp 'user-mail-address)
1604             (concat "Contact <" user-mail-address "> for comments & bug reports\n"))
1605
1606           "
1607 END_IP_HEADER
1608 "
1609
1610           )))
1611
1612     (goto-char (point-min))
1613
1614     ;; If this is a script, put the gpl after the first line
1615     (when (re-search-forward "^#!" nil t)
1616       (beginning-of-line)
1617       (next-line 1))
1618
1619     (let ((start (point)))
1620       (insert gpl)
1621       (comment-region start (point)))
1622     ))
1623
1624 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1625
1626 (defun ff/start-c ()
1627   "Adds the header to start a C program."
1628   (interactive)
1629   ;;   (beginning-of-buffer)
1630   (insert
1631    "
1632 #include <stdio.h>
1633 #include <stdlib.h>
1634
1635 int main(int argc, char **argv) {
1636   exit(EXIT_SUCCESS);
1637 }
1638 ")
1639   (previous-line 2)
1640   )
1641
1642 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1643
1644 (defun ff/start-c++ ()
1645   "Adds the header to start a C++ program."
1646   (interactive)
1647   ;;   (beginning-of-buffer)
1648   (insert
1649    "
1650 #include <iostream>
1651 #include <fstream>
1652 #include <cmath>
1653 #include <stdio.h>
1654 #include <stdlib.h>
1655
1656 using namespace std;
1657
1658 int main(int argc, char **argv) {
1659
1660 }
1661 ")
1662   (previous-line 2)
1663   )
1664
1665 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1666
1667 (defun ff/headerize ()
1668   "Adds the #define HEADER_H, etc."
1669   (interactive)
1670   (let ((flag-name (replace-regexp-in-string
1671                     "[\. \(\)]" "_"
1672                     (upcase (file-name-nondirectory (buffer-file-name))))))
1673     (goto-char (point-max))
1674     (insert "\n#endif\n")
1675     (goto-char (point-min))
1676     (insert (concat "#ifndef " flag-name "\n"))
1677     (insert (concat "#define " flag-name "\n"))
1678     )
1679   )
1680
1681 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1682
1683 (defun ff/start-html ()
1684   "Adds all that stuff to start a new HTML file."
1685   (interactive)
1686   (goto-char (point-min))
1687   (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>
1688 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
1689
1690 <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">
1691
1692 <head>
1693 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
1694 <title></title>
1695 <style>
1696 p {
1697  color:#009900;
1698 }
1699 </style>
1700 </head>
1701
1702 <body>
1703 ")
1704   (goto-char (point-max))
1705   (insert "
1706 </body>
1707
1708 </html>
1709 ")
1710   (html-mode))
1711
1712 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1713
1714 ;; Insert a line showing all the variables written on the current line
1715 ;; and separated by commas
1716
1717 (defun ff/cout-var (arg)
1718   "Invoked on a line with a list of variables names,
1719 it inserts a line which displays their values in cout, or cerr if
1720 the function is invoked with a universal arg"
1721   (interactive "P")
1722   (let ((line (if arg "cerr" "cout")))
1723     (goto-char (point-at-bol))
1724     ;; Regexp syntax sucks moose balls, honnest. To match '[', just
1725     ;; put it as the first char in the [...] ... This leads to some
1726     ;; obvious things like the following
1727     (while (re-search-forward "\\([][a-zA-Z0-9_.:\(\)]+\\)" (point-at-eol) t)
1728       (setq line
1729             (concat line " << \" "
1730                     (match-string 1) " = \" << " (match-string 1))))
1731     (goto-char (point-at-bol))
1732     (kill-line)
1733     (insert line " << endl\;\n")
1734     (indent-region (point-at-bol 0) (point-at-eol 0) nil)
1735     ))
1736
1737 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1738
1739 (defun ff/clean-article ()
1740   "Cleans up an article by removing the leading blanks on each line
1741 and refilling all the paragraphs."
1742   (interactive)
1743   (let ((fill-column 92))
1744     (goto-char (point-min))
1745     (while (re-search-forward "^\\ +" nil t)
1746       (replace-match "" nil nil))
1747     (fill-individual-paragraphs (point-min) (point-max) t)))
1748
1749 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1750
1751 (defun ff/start-slide ()
1752   (interactive)
1753   (insert "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1754
1755 \\begin{frame}{")
1756
1757   (save-excursion (insert "}{}
1758
1759 \\end{frame}
1760
1761 "))
1762   )
1763
1764 (add-hook
1765  'latex-mode-hook
1766  (lambda ()
1767    (define-key latex-mode-map [(meta S)] 'ff/start-slide)
1768    (define-key latex-mode-map [(control c) (control a)] 'align-current)
1769    (define-key latex-mode-map [(control end)] 'tex-close-latex-block)
1770    (define-key latex-mode-map [(control tab)] 'ispell-complete-word)
1771    (copy-face 'default 'tex-verbatim)
1772    ;; (ff/configure-faces '((tex-verbatim :background "gray95")))
1773    ))
1774
1775 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1776
1777 (defun ff/start-test-code ()
1778   (interactive)
1779   (let ((start (point)))
1780     (insert "
1781 { // ******************************* START ***************************
1782 #warning Test code added on "
1783             (format-time-string "%04Y %b %02d %02H:%02M:%02S" (current-time))
1784             "
1785
1786 } // ******************************** END ****************************
1787
1788 ")
1789     (indent-region start (point) nil))
1790   (previous-line 3)
1791   (c-indent-command))
1792
1793 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1794
1795 (defun ff/code-to-html () (interactive)
1796        (save-restriction
1797          (narrow-to-region (region-beginning) (region-end))
1798          (replace-string "\"" "&quot;" nil (point-min) (point-max))
1799          (replace-string " " "&nbsp;" nil (point-min) (point-max))
1800          (replace-string ">" "&gt;" nil (point-min) (point-max))
1801          (replace-string "<" "&lt;" nil (point-min) (point-max))
1802          (replace-string "\e" "^[" nil (point-min) (point-max))
1803          (replace-string "\7f" "^?" nil (point-min) (point-max))
1804          (replace-string "\1f" "^_" nil (point-min) (point-max))
1805          (replace-regexp "$" "<br />" nil (point-min) (point-max))
1806          )
1807        )
1808
1809 (defun ff/downcase-html-tags () (interactive)
1810        (save-excursion
1811          (beginning-of-buffer)
1812          (while (re-search-forward "<\\([^>]+\\)>" nil t)
1813            (downcase-region (match-beginning 1) (match-end 1)))
1814          )
1815        )
1816
1817 ;; If we enter html mode and there is no makefile around, create a
1818 ;; compilation command with tidy (this is cool stuff)
1819
1820 (add-hook 'html-mode-hook
1821           (lambda ()
1822             (unless (or (not (buffer-file-name))
1823                         (file-exists-p "makefile")
1824                         (file-exists-p "Makefile"))
1825               (set (make-local-variable 'compile-command)
1826                    (let ((fn (file-name-nondirectory buffer-file-name)))
1827                      (format "tidy -utf8 %s > /tmp/%s" fn fn))))))
1828
1829 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1830
1831 (defun ff/count-words-region (beginning end)
1832   "Print number of words in the region.
1833 Words are defined as at least one word-constituent character
1834 followed by at least one character that is not a
1835 word-constituent.  The buffer's syntax table determines which
1836 characters these are."
1837
1838   (interactive "r")
1839   (message "Counting words in region ... ")
1840   (save-excursion
1841     (goto-char beginning)
1842     (let ((count 0))
1843       (while (< (point) end)
1844         (re-search-forward "\\w+\\W+")
1845         (setq count (1+ count)))
1846       (cond ((zerop count) (message "The region does NOT have any word."))
1847             ((= 1 count) (message "The region has 1 word."))
1848             (t (message "The region has %d words." count))))))
1849
1850 ;; (add-hook 'html-mode-hook 'flyspell-mode)
1851
1852 (defun ff/tidy-html ()
1853   "Run tidy in on the content of the current buffer, put the result in
1854 a file in /tmp"
1855   (interactive)
1856   (call-process-region (point-min) (point-max)
1857                        "/usr/bin/tidy"
1858                        nil
1859                        (list nil (make-temp-file "/tmp/tidy-html."))))
1860
1861 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1862
1863 ;; Create the adequate embryo of a file if it does not exist
1864
1865 (defun ff/start-file () (interactive)
1866        (let ((filename (buffer-file-name)))
1867          (when filename
1868
1869            (when (string-match "\\.sh$" filename)
1870              (sh-mode)
1871              (insert "#!/bin/bash\n\nset -e\nset -o pipefail\n\n")
1872              (save-excursion
1873                (ff/add-copyrights))
1874              )
1875
1876            (when (string-match "\\.html$" filename)
1877              (html-mode)
1878              (ff/start-html)
1879              (previous-line 4)
1880              )
1881
1882            (when (string-match "\\.h$" filename)
1883              (c++-mode)
1884              (ff/headerize)
1885              (save-excursion
1886                (ff/add-copyrights)
1887                (newline))
1888              (newline)
1889              (newline)
1890              (previous-line 1)
1891              )
1892
1893            (when (string-match "\\.c$" filename)
1894              (c-mode)
1895              (ff/add-copyrights)
1896              (ff/start-c))
1897
1898            (when (string-match "\.\\(cc\\|cpp\\)$" filename)
1899              (c++-mode)
1900              (ff/add-copyrights)
1901              (let ((headername  (replace-regexp-in-string "\\.\\(cc\\|cpp\\)$" ".h"
1902                                                           filename)))
1903                (if (file-exists-p headername)
1904                    (insert (concat "\n#include \"" (file-name-nondirectory headername) "\"\n"))
1905                  (ff/start-c++))
1906                ))
1907
1908            (when (string-match "\\.tex$" filename)
1909              (latex-mode)
1910              (ff/start-latex)
1911              ))
1912          )
1913        (set-buffer-modified-p nil)
1914        )
1915
1916 (if (>= emacs-major-version 22)
1917     (add-to-list 'find-file-not-found-functions 'ff/start-file)
1918   (add-to-list 'find-file-not-found-hooks 'ff/start-file))
1919
1920 (when (>= emacs-major-version 24)
1921   (define-obsolete-function-alias 'make-local-hook 'ignore "21.1")
1922   (setq send-mail-function 'sendmail-send-it) ;; emacs 24.x stuff
1923
1924   (custom-set-faces
1925    '(diff-added ((default (:background "gray90" :foreground "green4" :weight bold))))
1926    '(diff-removed ((default (:background "gray90" :foreground "red2" :weight bold))))
1927    '(diff-changed ((default (:background "gray90" :foreground "blue" :weight bold))))
1928    )
1929   )
1930
1931 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1932
1933 (define-key global-map [f8] 'ff-find-other-file)
1934 (define-key global-map [(shift f8)] (lambda () (interactive) (ff-find-other-file t)))
1935
1936 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1937 ;; Antiword, htmlize and boxquote
1938 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1939
1940 (autoload 'no-word "no-word")
1941 (add-to-list 'auto-mode-alist '("\\.doc\\'" . no-word))
1942 ;; (add-to-list 'auto-mode-alist '("\\.DOC\\'" . no-word))
1943
1944 (autoload 'htmlize-buffer "htmlize" nil t)
1945
1946 (setq boxquote-top-and-tail "------------------")
1947 (autoload 'boxquote-region "boxquote" nil t)
1948
1949 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1950 ;; The compilation hacks
1951 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1952
1953 ;; If we enter c++ mode and there is no makefile around, we create a
1954 ;; make command on the fly for the specific object file
1955
1956 (add-hook 'c++-mode-hook
1957           (lambda ()
1958             (unless (or (file-exists-p "makefile") (file-exists-p "Makefile"))
1959               (set (make-local-variable 'compile-command)
1960                    (concat
1961                     "make -k "
1962                     (file-name-sans-extension
1963                      (file-name-nondirectory buffer-file-name)))))))
1964
1965 ;; <f1> runs the compilation according to the compile-command (and
1966 ;; thus does not ask any confirmation), shows the compilation buffer
1967 ;; during compilation and delete all windows showing the compilation
1968 ;; buffer if the compilation ends with no error
1969
1970 ;; <shift-f1> asks for a compilation command and runs the compilation
1971 ;; but does not restore the window configuration (i.e. the compilation
1972 ;; buffer's window will still be visible, as usual)
1973
1974 ;; <f2> goes to the next compilation error (as C-x ` does on the
1975 ;; standard configuration)
1976
1977 (defun ff/restore-windows-if-no-error (buffer msg)
1978   "Delete the windows showing the compilation buffer if msg
1979   matches \"^finished\"."
1980
1981   (when (string-match "^finished" msg)
1982     ;;     (delete-windows-on buffer)
1983     (if (boundp 'ff/window-configuration-before-compilation)
1984         (set-window-configuration ff/window-configuration-before-compilation))
1985     )
1986   )
1987
1988 (add-to-list 'compilation-finish-functions 'ff/restore-windows-if-no-error)
1989
1990 (defun ff/fast-compile ()
1991   "Compiles without asking anything."
1992   (interactive)
1993   (let ((compilation-read-command nil))
1994     (setq ff/window-configuration-before-compilation (current-window-configuration))
1995     (compile compile-command)))
1996
1997 (setq compilation-read-command t
1998       compile-command "make -j -k"
1999       compile-history '("make clean" "make DEBUG=yes -j -k" "make -j -k")
2000       )
2001
2002 (defun ff/universal-compile () (interactive)
2003        (funcall (or (cdr (assoc major-mode
2004                                 '(
2005                                   (latex-mode . tex-file)
2006                                   (html-mode . browse-url-of-buffer)
2007                                   ;; Here you can add other mode -> compile command
2008                                   )))
2009                     'ff/fast-compile         ;; And this is the failsafe
2010                     )))
2011
2012 (define-key global-map [f1] 'ff/universal-compile)
2013 (define-key global-map [(shift f1)] 'compile)
2014 (define-key global-map [f2] 'next-error)
2015
2016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2017 ;; Related to mail
2018 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2019
2020 ;; (when (ff/load-or-alert "flyspell-timer" t)
2021 ;;   (add-hook 'flyspell-mode-hook 'flyspell-timer-ensure-idle-timer))
2022
2023 (defun ff/start-flyspell () (interactive)
2024        (ff/configure-faces
2025         '(
2026           ;; (flyspell-incorrect :background "#ff0000" :foreground "black")
2027           ;; (flyspell-duplicate :background "#ff9000" :foreground "black")
2028           (flyspell-incorrect :foreground "#ff0000" :weight 'bold)
2029           (flyspell-duplicate :foreground "#ff9000" :weight 'bold)
2030           ))
2031        ;; (flyspell-buffer)
2032        )
2033
2034 (add-hook 'flyspell-mode-hook 'ff/start-flyspell)
2035
2036 (defun ff/pick-dictionnary () (interactive)
2037        (when (and (boundp 'flyspell-mode) flyspell-mode)
2038          (if (and current-input-method (string-match "latin" current-input-method))
2039              (ispell-change-dictionary "francais")
2040            (ispell-change-dictionary "american"))
2041          ;;     (flyspell-buffer)
2042          )
2043        )
2044
2045 (defadvice toggle-input-method (after ff/switch-dictionnary nil activate)
2046   (ff/pick-dictionnary))
2047
2048 ;; (add-hook 'message-mode-hook 'auto-fill-mode)
2049 ;; (add-hook 'message-mode-hook 'flyspell-mode)
2050
2051 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2052 ;; Delete all windows which are in the same "column", which means
2053 ;; whose xmin and xmax are bounded by the xmin and xmax of the
2054 ;; currently selected column
2055 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2056
2057 ;; This is from emacs23 ! better than my old ff/delete-other-windows-in-column
2058
2059 (unless (fboundp 'delete-other-windows-vertically)
2060
2061   (defun delete-other-windows-vertically (&optional window)
2062     "Delete the windows in the same column with WINDOW, but not WINDOW itself.
2063 This may be a useful alternative binding for \\[delete-other-windows]
2064  if you often split windows horizontally."
2065     (interactive)
2066     (let* ((window (or window (selected-window)))
2067            (edges (window-edges window))
2068            (w window) delenda)
2069       (while (not (eq (setq w (next-window w 1)) window))
2070         (let ((e (window-edges w)))
2071           (when (and (= (car e) (car edges))
2072                      (= (caddr e) (caddr edges)))
2073             (push w delenda))))
2074       (mapc 'delete-window delenda)))
2075   )
2076
2077 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2078 ;; Misc things
2079 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2080
2081 ;; Entropy is cool
2082
2083 (defun ff/entropy (l)
2084   (apply '+
2085          (mapcar
2086           (lambda (x)
2087             (if (= x 0.0) 0.0
2088               (* (- x) (/ (log x) (log 2)))))
2089           l)
2090          )
2091   )
2092
2093 ;; Usefull to deal with results in latex files
2094
2095 (defun ff/round-floats-in-region () (interactive)
2096        (save-restriction
2097          (condition-case nil
2098              (narrow-to-region (region-beginning) (region-end))
2099            (error (thing-at-point 'word)))
2100          (save-excursion
2101            (goto-char (point-min))
2102            (while (re-search-forward "[0-9\.]+" nil t)
2103              (let ((value (string-to-number (buffer-substring (match-beginning 0) (match-end 0)))))
2104                (delete-region (match-beginning 0) (match-end 0))
2105                (insert (format "%0.2f" value)))))))
2106
2107 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2108 ;; Keymaping
2109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2110
2111 (load "info" nil t)
2112
2113 (define-key global-map [(shift iso-lefttab)] 'ispell-complete-word)
2114 ;; shift-tab going backward is kind of standard
2115 (define-key Info-mode-map [(shift iso-lefttab)] 'Info-prev-reference)
2116
2117 ;; (define-key global-map [(control x) (control a)] 'auto-fill-mode)
2118
2119 ;; Put back my keys, you thief!
2120 (define-key global-map [(home)] 'beginning-of-buffer)
2121 (define-key global-map [(end)] 'end-of-buffer)
2122 ;; (define-key global-map [(insertchar)] 'overwrite-mode)
2123 (define-key global-map [(delete)] 'delete-char)
2124
2125 ;; Cool shortcuts to move to the end / beginning of block keen
2126 (define-key global-map [(control right)] 'forward-sexp)
2127 (define-key global-map [(control left)] 'backward-sexp)
2128
2129 ;; Wheel mouse moves up and down 2 lines (and DO NOT BEEP when we are
2130 ;; out of the buffer)
2131
2132 (define-key global-map [mouse-4]
2133   (lambda () (interactive) (condition-case nil (scroll-down 2) (error nil))))
2134 (define-key global-map [mouse-5]
2135   (lambda () (interactive) (condition-case nil (scroll-up 2) (error nil))))
2136
2137 ;; with shift it goes faster
2138 (define-key global-map [(shift mouse-4)]
2139   (lambda () (interactive) (condition-case nil (scroll-down 50) (error nil))))
2140 (define-key global-map [(shift mouse-5)]
2141   (lambda () (interactive) (condition-case nil (scroll-up 50) (error nil))))
2142
2143 ;; Meta-? shows the properties of the character at point
2144 (define-key global-map [(meta ??)]
2145   (lambda () (interactive)
2146     (message (prin1-to-string (text-properties-at (point))))))
2147
2148 ;; Compiles the latex file in the current buffer
2149
2150 (setq tex-start-commands "\\input")
2151 (define-key global-map [f3] 'tex-file)
2152 (define-key global-map [(shift f3)] 'tex-bibtex-file)
2153
2154 ;; To run xdvi on the dvi associated to the .tex in the current
2155 ;; buffer, and to edit the .fig or bitmap image used to generate the
2156 ;; .eps at point
2157
2158 (define-key global-map [f4] 'ff/run-viewer)
2159
2160 ;; Closes the current \begin{}
2161
2162 (when (ff/load-or-alert "longlines")
2163
2164   (setq longlines-show-hard-newlines t
2165         longlines-auto-wrap t
2166         ;; longlines-show-effect #("|\n" 0 2 (face escape-glyph))
2167         ;; longlines-show-effect #("∴\n" 0 2 (face escape-glyph))
2168         longlines-show-effect #("•\n" 0 2 (face escape-glyph))
2169         ;; longlines-show-effect #("↵\n" 0 2 (face escape-glyph))
2170         )
2171
2172   ;; (defun ff/auto-longlines ()
2173   ;; (when (save-excursion
2174   ;; (goto-char (point-min))
2175   ;; (re-search-forward "^.\\{81,\\}$" nil t))
2176   ;; (longlines-mode)
2177   ;; (message "Switched on the lonlines mode automatically")
2178   ;; ))
2179
2180   ;; (add-hook 'latex-mode-hook 'ff/auto-longlines)
2181
2182   )
2183
2184 ;; Meta-/ remaped (completion)
2185
2186 (define-key global-map [(shift right)] 'dabbrev-expand)
2187 (define-key global-map [(meta =)] 'dabbrev-expand)
2188
2189 ;; Change the current window.
2190
2191 (defun ff/next-same-frame-window () (interactive)
2192        (select-window (next-window (selected-window)
2193                                    (> (minibuffer-depth) 0)
2194                                    nil)))
2195
2196 (defun ff/previous-same-frame-window () (interactive)
2197        (select-window (previous-window (selected-window)
2198                                        (> (minibuffer-depth) 0)
2199                                        nil)))
2200
2201 (define-key global-map [(shift prior)] 'ff/next-same-frame-window)
2202 (define-key global-map [(shift next)] 'ff/previous-same-frame-window)
2203
2204 (define-key global-map [(control })] 'enlarge-window-horizontally)
2205 (define-key global-map [(control {)] 'shrink-window-horizontally)
2206 (define-key global-map [(control \")] 'enlarge-window)
2207 (define-key global-map [(control :)] 'shrink-window)
2208
2209 ;; (define-key global-map [(control shift prior)] 'next-multiframe-window)
2210 ;; (define-key global-map [(control shift next)] 'previous-multiframe-window)
2211
2212 ;; I have two screens sometime!
2213
2214 (define-key global-map [(meta next)] 'other-frame)
2215 (define-key global-map [(meta prior)] (lambda () (interactive) (other-frame -1)))
2216
2217 (define-key global-map [(shift home)] 'delete-other-windows-vertically)
2218
2219 ;; (define-key global-map [(control +)] 'enlarge-window)
2220 ;; (define-key global-map [(control -)] 'shrink-window)
2221
2222 ;; Goes to next/previous buffer
2223
2224 (define-key global-map [(control prior)] 'ff/next-buffer)
2225 (define-key global-map [(control next)] 'ff/prev-buffer)
2226
2227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2228 ;; If M-. on a symbol, show where it is defined in another window
2229 ;; without giving focus, cycle if repeated.
2230 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2231
2232 (when (ff/load-or-alert "etags")
2233
2234   (defun ff/find-tag-nofocus () (interactive)
2235          "Show in another window the definition of the current tag"
2236          (let ((tag (find-tag-default)))
2237            (display-buffer (find-tag-noselect tag (string= tag last-tag)))
2238            (message "Tag %s" tag)
2239            )
2240          )
2241
2242   (define-key global-map [(meta .)] 'ff/find-tag-nofocus)
2243   )
2244
2245 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2246 ;; Destroys the current buffer and its window if it's not the only one
2247 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2248
2249 (defcustom ff/kill-this-buffer-and-delete-window-exceptions ""
2250   "*Regexp matching the buffer names which have to be kept when using
2251 `ff/kill-this-buffer-and-delete-window'.")
2252
2253 (defun ff/kill-this-buffer-and-delete-window (universal)
2254   "Unless its name matches
2255 `ff/kill-this-buffer-and-delete-window-exceptions', kills the
2256 current buffer and deletes the current window if it's not the
2257 only one in the frame. If the buffer has to be kept, go to the
2258 next one. With universal argument, kill all killable buffers."
2259   (interactive "P")
2260   (if universal
2261       (let ((nb-killed 0))
2262         (mapc (lambda (x)
2263                 (unless (string-match ff/kill-this-buffer-and-delete-window-exceptions
2264                                       (buffer-name x))
2265                   (kill-buffer x)
2266                   (setq nb-killed (1+ nb-killed))
2267                   ))
2268               (buffer-list))
2269         (message "Killed %d buffer%s" nb-killed (if (> nb-killed 1) "s" "")))
2270     (if (string-match ff/kill-this-buffer-and-delete-window-exceptions (buffer-name))
2271         (ff/next-buffer)
2272       (kill-this-buffer)))
2273   ;; (unless (one-window-p t) (delete-window))
2274   )
2275
2276 (define-key global-map [(control backspace)] 'ff/kill-this-buffer-and-delete-window)
2277 ;; (define-key calc-mode-map [(control backspace)] 'calc-quit)
2278
2279
2280 (setq ff/kill-this-buffer-and-delete-window-exceptions
2281       "^ \\|\\*Messages\\*\\|\\*scratch\\*\\|\\*Group\\*\\|\\*-jabber-\\*\\|\\*-jabber-process-\\*\\|\\*media\\*")
2282
2283 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2284 ;; Misc stuff
2285 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2286
2287 (defun ff/elisp-debug-on ()
2288   "Switches `debug-on-error' and `debug-on-quit'."
2289   (interactive)
2290   (if debug-on-error
2291       (setq debug-on-error nil
2292             debug-on-quit nil)
2293     (setq debug-on-error t
2294           debug-on-quit t))
2295   (if debug-on-error
2296       (message "elisp debug on")
2297     (message "elisp debug off")))
2298
2299 (defun ff/create-dummy-buffer (&optional universal) (interactive "P")
2300        (find-file (concat "/tmp/" (ff/non-existing-filename "/tmp/" "dummy" "")))
2301        (text-mode)
2302        (if universal (ff/insert-url (current-kill 0)))
2303        (message "New dummy text-mode buffer"))
2304
2305 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2306 ;; Recentf to keep a list of recently visited files. I use it
2307 ;; exclusively with my selector.el
2308 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2309
2310 (load "recentf")
2311
2312 ;; If we just check for file-symlink-p, everytime we start emacs it
2313 ;; will check all the remote files listed in recentf-list, so we check
2314 ;; that they are not remote first
2315 (defun ff/file-not-remote-but-symlink (filename)
2316   (and (not (file-remote-p filename)) (file-symlink-p filename)))
2317
2318 (setq recentf-exclude (append recentf-exclude
2319                               '(
2320                                 ff/file-not-remote-but-symlink
2321                                 "enotes$" "secure-notes$" "media-playlists$"
2322                                 "bbdb$"
2323                                 "svn-commit.tmp$" ".git/COMMIT_EDITMSG$"
2324                                 "\.bbl$" "\.aux$" "\.toc$"
2325                                 ))
2326       recentf-max-saved-items 1000
2327       recentf-save-file (concat ff/emacs-dir "/recentf")
2328       )
2329
2330 (when (boundp 'recentf-keep) (add-to-list 'recentf-keep 'file-remote-p))
2331
2332 (recentf-mode 1)
2333
2334 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2335 ;; My front-end to mplayer
2336 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2337
2338 ;; (ff/compile-when-needed "media/mplayer")
2339 ;; (ff/compile-when-needed "media")
2340
2341 (when (ff/load-or-alert "media")
2342
2343   (unless window-system
2344     (ff/configure-faces
2345      '(
2346        (media/mode-string-face
2347         :foreground "blue4" :weight 'bold)
2348
2349        (media/current-tune-face
2350         :foreground "black" :background "yellow" :weight 'normal)
2351
2352        (media/instant-highlight-face
2353         :foreground "black" :background "orange" :weight 'normal)
2354        ))
2355     )
2356
2357   (define-key global-map [(meta \\)] 'media)
2358
2359   (setq media/expert t
2360         media/add-current-song-to-interrupted-when-killing t
2361         media/duration-to-history 30
2362         media/history-size 1000
2363         media/playlist-file (concat ff/emacs-dir "/media-playlists")
2364         media/mplayer/args '(
2365                              "-framedrop"
2366                              "-zoom"
2367                              "-cache" "512"
2368                              "-subfont-osd-scale" "3"
2369                              ;; "-stop-xscreensaver"
2370                              ;; "-osdlevel" "3"
2371                              )
2372         media/mplayer/timing-request-period 1.0
2373         )
2374   )
2375
2376 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2377 ;; A dynamic search
2378 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2379
2380 ;; selector.el is one of my own scripts, check my web page
2381
2382 (when (ff/load-or-alert "selector" t)
2383   ;; (define-key global-map [(shift return)] 'selector/quick-move-in-buffer)
2384   (define-key global-map [(control x) (control b)] 'selector/switch-buffer)
2385
2386   (defun ff/visit-debpkg-file (&optional regexp)
2387     "This function lists all the files found with dpkg -S and
2388 proposes to visit them."
2389     (interactive "sPattern: ")
2390
2391     (selector/select
2392
2393      (mapcar
2394       (lambda (s)
2395         (cons (selector/filename-to-string s) s))
2396       (split-string
2397        (shell-command-to-string (concat "dpkg -S " regexp " | awk '{print $2}'"))))
2398
2399      'selector/find-file
2400      "*selector find-file*"
2401      ))
2402   )
2403
2404 (add-hook 'selector/mode-hook (lambda () (setq truncate-lines t)))
2405
2406 (defun ff/selector-insert-record-callback (r)
2407   (bbdb-display-records (list r))
2408   ;; Weird things will happen if you kill the buffer from which you
2409   ;; invoked ff/selector-mail-from-bbdb
2410   (insert (car (elt r 6)))
2411   )
2412
2413 (defun ff/selector-compose-mail-callback (r)
2414   (vm-compose-mail (car (elt r 6)))
2415   )
2416
2417 (defun ff/selector-mail-from-bbdb () (interactive)
2418        (selector/select
2419         (mapcar
2420          (lambda (r) (cons (concat (elt r 0)
2421                                    " "
2422                                    (elt r 1)
2423                                    " ("
2424                                    (car (elt r 6))
2425                                    ")")
2426                            r))
2427          (bbdb-records))
2428         (if (string= mode-name "Mail")
2429             'ff/selector-insert-record-callback
2430           'ff/selector-compose-mail-callback)
2431         "*bbdb-search*"
2432         )
2433        )
2434
2435 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2436 ;; My script to automatically count the number of words and characters
2437 ;; between two markers
2438
2439 (ff/load-or-alert "text-counters.el")
2440
2441 ;; Display them in the modeline when in text-mode
2442
2443 (add-hook 'text-mode-hook 'tc/add-text-counters-in-modeline)
2444
2445 ;; (add-hook 'text-mode-hook
2446 ;; (lambda ()
2447 ;; (setq comment-start " > ")))
2448
2449 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2450 ;; A function to remove temporary alarm windows
2451 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2452
2453 (defcustom ff/annoying-windows-regexp
2454   "\\*Messages\\*\\|\\*compilation\\*\\|\\*tex-shell\\*\\|\\*Help\\*\\|\\*info\\*\\|\\*Apropos\\*\\|\\*BBDB\\*\\|\\*.*-diff\\*"
2455   "The regexp matching the windows to be deleted by `ff/delete-annoying-windows'"
2456   )
2457
2458 (defun ff/delete-annoying-windows ()
2459   "Close all the windows showing buffers whose names match
2460 `ff/annoying-windows-regexp'."
2461   (interactive)
2462   (when ff/annoying-windows-regexp
2463     (mapc (lambda (w)
2464             (when (and (not (one-window-p w))
2465                        (string-match ff/annoying-windows-regexp
2466                                      (buffer-name (window-buffer w))))
2467               (delete-window w)))
2468           (window-list)
2469           )
2470     (message "Removed annoying windows")
2471     )
2472   )
2473
2474 (setq ff/annoying-windows-regexp
2475       (concat ff/annoying-windows-regexp
2476               "\\|\\*unspooled mails\\*\\|\\*enotes alarms\\*\\|\\*system info\\*"))
2477
2478 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2479 ;; Some handy functions
2480 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2481
2482 (defun ff/twin-horizontal-current-buffer () (interactive)
2483        (delete-other-windows)
2484        (split-window-horizontally)
2485        (balance-windows)
2486        )
2487
2488 (defun ff/twin-vertical-current-buffer () (interactive)
2489        (delete-other-windows)
2490        (split-window-vertically)
2491        (balance-windows)
2492        )
2493
2494 (defun ff/flyspell-mode (arg) (interactive "p")
2495        (if flyspell-mode (flyspell-mode -1)
2496          (flyspell-mode 1)
2497          (flyspell-buffer))
2498        )
2499
2500 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2501 ;; The fridge!
2502 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2503
2504 (defun ff/move-region-to-fridge () (interactive)
2505        "Cut the current region, paste it in a file called ./fridge
2506 with a time tag, and save this file"
2507        (unless (use-region-p) (error "No region selected"))
2508        (let ((bn (file-name-nondirectory (buffer-file-name))))
2509          (kill-region (region-beginning) (region-end))
2510          (with-current-buffer (find-file-noselect "fridge")
2511            (goto-char (point-max))
2512            (insert "\n")
2513            (insert "######################################################################\n")
2514            (insert "\n"
2515                    (format-time-string "%Y %b %d %H:%M:%S" (current-time))
2516                    " (from "
2517                    bn
2518                    ")\n\n")
2519            (yank)
2520            (save-buffer)
2521            (message "Region moved to fridge")
2522            )
2523          )
2524        )
2525
2526 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2527 ;; My own keymap mapped to C-`
2528 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2529
2530 (setq ff/map (make-sparse-keymap))
2531 (define-key global-map [(control \`)] ff/map)
2532
2533 (unless window-system
2534   ;; (define-key global-map [(control @)] ff/map)
2535   (define-key global-map [(meta O) \`] ff/map)
2536   )
2537
2538 (define-key esc-map "`" ff/map)
2539
2540 (defun ff/git-status (&optional dir) (interactive)
2541        (if (buffer-file-name)
2542            (git-status (file-name-directory (buffer-file-name)))
2543          (error "No file attached to this buffer")))
2544
2545 (defun ff/insert-date (&optional universal) (interactive "P")
2546        ;; (insert (format-time-string "\n * %Y %b %d %H:%M:%S\n\n" (current-time)))
2547        ;; (insert (format-time-string "%Y %b %d %H:%M:%S" (current-time)))
2548        ;; (insert (format-time-string "%d.%m.%y" (current-time)))
2549        (if universal
2550            (insert (format-time-string "%d.%m.%Y %H:%M:%S" (current-time)))
2551          (insert (format-time-string "%d.%m.%Y" (current-time))))
2552        )
2553
2554 (define-key ff/map [(control g)] 'ff/git-status)
2555 (define-key ff/map [(control w)] 'server-edit)
2556 (define-key ff/map [(control d)] 'ff/elisp-debug-on)
2557 ;; (define-key ff/map "d" 'diary)
2558 (define-key ff/map "d" 'ff/insert-date)
2559 (define-key ff/map [(control \`)] 'ff/bash-new-buffer)
2560 (define-key ff/map [(control n)] 'enotes/show-all-notes)
2561 (define-key ff/map [(control s)] 'ff/secure-note-add)
2562 (define-key ff/map [(control t)] 'ff/start-test-code)
2563 (define-key ff/map [(control q)] 'ff/create-dummy-buffer)
2564 (define-key ff/map [(control a)] 'auto-fill-mode)
2565 (define-key ff/map [(control i)] 'ff/system-info)
2566 (define-key ff/map "w" 'ff/word-occurences)
2567 (define-key ff/map [(control c)] 'calendar)
2568 ;; (define-key ff/map [(control c)] (lambda () (interactive) (save-excursion (calendar))))
2569 (define-key ff/map [(control l)] 'goto-line)
2570 (define-key ff/map "l" 'longlines-mode)
2571 (define-key ff/map [(control o)] 'selector/quick-pick-recent)
2572 (define-key ff/map "s" 'selector/quick-move-in-buffer)
2573 (define-key ff/map "S" 'selector/search-sentence)
2574 (define-key ff/map "t" (lambda () (interactive) (find-file "~/private/TODO.txt")))
2575 (define-key ff/map "h" 'ff/tidy-html)
2576 (define-key ff/map "c" 'ff/count-char)
2577 (define-key ff/map [(control p)] 'ff/print-to-file)
2578 (define-key ff/map "P" 'ff/print-to-printer)
2579 (define-key ff/map [(control b)] 'bbdb)
2580 (define-key ff/map "m" 'ff/selector-mail-from-bbdb)
2581 (define-key ff/map [(control m)] 'woman)
2582 (define-key ff/map "b" 'bookmark-jump)
2583 (define-key ff/map [(control =)] 'calc)
2584 (define-key ff/map [(control shift b)]
2585   (lambda () (interactive)
2586     (bookmark-set)
2587     (bookmark-save)))
2588 (define-key ff/map "f" 'ff/move-region-to-fridge)
2589 (define-key ff/map [(control f)] 'ff/flyspell-mode)
2590
2591 (define-key ff/map [?\C-0] 'ff/delete-annoying-windows)
2592 (define-key ff/map "1" 'delete-other-windows)
2593 (define-key ff/map [?\C-1] 'delete-other-windows)
2594 (define-key ff/map "2" 'ff/twin-vertical-current-buffer)
2595 (define-key ff/map [?\C-2] 'ff/twin-vertical-current-buffer)
2596 (define-key ff/map "3" 'ff/twin-horizontal-current-buffer)
2597 (define-key ff/map [?\C-3] 'ff/twin-horizontal-current-buffer)
2598
2599 (define-key ff/map " " 'delete-trailing-whitespace)
2600
2601 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2602 ;; Hacks so that all keys are functionnal in xterm and through ssh.
2603 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2604
2605 (unless window-system
2606
2607   ;; One day I will understand these clipboard business. Until then,
2608   ;; so that it works in xterm (yes), let's use xclip. This is a bit
2609   ;; ugly.
2610
2611   ;; (defun ff/yank-with-xclip (&optional arg)
2612   ;; "Paste the content of the X clipboard with the xclip
2613   ;; command. Without ARG converts some of the '\\uxxxx' characters."
2614   ;; (interactive "P")
2615   ;; (with-temp-buffer
2616   ;; (shell-command "xclip -o" t)
2617   ;; (unless arg
2618   ;; (mapc (lambda (x) (replace-string (concat "\\u" (car x)) (cdr x) nil (point-min) (point-max)))
2619   ;; '(("fffd" . "??")
2620   ;; ("2013" . "-")
2621   ;; ("2014" . "--")
2622   ;; ("2018" . "`")
2623   ;; ("2019" . "'")
2624   ;; ("201c" . "``")
2625   ;; ("201d" . "''")
2626   ;; ("2022" . "*")
2627   ;; ("2026" . "...")
2628   ;; ("20ac" . "EUR")
2629   ;; )))
2630   ;; (kill-ring-save (point-min) (point-max)))
2631
2632   ;; (yank))
2633
2634   ;; (define-key global-map [(meta y)] 'ff/yank-with-xclip)
2635
2636   ;;   (set-terminal-coding-system 'iso-latin-1)
2637   ;; (set-terminal-coding-system 'utf-8)
2638
2639   ;; I have in my .Xressource
2640
2641   ;; XTerm.VT100.translations: #override\n\
2642   ;;   <Btn4Down>,<Btn4Up>:scroll-back(2,line)\n\
2643   ;;   <Btn5Down>,<Btn5Up>:scroll-forw(2,line)\n\
2644   ;;   Ctrl<Btn4Down>,Ctrl<Btn4Up>:scroll-back(1,page)\n\
2645   ;;   Ctrl<Btn5Down>,Ctrl<Btn5Up>:scroll-forw(1,page)\n\
2646   ;;   Shift<Btn4Down>,Shift<Btn4Up>:scroll-back(1,halfpage)\n\
2647   ;;   Shift<Btn5Down>,Shift<Btn5Up>:scroll-forw(1,halfpage)\n\
2648   ;;   Alt<KeyPress>:insert-eight-bit()\n\
2649   ;;   !Shift<Key>BackSpace: string("\7f")\n\
2650   ;;   Ctrl<Key>BackSpace: string("\eOZ")\n\
2651   ;;   Shift<Key>Prior: string("\e[5;2~")\n\
2652   ;;   Shift<Key>Next: string("\e[6;2~")\n\
2653   ;;   Shift Ctrl<Key>]: string("\eO}")\n\
2654   ;;   Shift Ctrl<Key>[: string("\eO{")\n\
2655   ;;   Shift Ctrl<Key>/: string("\eO?")\n\
2656   ;;   Ctrl<Key>/: string("\eO/")\n\
2657   ;;   Shift Ctrl<Key>=: string("\eO+")\n\
2658   ;;   Ctrl<Key>=: string("\eO=")\n\
2659   ;;   Shift Ctrl<Key>;: string("\eO:")\n\
2660   ;;   Ctrl<Key>;: string("\eO;")\n\
2661   ;;   Shift Ctrl<Key>`: string("\eO~")\n\
2662   ;;   Ctrl<Key>`: string("\eO`")\n\
2663   ;;   Shift Ctrl<Key>': string("\eO\\\"")\n\
2664   ;;   Ctrl<Key>': string("\eO'")\n\
2665   ;;   Shift Ctrl<Key>.: string("\eO>")\n\
2666   ;;   Ctrl<Key>.: string("\eO.")\n\
2667   ;;   Shift Ctrl<Key>\\,: string("\eO<")\n\
2668   ;;   Ctrl<Key>\\,: string("\eO,")
2669
2670   (define-key function-key-map "\e[2~" [insert])
2671
2672   (define-key function-key-map "\e[Z" [S-iso-lefttab])
2673
2674   (define-key function-key-map "\e[1;2A" [S-up])
2675   (define-key function-key-map "\e[1;2B" [S-down])
2676   (define-key function-key-map "\e[1;2C" [S-right])
2677   (define-key function-key-map "\e[1;2D" [S-left])
2678   (define-key function-key-map "\e[1;2F" [S-end])
2679   (define-key function-key-map "\e[1;2H" [S-home])
2680
2681   (define-key function-key-map "\e[2;2~" [S-insert])
2682   (define-key function-key-map "\e[5;2~" [S-prior])
2683   (define-key function-key-map "\e[6;2~" [S-next])
2684
2685   (define-key function-key-map "\e[1;2P" [S-f1])
2686   (define-key function-key-map "\e[1;2Q" [S-f2])
2687   (define-key function-key-map "\e[1;2R" [S-f3])
2688   (define-key function-key-map "\e[1;2S" [S-f4])
2689   (define-key function-key-map "\e[15;2~" [S-f5])
2690   (define-key function-key-map "\e[17;2~" [S-f6])
2691   (define-key function-key-map "\e[18;2~" [S-f7])
2692   (define-key function-key-map "\e[19;2~" [S-f8])
2693   (define-key function-key-map "\e[20;2~" [S-f9])
2694   (define-key function-key-map "\e[21;2~" [S-f10])
2695
2696   (define-key function-key-map "\e[1;5A" [C-up])
2697   (define-key function-key-map "\e[1;5B" [C-down])
2698   (define-key function-key-map "\e[1;5C" [C-right])
2699   (define-key function-key-map "\e[1;5D" [C-left])
2700   (define-key function-key-map "\e[1;5F" [C-end])
2701   (define-key function-key-map "\e[1;5H" [C-home])
2702
2703   (define-key function-key-map "\e[2;5~" [C-insert])
2704   (define-key function-key-map "\e[5;5~" [C-prior])
2705   (define-key function-key-map "\e[6;5~" [C-next])
2706
2707   (define-key function-key-map "\e[1;9A" [M-up])
2708   (define-key function-key-map "\e[1;9B" [M-down])
2709   (define-key function-key-map "\e[1;9C" [M-right])
2710   (define-key function-key-map "\e[1;9D" [M-left])
2711   (define-key function-key-map "\e[1;9F" [M-end])
2712   (define-key function-key-map "\e[1;9H" [M-home])
2713
2714   (define-key function-key-map "\e[2;9~" [M-insert])
2715   (define-key function-key-map "\e[5;9~" [M-prior])
2716   (define-key function-key-map "\e[6;9~" [M-next])
2717
2718   ;; The following ones are not standard
2719
2720   (define-key function-key-map "\eO}" (kbd "C-}"))
2721   (define-key function-key-map "\eO{" (kbd "C-{"))
2722   (define-key function-key-map "\eO?" (kbd "C-?"))
2723   (define-key function-key-map "\eO/" (kbd "C-/"))
2724   (define-key function-key-map "\eO:" (kbd "C-:"))
2725   (define-key function-key-map "\eO;" (kbd "C-;"))
2726   (define-key function-key-map "\eO~" (kbd "C-~"))
2727   (define-key function-key-map "\eO`" (kbd "C-\`"))
2728   (define-key function-key-map "\eO\"" (kbd "C-\""))
2729   (define-key function-key-map "\eO|" (kbd "C-|"))
2730   (define-key function-key-map "\eO'" (kbd "C-'"))
2731   (define-key function-key-map "\eO>" (kbd "C->"))
2732   (define-key function-key-map "\eO." (kbd "C-."))
2733   (define-key function-key-map "\eO<" (kbd "C-<"))
2734   (define-key function-key-map "\eO," (kbd "C-,"))
2735   (define-key function-key-map "\eO-" (kbd "C--"))
2736   (define-key function-key-map "\eO=" (kbd "C-="))
2737   (define-key function-key-map "\eO+" (kbd "C-+"))
2738
2739   (define-key function-key-map "\eOZ" [C-backspace])
2740
2741   (define-key minibuffer-local-map "\10" 'previous-history-element)
2742   (define-key minibuffer-local-map "\ e" 'next-history-element)
2743
2744   ;; (define-key global-map [(alt prior)] 'ff/prev-buffer)
2745   ;; (define-key global-map [(alt next)] 'ff/next-buffer)
2746
2747   )
2748
2749 ;; I am fed up with Alt-Backspace in the minibuffer erasing the
2750 ;; content of the kill-ring
2751
2752 (defun ff/backward-delete-word (arg)
2753   "Delete characters forward until encountering the end of a word, but do not put them in the kill ring.
2754 With argument ARG, do this that many times."
2755   (interactive "p")
2756   (delete-region (point) (progn (forward-word (- arg)) (point))))
2757
2758 (define-key minibuffer-local-map
2759   [remap backward-kill-word] 'ff/backward-delete-word)
2760
2761 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2762 ;; Privacy
2763 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2764
2765 ;; Where to save the bookmarks and where is bbdb
2766
2767 (setq bookmark-default-file (concat ff/emacs-dir "/bmk")
2768       bbdb-file "~/private/bbdb"
2769       custom-file (concat ff/emacs-dir "/custom"))
2770
2771 ;; enotes.el is one of my own scripts, check my web page
2772
2773 (when (ff/load-or-alert "enotes" t)
2774   (setq enotes/file "~/private/enotes"
2775         enotes/show-help nil
2776         enotes/full-display nil
2777         enotes/default-time-fields "9:30")
2778
2779   (enotes/init)
2780   ;; (add-hook 'enotes/alarm-hook
2781   ;;  (lambda () (ff/play-sound-async "~/local/sounds/three_notes2.wav")))
2782   )
2783
2784 ;; (when (ff/load-or-alert "goto-last-change.el")
2785 ;; (define-key global-map [(control x) (control a)] 'goto-last-change))
2786
2787 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2788 ;; My private stuff (email adresses, mail filters, etc.)
2789 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2790
2791 (ff/load-or-alert "~/private/emacs.perso.el" t)
2792
2793 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2794 ;; emacs server
2795 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2796
2797 ;; Runs in server mode, so that emacsclient works
2798 (server-start)
2799
2800 (defun ff/raise-frame-and-give-focus ()
2801   (when window-system
2802     (raise-frame)
2803     (x-focus-frame (selected-frame))
2804     (set-mouse-pixel-position (selected-frame) 4 4)
2805     ))
2806
2807 ;; Raises the window when the server is invoked
2808
2809 (add-hook 'server-switch-hook 'ff/raise-frame-and-give-focus)