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