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