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