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