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