X-Git-Url: https://www.fleuret.org/cgi-bin/gitweb/gitweb.cgi?p=elisp.git;a=blobdiff_plain;f=emacs.el;h=5d30a6e40930bb702d8c9f3a73d2831bbe16bb14;hp=9e07d6008ef43887abeb7025eee2c524d92fb234;hb=HEAD;hpb=4a40307f81b8f89c1eba4138f934cfb189650e50 diff --git a/emacs.el b/emacs.el index 9e07d60..96874b0 100644 --- a/emacs.el +++ b/emacs.el @@ -18,14 +18,10 @@ ;; Contact for comments & bug reports ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Ugly hack because 23.2 is not installed properly in my Debian - -(when (and (>= emacs-major-version 23) - (>= emacs-minor-version 2)) - (add-to-list 'load-path "/usr/share/emacs/site-lisp/vm/") - (add-to-list 'load-path "/usr/share/emacs/site-lisp/bbdb/lisp/") - (add-to-list 'load-path "/usr/share/emacs/site-lisp/mailcrypt/") - ) +;; (defadvice display-warning (before ff/blah (type message &optional level buffer-name) activate) + ;; (message "--- BLAH %s ---" message) + ;; (backtrace) +;; ) ;; It's better to set the preferences in the .Xresources so that the ;; window is not first displayed with the wrong options @@ -40,6 +36,24 @@ ;; Xft.antialias: true ;; Xft.rgba: rgb +;;(set-frame-font "Inconsolata 14") + +;; (package-initialize) + +;; (set-default-font "Bitstream vera sans mono 12") +;; (set-default-font "Liberation Mono-13") +;; (set-default-font "DejaVu sans mono 15") +;; (set-default-font "Droid sans mono 13") +;; (set-default-font "Opensans 10") + +(when (fboundp 'horizontal-scroll-bar-mode) + (horizontal-scroll-bar-mode -1)) + +;; This is where I put most of my emacs-related files +(setq ff/emacs-dir "~/private/emacs") +(unless (file-exists-p ff/emacs-dir) + (mkdir ff/emacs-dir t)) + ;; Give the focus to the emacs window if we are under a windowing ;; system @@ -49,14 +63,17 @@ ;; Where I keep my own scripts -(add-to-list 'load-path "~/sources/gpl/elisp") -(add-to-list 'load-path "~/sources/elisp") +(add-to-list 'load-path "~/src/gpl/elisp") +(add-to-list 'load-path "~/src/elisp") +(add-to-list 'load-path "~/local/elisp") ;; No, I do not like menus (menu-bar-mode -1) ;; Nor fringes -(when (functionp 'fringe-mode) (fringe-mode '(0 . 0))) +;; (when (functionp 'fringe-mode) (fringe-mode '(0 . 0))) +;; (when (functionp 'fringe-mode) (fringe-mode '(0 . 1))) +(when (functionp 'fringe-mode) (fringe-mode 10)) ;; And I do not like scrollbar neither (when (functionp 'scroll-bar-mode) (scroll-bar-mode -1)) @@ -64,6 +81,10 @@ ;; Make all "yes or no" prompts be "y or n" instead (fset 'yes-or-no-p 'y-or-n-p) +;; The space bar acting as "yes" has been several times really +;; problematic. +(define-key query-replace-map (kbd "SPC") nil) + ;; Show the matching parenthesis and do it immediately, we are in a ;; hurry (setq show-paren-delay 0) @@ -72,17 +93,24 @@ ;; use colorization for all modes (global-font-lock-mode t) -(setq font-lock-maximum-decoration 2 +;; (load "auctex") + +(setq font-lock-maximum-decoration 3 ;;'((latex-mode . 2) (t . 2)) ) ;; Activate the dynamic completion of buffer names -(iswitchb-mode 1) +;; (iswitchb-mode 1) +;; (load "lcomplete") ;; Save the minibuffer history -(setq savehist-file "~/private/emacs/savehist") +(setq savehist-file (concat ff/emacs-dir "/savehist")) (when (functionp 'savehist-mode) (savehist-mode 1)) +;; And allow minibuffer recursion +(setq enable-recursive-minibuffers t) +(minibuffer-depth-indicate-mode 1) + ;; I do not like tooltips (when (functionp 'tooltip-mode) (tooltip-mode nil)) @@ -102,11 +130,16 @@ uses `load-path' to find it." (ff/compile-when-needed (concat name ".el")) (mapc (lambda (dir) (let* ((src (concat dir "/" name))) + ;; (message "Compiling " scr) ;;*********** (when (file-newer-than-file-p src (concat src "c")) - (if (let ((byte-compile-verbose nil)) - (condition-case nil - (byte-compile-file src) - (error nil))) + (if + ;; (let ((byte-compile-verbose nil)) + ;; (condition-case nil + ;; (byte-compile-file src) + ;; (error nil))) + + (byte-compile-file src) + (message (format "Compiled %s" src )) (message (format "Failed compilation of %s" src)))))) load-path))) @@ -133,8 +166,12 @@ load-warning buffer in case of failure." ;; make emacs use the clipboard so that copy/paste works for other ;; x-programs. I have no clue how all that clipboard thing works. + ;; (setq x-select-enable-clipboard t) ;; (setq interprogram-paste-function 'x-cut-buffer-or-selection-value) +;; (setq x-select-enable-primary t) +;; (setq x-select-enable-clipboard t) +;; (global-set-key "\C-y" 'clipboard-yank) (setq @@ -159,7 +196,7 @@ load-warning buffer in case of failure." next-error-highlight t ;; blink the screen instead of beeping - ;; visible-bell t + visible-bell t ;; take the CR when killing a line kill-whole-line t @@ -206,6 +243,13 @@ load-warning buffer in case of failure." epa-file-cache-passphrase-for-symmetric-encryption t ;; And I like ascii files epa-armor t + ;; This goes with in your ~/.gnupg/gpg-agent.conf: + ;; allow-emacs-pinentry + ;; allow-loopback-pinentry + epa-pinentry-mode 'loopback + + ;; tramp-default-method "ssh" + tramp-default-method "scp" ;; I have no problem with files having their own local variables enable-local-eval t @@ -216,8 +260,16 @@ load-warning buffer in case of failure." mc-use-default-recipients t ;; browse-url-new-window-flag t + + ;; I do not like compilation to automatically split the active window + ;; vertically, even when the said window is very wide + split-height-threshold 0 + split-width-threshold nil ) +(custom-set-variables + '(query-replace-from-to-separator nil)) + ;; The backups (setq @@ -231,10 +283,21 @@ load-warning buffer in case of failure." backup-by-copying-when-linked t ) +(setq tramp-backup-directory-alist backup-directory-alist) + +(setq user-emacs-directory "~/misc/emacs.d/") + +(setq + abbrev-file-name (concat user-emacs-directory "abbrev_defs") + server-auth-dir (concat user-emacs-directory "server/") + custom-theme-directory user-emacs-directory + ) + ;; Stop this crazy blinking cursor (blink-cursor-mode 0) -;; (setq blink-cursor-delay 0.25 +;; (setq blink-cursor-delay 0.05 +;; blink-cursor-blinks 0 ;; blink-cursor-interval 0.25) ;; (set-terminal-coding-system 'utf-8) @@ -262,8 +325,12 @@ load-warning buffer in case of failure." ;; This is the default coding system when toggle-input-method is ;; invoked (C-\) default-input-method "latin-1-prefix" + ;; do not put tabs when indenting indent-tabs-mode nil + ;; Stop indenting automatically, that's annoying + electric-indent-chars nil + ;; And yes, we have a fast display / connection / whatever baud-rate 524288 ;; baud-rate 10 @@ -282,15 +349,23 @@ load-warning buffer in case of failure." ;; What modes for what file extentions (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) +(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode)) + +(require 'org-table) + (add-to-list 'auto-mode-alist '("\\.txt\\'" . (lambda() (text-mode) (orgtbl-mode) - (auto-fill-mode) + ;; (auto-fill-mode) (flyspell-mode)))) (add-hook 'c++-mode-hook 'flyspell-prog-mode) +;; (add-hook 'lua-mode-hook 'flyspell-prog-mode) (add-hook 'log-edit-mode-hook 'flyspell-mode) +(add-hook 'markdown-mode-hook 'flyspell-mode) +(add-hook 'markdown-mode-hook 'auto-fill-mode) + ;; I am a power-user (put 'narrow-to-region 'disabled nil) @@ -333,15 +408,7 @@ load-warning buffer in case of failure." )) ;; "tool" bar? Are you kidding? -(when (boundp 'tool-bar-mode) (tool-bar-mode -1)) - -;; ;; If my own letter icon is here, use it and change its color -;; (when (file-exists-p "~/local/share/emacs/letter.xbm") -;; (setq-default display-time-mail-icon -;; (find-image -;; '((:type xbm -;; :file "~/local/share/emacs/letter.xbm" -;; :ascent center))))) +(when (fboundp 'tool-bar-mode) (tool-bar-mode -1)) ;; My funky setting of face colors. Basically, we switch to a sober ;; look and darken a bit the colors which need to (because of the @@ -357,16 +424,77 @@ load-warning buffer in case of failure." ;; Not the same in xterm (which is gray in my case) and in ;; X-window +(when window-system + + (ff/configure-faces + '( + ;; (escape-glyph :foreground "#c0c0c0" :weight 'bold) + (escape-glyph :foreground "green3" :weight 'bold) + (default :background "gray90" :foreground "black") + (cperl-array-face :background "gray90" :foreground "blue" :weight 'bold) + (cperl-hash-face :background "gray90" :foreground "purple" :weight 'bold) + (message-cited-text :foreground "red4") + (diff-mode :background "gray90" :weight 'bold) + (diff-added :background "gray90" :foreground "green4" :weight 'bold) + (diff-removed :background "gray90" :foreground "red2" :weight 'bold) + (diff-changed :background "gray90" :foreground "blue" :weight 'bold) + (diff-file-header :background "white" :foreground "black" + :weight 'bold) + (diff-header :background "white" :foreground "black") + (diff-hunk-header :background "white" :foreground "black") + (font-lock-builtin-face :foreground "deeppink3") + (font-lock-string-face :foreground "dark olive green") + (font-lock-variable-name-face :foreground "sienna") + ;; (font-lock-function-name-face :foreground "blue" :weight 'bold) + (font-lock-function-name-face :foreground "blue") + ;; (font-lock-comment-delimiter-face :foreground "dark violet") + ;; (font-lock-comment-face :foreground "dark violet") + (flyspell-incorrect :background "#ff0000" :foreground "black") + (flyspell-duplicate :background "#ff9000" :foreground "black") + (hl-line :background "white") + (sh-heredoc :foreground "black" :background "#fff0f0") + (sh-heredoc-face :foreground "black" :background "#fff0f0") + (header-line :background "gray65") + (highlight :background "white") + (message-cited-text-face :foreground "firebrick") + (isearch :background "yellow" :foreground "black") + (isearch-lazy-highlight-face' :background "yellow3" :foreground "black") + (region :background "#b8b8e0" :foreground "black") + ;; (region :background "plum" :foreground "black") + (show-paren-match-face :background "gold" :foreground "black") + (show-paren-mismatch-face :background "red" :foreground "black") + (trailing-whitespace :background "gray65") + (cursor :inverse-video t) + (enotes/list-title-face :foreground "blue" :weight 'bold) + (mode-line :background "#b0b0ff" :foreground "black" :box nil + :inverse-video nil) + (header-line :background "cornflowerblue" :foreground "black" :box nil + :inverse-video nil) + (mode-line-inactive :background "gray80" :foreground "black" :box nil + :inverse-video nil) + ;; (fringe :background "black" :foreground "gray90") + (fringe :background "gray80") + (ff/date-info-face :foreground "white") + (ff/battery-info-face :foreground "blue") + (ff/battery-info-alarm-face :foreground "red") + ;; (ff/mail-alarm-face :foreground "white" :background "red2") + ;; (alarm-vc-face :foreground "black" :background "yellow" :weight 'normal) + (gui-button-face :background "green" :foreground "black") + )) + ) + (unless window-system - ;; (xterm-mouse-mode 1) + ;; (xterm-mouse-mode 1) (ff/configure-faces '((italic :underline nil) (info-title-2 :foreground "green") + (font-lock-comment-delimiter-face :foreground "green") + (font-lock-comment-face :foreground "green") (cperl-array-face :background "gray90" :foreground "blue" :weight 'bold) (cperl-hash-face :background "gray90" :foreground "purple" :weight 'bold) - (diff-added-face :foreground "blue" :weight 'bold) - (diff-changed-face :foreground "green" :weight 'bold) - (diff-removed-face :foreground "red" :weight 'bold) + (diff-added :background "gray90" :foreground "green4" :weight 'bold) + (diff-removed :background "gray90" :foreground "red2" :weight 'bold) + (diff-changed :background "gray90" :foreground "blue" :weight 'bold) (diff-file-header-face :background "white" :foreground "black" :weight 'bold) (diff-header-face :background "white" :foreground "black") @@ -378,15 +506,15 @@ load-warning buffer in case of failure." (font-lock-string-face :foreground "green") (font-lock-variable-name-face :foreground "blue") (font-lock-constant-face :foreground "blue") - (font-lock-function-name-face :foreground "blue") (font-lock-preprocessor-face :foreground "green") (font-lock-function-name-face :foreground "cyan") - (flyspell-incorrect-face :foreground "red2") - (flyspell-duplicate-face :foreground "OrangeRed2") - (sh-heredoc :foreground "blue") - (sh-heredoc-face :foreground "blue") + (flyspell-incorrect :foreground "red2") + (flyspell-duplicate :foreground "OrangeRed2") + (hl-line :background "white") + (sh-heredoc :foreground "black" :background "#fff0f0") + (sh-heredoc-face :foreground "black" :background "#fff0f0") (font-lock-keyword-face :foreground "blue") - (highlight :background "darkseagreen3") + (highlight :background "white") (isearch :background "orange" :foreground "black") (isearch-lazy-highlight-face' :background "yellow" :foreground "black") ;; (display-time-mail-face :background "white") @@ -399,71 +527,18 @@ load-warning buffer in case of failure." :inverse-video nil) (mode-line-inactive :background "gray60" :foreground "black" :box nil :inverse-video nil) - (region :background "springgreen2") + (region :background "white" :foreground "black") (ff/date-info-face :foreground "white" :weight 'bold) - (ff/mail-alarm-face :foreground "red" :weight 'bold) + (ff/battery-info-face :foreground "black") + (ff/battery-info-alarm-face :foreground "red") + ;; (ff/mail-alarm-face :foreground "red" :weight 'bold) + (selector/selection :background "yellow") (gui-button-face :background "green" :foreground "white") (enotes/information-face :foreground "cyan") - )) - ) - -;; (list-colors-display (mapcar 'car color-name-rgb-alist)) - -;; (ff/configure-faces '((default :background "black" :foreground "gray80"))) -;; (ff/configure-faces '((default :background "gray80" :foreground "black"))) - -(when window-system - ;; (setq - ;; display-time-use-mail-icon t) - (ff/configure-faces - '( - (escape-glyph :foreground "#c0c0c0" :weight 'bold) - (default :background "gray90" :foreground "black") - (cperl-array-face :background "gray90" :foreground "blue" :weight 'bold) - (cperl-hash-face :background "gray90" :foreground "purple" :weight 'bold) - (message-cited-text :foreground "red4") - (diff-added :background "gray90" :foreground "green4" :weight 'bold) - (diff-removed :background "gray90" :foreground "red2" :weight 'bold) - (diff-changed :background "gray90" :foreground "blue") - (diff-file-header :background "white" :foreground "black" - :weight 'bold) - (diff-header :background "white" :foreground "black") - (diff-hunk-header :background "white" :foreground "black") - (font-lock-builtin-face :foreground "deeppink3") - (font-lock-string-face :foreground "dark olive green") - (font-lock-variable-name-face :foreground "sienna") - (font-lock-function-name-face :foreground "blue4" :weight 'bold) - ;; (font-lock-comment-delimiter-face :foreground "dark violet") - ;; (font-lock-comment-face :foreground "dark violet") - (flyspell-incorrect-face :foreground "red2") - (flyspell-duplicate-face :foreground "OrangeRed2") - (header-line :background "gray65") - (sh-heredoc :foreground "darkorange3") - (sh-heredoc-face :foreground "darkorange3") - (highlight :background "turquoise") - (message-cited-text-face :foreground "firebrick") - (isearch :background "yellow" :foreground "black") - (isearch-lazy-highlight-face' :background "yellow3" :foreground "black") - (region :background "light sky blue" :foreground "black") - ;; (region :background "plum" :foreground "black") - (show-paren-match-face :background "gold" :foreground "black") - (show-paren-mismatch-face :background "red" :foreground "black") - (trailing-whitespace :background "gray65") - (cursor :inverse-video t) - (enotes/list-title-face :foreground "blue" :weight 'bold) - (mode-line :background "#9090f0" :foreground "black" :box nil - :inverse-video nil) - (header-line :background "cornflowerblue" :foreground "black" :box nil - :inverse-video nil) - (mode-line-inactive :background "#606080" :foreground "black" :box nil - :inverse-video nil) - ;; (fringe :background "black" :foreground "gray90") - (fringe :background "gray65") - (tex-verbatim :family "courrier") - (ff/date-info-face :foreground "white" :weight 'bold) - (ff/mail-alarm-face :foreground "white" :background "red2") - ;; (alarm-vc-face :foreground "black" :background "yellow" :weight 'normal) + (file-name-shadow :foreground "black") + (shadow :foreground "black") + (warning :foreground "black" :background "red") )) ) @@ -475,6 +550,19 @@ load-warning buffer in case of failure." :inverse-video nil)) )) +;; Why should I have to do this? +(add-hook 'sh-mode-hook + (lambda () + (set-face-attribute 'sh-heredoc nil + :foreground "#604000" + :background "white" + :italic t) + (set-face-attribute 'sh-heredoc-face nil + :foreground "#604000" + :background "white" + :italic t) + )) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Move the window on the buffer without moving the cursor ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -509,6 +597,16 @@ load-warning buffer in case of failure." (define-key global-map [(meta up)] 'ff/scroll-down) (define-key global-map [(meta down)] 'ff/scroll-up) + +(define-key global-map [(meta shift up)] + (lambda () (interactive) (condition-case nil (scroll-down 10) (error nil)))) + +(define-key global-map [(meta shift down)] + (lambda () (interactive) (condition-case nil (scroll-up 10) (error nil)))) + +;; (define-key global-map [(meta shift up)] (lambda () (interactive) (ff/scroll-down 10))) +;; (define-key global-map [(meta shift down)] 'ff/scroll-up) + (define-key global-map [(meta p)] 'ff/scroll-down) (define-key global-map [(meta n)] 'ff/scroll-up) (define-key global-map [(meta right)] 'ff/scroll-left) @@ -521,17 +619,12 @@ load-warning buffer in case of failure." (define-key global-map [(control c) (control q)] 'ff/delete-trailing-whitespaces-and-indent) +(define-key global-map [(control x) (control o)] 'other-window) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Playing sounds ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; (defun ff/esd-sound (file) -;; "Plays a sound with the Enlighted sound daemon." -;; (interactive) -;; (process-kill-without-query (start-process-shell-command "esdplay" -;; nil -;; "esdplay" file))) - (defun ff/alsa-sound (file) "Plays a sound with ALSA." (interactive) @@ -569,34 +662,21 @@ load-warning buffer in case of failure." (define-key global-map [(shift down)] 'ff/comment-and-go-down) (define-key global-map [(shift up)] 'ff/uncomment-and-go-up) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Counting various entities in text ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun ff/count-char () - "Prints the number of characters between the first previous \"--\" -and the firt next \"--\"." +(defun ff/show-compilation-buffer-split-window () + "Split the window vertically and show the compilation buffer in the newly created right one" (interactive) - (let ((from (save-excursion (re-search-backward "^--$" nil t))) - (to (save-excursion (re-search-forward "^--$" nil t)))) - (if (and to from) (message "%d character(s)" (- to from 6)) - (error "Can not find the -- delimiters")))) - -(defun ff/count-words () - "Print number of words between the first previous \"--\" and the -firt next \"--\"." - (interactive) - (let ((from (save-excursion (re-search-backward "^--$" nil t))) - (to (save-excursion (re-search-forward "^--$" nil t)))) - (if (and to from) - (save-excursion - (goto-char from) - (let ((count 0)) - (while (< (point) to) - (re-search-forward "\\w+\\W+") - (setq count (1+ count))) - (message "%d word(s)" count))) - (error "Can not find the -- delimiters")))) + + (let ((b (get-buffer "*compilation*"))) + (if b (show-buffer (split-window-right) b) + (error "Cannot find a compilation buffer")) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Counting various entities in text +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ff/word-occurences () "Display in a new buffer the list of words sorted by number of @@ -655,11 +735,11 @@ occurrences " ;; Printing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(require 'ps-print) +(load "ps-print") (setq ps-print-color-p nil - ;; ps-paper-type 'letter - ps-paper-type 'a4 + ps-paper-type 'letter + ;; ps-paper-type 'a4 ;; ps-top-margin (* 1.75 56.692) ;; ps-left-margin 56.692 ;; ps-bottom-margin 56.692 @@ -671,7 +751,8 @@ occurrences " ps-header-line-pad 0.3 ps-header-font-family 'Courier ps-header-title-font-size '(8.5 . 10) - ps-header-font-size '(6 . 7) + ;; ps-header-font-size '(6 . 7) + ps-header-font-size '(10 . 12) ps-font-size '(7 . 8) ) @@ -757,165 +838,164 @@ printer." ;; Dealing with the laptop battery ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defcustom ff/battery-file "/proc/acpi/battery/BAT0" +(defcustom ff/battery-dirs '("/sys/class/power_supply/BAT0") "*Where to gather the battery information") -(defcustom ff/thermal-file "/proc/acpi/thermal_zone/THM1/" +(defcustom ff/temperature-files '("/sys/class/thermal/thermal_zone0/temp" + "/sys/class/thermal/thermal_zone1/temp" + "/sys/class/thermal/thermal_zone2/temp" + "/sys/class/thermal/thermal_zone3/temp" + "/sys/class/thermal/thermal_zone4/temp" + "/sys/class/thermal/thermal_zone5/temp") "*Where to gather the thermal information") -(defun ff/battery-info (path) - - (let ((state nil) - (full nil) - (charge nil) - (rate nil)) - - (with-temp-buffer - (insert-file-contents-literally (concat path "/state")) - (while (re-search-forward "^\\([a-z ]*\\): *\\(.*\\)$" nil t) - (let ((field (match-string 1)) - (value (match-string 2))) - - (cond ((string= field "charging state") - (cond ((string= value "charged") (setq state 'charged)) - ((string= value "charging") (setq state 'charging)) - ((string= value "discharging")(setq state 'discharging)) - (t (setq state 'unknown)))) - - ((string= field "remaining capacity") - (setq charge (string-to-number value))) - - ((string= field "present rate") - (setq rate (string-to-number value))))))) - - (with-temp-buffer - (insert-file-contents-literally (concat path "/info")) - (while (re-search-forward "^\\([a-z ]*\\): *\\(.*\\)$" nil t) - (let ((field (match-string 1)) - (value (match-string 2))) - - (cond ((string= field "last full capacity") - (setq full (string-to-number value))))))) - - (list state full charge rate))) - -(defun ff/thermal-info (path) - (let ((temperature nil)) - (with-temp-buffer - (insert-file-contents-literally (concat path "/temperature")) - (while (re-search-forward "^\\([a-z ]*\\): *\\(.*\\)$" nil t) - (let ((field (match-string 1)) - (value (match-string 2))) - - (cond ((string= field "temperature") - (setq temperature (string-to-number value))))))) +(defun ff/file-first-line (file) + (with-temp-buffer + (insert-file-contents-literally file) + (buffer-substring (point-at-bol) (point-at-eol)))) + +(defun ff/battery-discharging (l) + (and l (or (string= (ff/file-first-line (concat (car l) "/status")) "Discharging") + (ff/battery-discharging (cdr l))))) + +;; If there is one "Discharging" among the states of all the +;; batteries, the global state is 'discharging. Otherwise, if there is +;; a "Charging", the state is 'charging. If none is true, it is +;; 'unknown +(defun ff/battery-state (l) + (if l + (let ((u (ff/file-first-line (concat (car l) "/status")))) + (if (string= u "Discharging") 'discharging + (let ((s (ff/battery-state (cdr l)))) + (if (eq s 'discharging) 'discharging + (if (or (eq s 'charging) (string= u "Charging")) + 'charging + 'unknown)) + ) + ) + ) + 'unknown)) - (list temperature))) +(defun ff/sum-values-from-files (list-files prefix) + (apply '+ + (mapcar + (lambda (f) + (condition-case nil + (string-to-number (ff/file-first-line (format "%s/%s" f prefix))) + (error 0)) + ) + list-files))) -(defun ff/laptop-info-string () (interactive) +(defun ff/battery-percent () (condition-case nil - (let ((info (ff/battery-info ff/battery-file)) - (temperature (car (ff/thermal-info ff/thermal-file)))) - - (concat + (/ (* 100 (ff/sum-values-from-files ff/battery-dirs "energy_now")) + (ff/sum-values-from-files ff/battery-dirs "energy_full")) + (error -1)) + ) - ;; The temperature +(defun ff/temp-info-string () (interactive) + (condition-case nil + ;; The temperature + + (let ((temp (/ + (apply 'max (mapcar + (lambda (f) (string-to-number (ff/file-first-line f))) + ff/temperature-files)) + 1000))) + + (if (> temp 50) + (let ((s (format "%dC " temp))) + (if (> temp 70) + (propertize s 'face 'font-lock-warning-face) + s) + ) + ) + ) - (if (> temperature 50) - (concat - (let ((s (format "%dC" temperature))) - (if (> temperature 65) (propertize s 'face - 'font-lock-warning-face) - s)) - "/" + (error nil)) + ) + +(defun ff/battery-info-string () (interactive) + (condition-case nil + (pcase (ff/battery-state ff/battery-dirs) + ;; (`charging (format "c%d%%" (ff/battery-percent))) + ;; (`discharging (format "d%d%%" (ff/battery-percent))) + ;; (`unknown "f") + + (`charging + (let ((p (ff/battery-percent))) + (if (> p 10) + (propertize (format "↑%d%%" p) 'face 'ff/battery-info-face) + (propertize (format "↑%d%%" p) 'face 'ff/battery-info-alarm-face)) + ) ) - ) - - ;; The battery - - (cond - - ((eq (nth 0 info) 'charged) "L") - - ((eq (nth 0 info) 'discharging) - (let* ((time (/ (* (nth 2 info) 60) (nth 3 info))) - (s (format "B%d:%02d" (/ time 60) (mod time 60)))) - (if (< time 15) - ;; Les than 15 minutes, let's write the remaining - ;; time in red - (propertize s 'face 'font-lock-warning-face) - s))) - ((eq (nth 0 info) 'charging) - (format "L%2d%%" (/ (* 100 (nth 2 info)) (nth 1 info)))) - - (t (format "???")) - - ))) - - (error nil))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun ff/system-info () (interactive) - - (let ((buf (get-buffer-create "*system info*")) - (map (make-sparse-keymap))) - - (define-key map "q" 'kill-this-buffer) - (display-buffer buf) - (set-buffer buf) - (setq show-trailing-whitespace nil) - (erase-buffer) - - (let ((highlight nil)) - - (mapc (lambda (x) - (insert - (if (setq highlight (not highlight)) - (propertize - (with-temp-buffer (apply 'call-process x) - (buffer-string)) - 'face '(:background "gray80")) - (with-temp-buffer (apply 'call-process x) - (buffer-string)) - )) + (`discharging + (let ((p (ff/battery-percent))) + (if (> p 10) + (propertize (format "↓%d%%" p) 'face 'ff/battery-info-face) + (propertize (format "↓%d%%" p) 'face 'ff/battery-info-alarm-face)) + ) ) - '( - ("hostname" nil t nil "-v") - ("acpi" nil t) - ("df" nil t nil "-h") - ;; ("mount" nil t) - ("ifconfig" nil t) - ("ssh-add" nil t nil "-l") - ))) - - (goto-char (point-min)) - (while (re-search-forward "^$" nil t) (backward-delete-char 1)) - - (fit-window-to-buffer (get-buffer-window buf)) - (use-local-map map) - (set-buffer-modified-p nil) - )) + (`unknown (propertize "☼" 'face 'ff/battery-info-face)) + ;; (`unknown "☼") + ;; (`unknown "F") + (_ "?")) + (error nil)) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Make a sound when there is new mail -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; I do not like sounds anymore -;; (setq ff/already-boinged-for-mail nil) +(defun ff/system-info () (interactive) -;; (defun ff/boing-if-new-mail () -;; (if mail (when (not ff/already-boinged-for-mail) -;; ;; (ff/play-sound-async "~/local/sounds/boing1.wav") -;; ;; (ff/show-unspooled-mails) -;; (setq ff/already-boinged-for-mail t)) -;; (setq ff/already-boinged-for-mail nil)) -;; ) + (let* ((buf (get-buffer-create "*system info*")) + (win (get-buffer-window buf)) + (map (make-sparse-keymap))) + + (if win + (progn + (delete-window win) + (kill-buffer buf)) + + (define-key map "q" 'kill-this-buffer) + (display-buffer buf) + (set-buffer buf) + (setq show-trailing-whitespace nil) + (erase-buffer) + + (let ((highlight nil)) + + (mapc (lambda (x) + (insert + (if (setq highlight (not highlight)) + (propertize + (with-temp-buffer (apply 'call-process x) + (buffer-string)) + 'face '(:background "#d0d0ff")) + (with-temp-buffer (apply 'call-process x) + (buffer-string)) + )) + ) -;; (add-hook 'display-time-hook 'ff/boing-if-new-mail) + '( + ("hostname" nil t nil "-f") + ("acpi" nil t) + ("df" nil t nil "-h") + ;; ("mount" nil t) + ("ifconfig" nil t) + ("ssh-add" nil t nil "-l") + ))) + + (goto-char (point-min)) + (while (re-search-forward "^$" nil t) (backward-delete-char 1)) + + (fit-window-to-buffer (get-buffer-window buf)) + (use-local-map map) + (set-buffer-modified-p nil) + ) + ) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Display time @@ -923,33 +1003,40 @@ printer." (setq - display-time-interval 15 ;; Check every 15s + display-time-interval 10 ;; Check every 10s display-time-string-forms `( - ;; (if mail - ;; (concat " " - ;; (propertize " mail " - ;; 'face 'ff/mail-alarm-face) - ;; " ") - ;; ) + load - (propertize (concat 24-hours ":" minutes - " " - dayname " " - monthname " " - day) - 'face 'ff/date-info-face) + " " - load + ,@(when (ff/temp-info-string) + '((ff/temp-info-string))) + + ,@(when (ff/battery-info-string) + '((ff/battery-info-string))) - ,(if (ff/laptop-info-string) - '(concat " /" (ff/laptop-info-string) "/")) + ;; '((propertize + ;; (ff/battery-info-string) + ;; 'face 'ff/battery-info-face))) + + " " + + (propertize + (concat ;;" ˌ" + 24-hours ":" minutes + " " + ;; dayname " " + monthname " " day + ;;"ˌ" + ) + 'face 'ff/date-info-face) ) - ;; display-time-format "%b %a %e %H:%M" - ;; display-time-mail-face nil + ;; display-time-format "%b %a %e %H:%M" + ;; display-time-mail-face nil ) ;; Show the time, mail and stuff @@ -979,8 +1066,13 @@ printer." (setq list (cdr list))) (switch-to-buffer found))) -(define-key global-map [?\C-x right] 'ff/next-buffer) -(define-key global-map [?\C-x left] 'ff/prev-buffer) +;; (define-key global-map [?\C-x right] 'ff/next-buffer) +;; (define-key global-map [?\C-x left] 'ff/prev-buffer) +;; (define-key global-map [?\M-\]] 'ff/next-buffer) +;; (define-key global-map [?\M-\[] 'ff/prev-buffer) + +(define-key global-map [(meta right)] 'ff/next-buffer) +(define-key global-map [(meta left)] 'ff/prev-buffer) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; There is actually a decent terminal emulator in emacs! @@ -988,11 +1080,16 @@ printer." (load "term") +(defun ff/kill-associated-buffer (process str) (interactive) + (let ((buffer (process-buffer process))) + (kill-buffer buffer)) + (message "Process finished (%s)" (replace-regexp-in-string "\n$" "" str))) + (defun ff/kill-associated-buffer-and-delete-windows (process str) (interactive) - (let ((buffer (process-buffer process))) - (delete-windows-on buffer) - (kill-buffer buffer)) - (message "Process finished (%s)" (replace-regexp-in-string "\n$" "" str))) + (let ((buffer (process-buffer process))) + (delete-windows-on buffer) + (kill-buffer buffer)) + (message "Process finished (%s)" (replace-regexp-in-string "\n$" "" str))) (defun ff/shell-new-buffer (buffername program &rest param) "Start a terminal-emulator in a new buffer with the shell PROGRAM, @@ -1034,9 +1131,12 @@ In line mode: M-p previous line, M-n next line.") (let ((process (get-buffer-process (current-buffer)))) (process-kill-without-query process) (set-process-sentinel process - 'ff/kill-associated-buffer-and-delete-windows)) + ;; 'ff/kill-associated-buffer-and-delete-windows + 'ff/kill-associated-buffer + )) - (switch-to-buffer-other-window (concat "*" bn "*")) + ;; (switch-to-buffer-other-window (concat "*" bn "*")) + (switch-to-buffer (concat "*" bn "*")) )) (defcustom ff/default-bash-commands '("ssh") @@ -1065,7 +1165,7 @@ of commands in `ff/default-bash-commands' is used for auto-completion" vc-follow-symlinks t ) -(when (require 'vc-git nil t) +(when (load "vc-git" nil t) (add-to-list 'vc-handled-backends 'GIT)) ;; alarm-vc.el is one of my own scripts, check my web page @@ -1073,9 +1173,9 @@ of commands in `ff/default-bash-commands' is used for auto-completion" (when (ff/load-or-alert "alarm-vc" t) (setq alarm-vc-mode-exceptions "^VM")) -(when (ff/load-or-alert "git") - (setq git-show-unknown nil) - ) +;; (when (ff/load-or-alert "git") + ;; (setq git-show-unknown nil) + ;; ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Makes .sh and others files executable automagically @@ -1083,21 +1183,24 @@ of commands in `ff/default-bash-commands' is used for auto-completion" ;; Please consider the security-related consequences of using it -(defun ff/make-shell-scripts-executable (&optional filename) - (setq filename (or filename (buffer-name))) - (when (and (string-match "\\.sh$\\|\\.pl$\\|\\.rb" filename) - (not (file-executable-p filename)) - ) - (set-file-modes filename 493) - (message "Made %s executable" filename))) +;; (defun ff/make-shell-scripts-executable (&optional filename) +;; (setq filename (or filename (buffer-name))) +;; (when (and (string-match "\\.sh$\\|\\.pl$\\|\\.rb" filename) +;; (not (file-executable-p filename)) +;; ) +;; (set-file-modes filename 493) +;; (message "Made %s executable" filename))) + +;; (add-hook 'after-save-hook 'ff/make-shell-scripts-executable) -(add-hook 'after-save-hook 'ff/make-shell-scripts-executable) +(add-hook 'after-save-hook + 'executable-make-buffer-file-executable-if-script-p) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Cool stuff to navigate in emacs-lisp sources ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(require 'find-func) +(load "find-func") (defun ff/goto-function-definition (&optional goback) "Go directly to the definition of the function at point. With @@ -1127,43 +1230,72 @@ goback argument, go back where we were." (define-key global-map [(meta G)] (lambda () (interactive) (ff/goto-function-definition t))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; (setq python-indent-offset 4) + +;; (define-key python-mode-map [(shift right)] 'python-indent-shift-right) +;; (define-key python-mode-map [(shift left)] 'python-indent-shift-left) +;; (define-key python-mode-map [(shift right)] 'indent-rigidly-right-to-tab-stop) +;; (define-key python-mode-map [(shift left)] 'indent-rigidly-left-to-tab-stop) + +(load "vc-git") + +(defun ff/git-pull-push (universal) (interactive "P") + (when universal (shell-command "git commit -a -m \"Update.\"" nil)) + (message "git pull / push ...") + (async-shell-command "git remote get-url origin && git pull && git push" nil) + ) + +(defun ff/git-pull () (interactive) + (message "git pull ...") + (shell-command "git pull" nil) + ) + +(define-key global-map [(control x) (v) (p)] 'ff/git-pull-push) +(define-key global-map [(control x) (v) (P)] 'ff/git-pull) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The big stuff (bbdb, mailcrypt, etc.) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Failsafe version if we can't load bbdb -(defun ff/explicit-name (email) email) - -(when (ff/load-or-alert "bbdb") - - (setq - ;; Stop asking (if not t or nil, will not ask) - bbdb-offer-save 'never - ;; I hate when bbdb decides to mess up my windows - bbdb-use-pop-up nil - ;; I have no problem with bbdb asking me if the sender email - ;; does not match exactly the address we have in the database - bbdb-quiet-about-name-mismatches 0 - ;; I have european friends, too - bbdb-north-american-phone-numbers-p nil - ;; To cycle through all possible addresses - bbdb-complete-name-allow-cycling t - ;; Cycle with full names only, not through all net-addresses alone too - bbdb-dwim-net-address-allow-redundancy t - ;; Do not add new addresses automatically - bbdb-always-add-addresses nil - ) +(setq bbdb-file "~/private/bbdb") + +(when (file-exists-p bbdb-file) + + ;; Failsafe version if we can't load bbdb + (defun ff/explicit-name (email) email) - (defface ff/known-address-face - '((t (:foreground "blue2"))) - "The face to display known mail identities.") + (when (with-no-warnings (ff/load-or-alert "bbdb")) - (defface ff/unknown-address-face - '((t (:foreground "red4"))) - "The face to display unknown mail identities.") + (setq + ;; Stop asking (if not t or nil, will not ask) + bbdb-offer-save 'never + ;; I hate when bbdb decides to mess up my windows + bbdb-use-pop-up nil + ;; I have no problem with bbdb asking me if the sender email + ;; does not match exactly the address we have in the database + bbdb-quiet-about-name-mismatches 0 + ;; I have european friends, too + bbdb-north-american-phone-numbers-p nil + ;; To cycle through all possible addresses + bbdb-complete-name-allow-cycling t + ;; Cycle with full names only, not through all net-addresses alone too + bbdb-dwim-net-address-allow-redundancy t + ;; Do not add new addresses automatically + bbdb-always-add-addresses nil + ) - (defun ff/explicit-name (email) - "Returns a string identity for the first address in EMAIL. The + (defface ff/known-address-face + '((t (:foreground "blue2"))) + "The face to display known mail identities.") + + (defface ff/unknown-address-face + '((t (:foreground "gray50"))) + "The face to display unknown mail identities.") + + (defun ff/explicit-name (email) + "Returns a string identity for the first address in EMAIL. The identity is taken from bbdb if possible or from the address itself with mail-extract-address-components. The suffix \"& al.\" is added if there are more than one address. @@ -1173,80 +1305,83 @@ ff/unknown-address-face. If a record is found and contains a note 'face, the associated face is used, otherwise ff/known-address-face is used." - (and email - (let* ((data (mail-extract-address-components email)) - (name (car data)) - (net (cadr data)) - (record (bbdb-search-simple nil net))) - - (concat + (and email + (let* ((data (mail-extract-address-components email)) + (name (car data)) + (net (cadr data)) + (record (bbdb-search-simple nil net))) - (condition-case nil - (propertize (bbdb-record-name record) - 'face - (or (cdr (assoc 'face - (bbdb-record-raw-notes record))) - 'ff/known-address-face)) - (error - (propertize (or (and data (concat "<" net ">")) - "*undefined*") - 'face 'ff/unknown-address-face) - )) - (if (string-match "," (mail-strip-quoted-names email)) " & al.") - ))) - ) + (concat - (ff/configure-faces '((ff/robot-address-face :foreground "green4") - (ff/important-address-face :foreground "blue2" - ;; :underline t - ;; :background "white" - ;; :foreground "green4" - :weight 'bold - ;; :slant 'italic - ))) + (condition-case nil + (propertize (bbdb-record-name record) + 'face + (or (cdr (assoc 'face + (bbdb-record-raw-notes record))) + 'ff/known-address-face)) + (error + (propertize (or (and data (concat "<" net ">")) + "*undefined*") + 'face 'ff/unknown-address-face) + )) + (if (string-match "," (mail-strip-quoted-names email)) " & al.") + ))) + ) + (ff/configure-faces '((ff/robot-address-face :foreground "green4") + (ff/personal-address-face :foreground "dark magenta" :weight 'bold) + (ff/important-address-face :foreground "red3" + :weight 'bold + ))) + ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; An encrypted file to put secure stuff (passwords, ...) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(when (ff/load-or-alert "mailcrypt") - (mc-setversion "gpg") - ;; Keep the passphrase for 10min - (setq mc-passwd-timeout 600 - ff/secure-note-file "~/private/secure-notes.gpg") - ) +(setq ff/secure-note-file "~/private/secure-notes.gpg") + +;; (when (ff/load-or-alert "mailcrypt") + ;; (mc-setversion "gpg") + ;; ;; Keep the passphrase for 10min + ;; (setq mc-passwd-timeout 600 + ;; ff/secure-note-file "~/private/secure-notes.gpg") + ;; ) (defface ff/secure-date - '((t (:background "gold" :weight bold))) + '((t (:background "white" :weight bold))) "The face to display the dates in the modeline.") (defun ff/secure-note-add () (interactive) - (find-file "~/private/secure-notes.gpg") - ;; Adds a new entry (i.e. date and a bunch of empty lines) + (unless + (let ((b (find-buffer-visiting ff/secure-note-file))) + (and b (switch-to-buffer b))) + (find-file ff/secure-note-file) + ;; Adds a new entry (i.e. date and a bunch of empty lines) + (goto-char (point-min)) + (insert "-- " + (format-time-string "%Y %b %d %H:%M:%S" (current-time)) + " --\n\n") + (previous-line 1) + ) - (goto-char (point-min)) - (insert "-- " - (format-time-string "%Y %b %d %H:%M:%S" (current-time)) - " ------------------------------------------------\n\n") - (previous-line 1) + ;; Colorizes the dates - ;; Colorizes the dates + (save-excursion + (goto-char (point-min)) + (while (re-search-forward + "^-- [0-9]+ [a-z]+ [0-9]+ [0-9]+:[0-9]+:[0-9]+ -+$" + nil t) + (add-text-properties + (match-beginning 0) (1+ (match-end 0)) + '(face ff/secure-date rear-nonsticky t)))) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward - "^-+ [0-9]+ [a-z]+ [0-9]+ [0-9]+:[0-9]+:[0-9]+.+$" - nil t) - (add-text-properties - (match-beginning 0) (match-end 0) '(face ff/secure-date)))) - - (set-buffer-modified-p nil) - (setq buffer-undo-list nil) - ) + (set-buffer-modified-p nil) + (setq buffer-undo-list nil) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Spelling @@ -1314,7 +1449,7 @@ universal argument starts xfig even if the .fig does not exist" '(("fig" . "xfig") ("jpg" . "gimp" ) ("png" . "gimp") ("pgm" . "gimp") ("ppm" . "gimp") - ("jpg" . "xv")) + ("svg" . "inkscape")) universal) (if (not (and (buffer-file-name) (string-match "\\(.*\\)\.tex$" @@ -1332,18 +1467,27 @@ universal argument starts xfig even if the .fig does not exist" )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Tex mode -;; When working on a tex file with other people, I can just change -;; ff/tex-command in the -*- part of the file so that I don't mess up -;; other's people configuration. +(defun ff/save-window-configuration (universal) (interactive "P") + (if universal + (progn + (setq ff/window-configuration (current-window-configuration)) + (message "Window configuration stored") + ) + (set-window-configuration ff/window-configuration)) + ) -(defadvice tex-file (around ff/set-my-own-tex-command () activate) - (let ((tex-command - (or (and (boundp 'ff/tex-command) - ff/tex-command) - tex-command))) - ad-do-it)) +(define-key global-map [(control =)] 'ff/save-window-configuration) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Tex mode + +;; (defadvice tex-file (around ff/set-my-own-tex-command () activate) + ;; (let ((ff/window-configuration-before-compilation (current-window-configuration))) + ;; ad-do-it + ;; (set-window-configuration ff/window-configuration-before-compilation) + ;; ) + ;; ) ;; This is a bit hardcore, but really I can't bear the superscripts in ;; my emacs window and could not find another way to deactivate them. @@ -1351,6 +1495,41 @@ universal argument starts xfig even if the .fig does not exist" (load "tex-mode") (defun tex-font-lock-suscript (pos) ()) +;; Automagically add the frame numbers in comments in a beamer file + +(defun ff/number-beamer-frames () + "Add the frame numbers as comments after each \begin{frame}" + (interactive) + + (save-excursion + (let ((total 0) + (n 1)) + + ;; First, clean-up existing numbering + (goto-char (point-min)) + (while (re-search-forward "^ *\\\\begin{frame}.*\\( %% frame [0-9]* / [0-9]*\\)$" nil t) + (kill-region (match-beginning 1) (match-end 1)) + ) + + ;; Then count the total number of frames + (goto-char (point-min)) + (while (re-search-forward "^ *\\\\begin{frame}" nil t) + (setq total (+ total 1)) + ) + + ;; Then, add the updated numbers + (goto-char (point-min)) + (while (re-search-forward "^ *\\\\begin{frame}" nil t) + (move-end-of-line 1) + (insert " %% frame " (prin1-to-string n) " / " (prin1-to-string total)) + (setq n (+ n 1)) + ) + ) + ) + + (message "Added frame numbers in comments.") + ) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Prevents many errors from beeping and makes the others play a nifty ;; sound @@ -1376,7 +1555,7 @@ universal argument starts xfig even if the .fig does not exist" ;; (ff/play-sound-async "~/local/sounds/short_la.wav") )) -(setq ring-bell-function 'ff/ring-bell) +;; (setq ring-bell-function 'ff/ring-bell) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Past the content of the url currently in the kill-ring with @@ -1393,8 +1572,15 @@ universal argument starts xfig even if the .fig does not exist" (call-process "w3m" nil t nil "-dump" url)) ) -(define-key global-map [(shift mouse-2)] - (lambda () (interactive) (ff/insert-url (current-kill 0)))) +;; (define-key global-map [(shift mouse-2)] + ;; (lambda () (interactive) (ff/insert-url (current-kill 0)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Trying to deal with cut-paste + +(setq x-select-enable-clipboard t) +(setq interprogram-paste-function 'x-cut-buffer-or-selection-value) +(define-key global-map [(shift mouse-2)] 'clipboard-yank) ;; lookup-dict is one of my own scripts, check my web page @@ -1410,13 +1596,13 @@ universal argument starts xfig even if the .fig does not exist" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ff/snip () (interactive) - (let ((start (condition-case nil (region-beginning) (error (point)))) - (end (condition-case nil (region-end) (error (point))))) - (goto-char end) - (insert "---------------------------- snip snip -------------------------------\n") - (goto-char start) - (insert "---------------------------- snip snip -------------------------------\n") - )) + (let ((start (condition-case nil (region-beginning) (error (point)))) + (end (condition-case nil (region-end) (error (point))))) + (goto-char end) + (insert "----------------------------- snip snip -----------------------------\n") + (goto-char start) + (insert "----------------------------- snip snip -----------------------------\n") + )) (defun ff/start-latex () "Adds all that stuff to start a new LaTeX document." @@ -1424,39 +1610,40 @@ universal argument starts xfig even if the .fig does not exist" (goto-char (point-min)) (insert "%% -*- mode: latex; mode: reftex; mode: flyspell; coding: utf-8; tex-command: \"pdflatex.sh\" -*- -\\documentclass[12pt]{article} -\\usepackage{epsfig} -\\usepackage{a4} -\\usepackage{amsmath} -\\usepackage{amssymb} +\\documentclass[11pt,a4paper,twoside]{article} +\\usepackage[a4paper,top=2.5cm,bottom=2cm,left=2.5cm,right=2.5cm]{geometry} \\usepackage[utf8]{inputenc} -%% \\usepackage{eurosym} -%% \\usepackage{hyperref} -%% \\usepackage{harvard} +\\usepackage{amsmath,amssymb,dsfont} +\\usepackage[pdftex]{graphicx} +\\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue,citecolor=blue]{hyperref} +\\usepackage{tikz} +\\usepackage[round]{natbib} +\\usepackage{cmbright} +%\\usepackage{showframe} \\setlength{\\parindent}{0cm} \\setlength{\\parskip}{12pt} +%\\renewcommand{\\baselinestretch}{1.3} +%\\setlength{\\tabcolsep}{0pt} +%\\renewcommand{\\arraystretch}{1.0} + +\\def\\argmax{\\operatornamewithlimits{argmax}} +\\def\\argmin{\\operatornamewithlimits{argmin}} +\\def\\expect{\\mathds{E}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Sans serif fonts -%% \\usepackage[T1]{fontenc} -%% \\usepackage[scaled]{helvet} -%% \\usepackage[cm]{sfmath} -%% \\renewcommand{\\ttdefault}{pcr} -%% \\renewcommand*\\familydefault{\\sfdefault} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Draft layout -%% \\setlength{\\parindent}{1cm} -%% \\renewcommand{\\baselinestretch}{2.0} -%% \\setlength{\\oddsidemargin}{-0.6cm} -%% \\setlength{\\evensidemargin}{0cm} -%% \\setlength{\\textwidth}{17.5cm} -%% \\setlength{\\textheight}{23cm} -%% \\setlength{\\topmargin}{-1.5cm} +%% The \\todo command +\\newcounter{nbdrafts} +\\setcounter{nbdrafts}{0} +\\makeatletter +\\newcommand{\\checknbdrafts}{ +\\ifnum \\thenbdrafts > 0 +\\@latex@warning@no@line{*WARNING* The document contains \\thenbdrafts \\space draft note(s)} +\\fi} +\\newcommand{\\todo}[1]{\\addtocounter{nbdrafts}{1}{\\color{red} #1}} +\\makeatother %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% \\renewcommand{\\baselinestretch}{1.3} - \\begin{document} ") @@ -1464,6 +1651,12 @@ universal argument starts xfig even if the .fig does not exist" (goto-char (point-max)) (insert " +\\bibliographystyle{abbrvnat} + +\\bibliography{dlc} + +\\checknbdrafts + \\end{document} ")) (latex-mode)) @@ -1473,25 +1666,12 @@ universal argument starts xfig even if the .fig does not exist" (defun ff/add-copyrights () "Adds two lines for the (C) at the beginning of current buffer." (interactive) - (let ((comment-style 'plain) - (gpl - (concat - - "\nSTART_IP_HEADER\n" - - (when (boundp 'user-full-name) - (concat "\nWritten by " user-full-name "\n")) - - (when (boundp 'user-mail-address) - (concat "Contact <" user-mail-address "> for comments & bug reports\n")) - "\nEND_IP_HEADER\n" - - ))) + (let ((comment-style 'plain)) (goto-char (point-min)) - ;; If this is a script, put the gpl after the first line + ;; If this is a script, put the copyrights after the first line (when (re-search-forward "^#!" nil t) (beginning-of-line) @@ -1499,7 +1679,20 @@ universal argument starts xfig even if the .fig does not exist" (let ((start (point)) (comment-style 'box)) - (insert gpl) + (insert + (concat + + "\nSTART_IP_HEADER\n" + + (when (boundp 'user-full-name) + (concat "\nWritten by " user-full-name "\n")) + + (when (boundp 'user-mail-address) + (concat "Contact <" user-mail-address "> for comments & bug reports\n")) + + "\nEND_IP_HEADER\n" + )) + (comment-region start (point))) )) @@ -1507,12 +1700,12 @@ universal argument starts xfig even if the .fig does not exist" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ff/remove-ip-header () (interactive) - (save-excursion - (goto-char (point-min)) - (when (and (re-search-forward "START_IP_HEADER" nil t) - (re-search-forward "END_IP_HEADER" nil t)) - (message "yep")) - )) + (save-excursion + (goto-char (point-min)) + (when (and (re-search-forward "START_IP_HEADER" nil t) + (re-search-forward "END_IP_HEADER" nil t)) + (message "yep")) + )) (defun ff/add-gpl () "Adds the GPL statements at the beginning of current buffer." @@ -1631,6 +1824,39 @@ int main(int argc, char **argv) { ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ff/start-lua () + "Adds all the stuff to start a new lua file" + (interactive) + (goto-char (point-min)) + (insert "#!/usr/bin/env luajit + +require 'torch' +require 'nn' +require 'image' +require 'optim' + +") + (lua-mode) + ) + +(defun ff/start-python () + "Adds all the stuff to start a new python file" + (interactive) + (goto-char (point-min)) + (insert "#!/usr/bin/env python + +import math + +import torch, torchvision + +from torch import nn +from torch.nn import functional as F + +") + (python-mode) + ) + + (defun ff/start-html () "Adds all that stuff to start a new HTML file." (interactive) @@ -1643,6 +1869,11 @@ int main(int argc, char **argv) { + @@ -1667,9 +1898,7 @@ the function is invoked with a universal arg" (interactive "P") (let ((line (if arg "cerr" "cout"))) (goto-char (point-at-bol)) - ;; Regexp syntax sucks moose balls, honnest. To match '[', just - ;; put it as the first char in the [...] ... This leads to some - ;; obvious things like the following + ;; To match '[', put it as the first char in the [...] (while (re-search-forward "\\([][a-zA-Z0-9_.:\(\)]+\\)" (point-at-eol) t) (setq line (concat line " << \" " @@ -1694,17 +1923,31 @@ and refilling all the paragraphs." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun ff/start-slide () - (interactive) - (insert "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +(defun ff/start-slide (universal) + (interactive "P") + + (if universal + (progn + (insert "\\end{frame} -\\begin{frame}{") +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - (save-excursion (insert "}{} +\\begin{frame}[fragile]{") + (save-excursion (insert "}{} + +")) + ) + + (insert "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\\begin{frame}[fragile]{") + + (save-excursion (insert "}{} \\end{frame} ")) + ) ) (add-hook @@ -1714,8 +1957,8 @@ and refilling all the paragraphs." (define-key latex-mode-map [(control c) (control a)] 'align-current) (define-key latex-mode-map [(control end)] 'tex-close-latex-block) (define-key latex-mode-map [(control tab)] 'ispell-complete-word) - (flyspell-mode) - (reftex-mode) + (copy-face 'default 'tex-verbatim) + ;; (ff/configure-faces '((tex-verbatim :background "gray95"))) )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1739,26 +1982,26 @@ and refilling all the paragraphs." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ff/code-to-html () (interactive) - (save-restriction - (narrow-to-region (region-beginning) (region-end)) - (replace-string "\"" """ nil (point-min) (point-max)) - (replace-string " " " " nil (point-min) (point-max)) - (replace-string ">" ">" nil (point-min) (point-max)) - (replace-string "<" "<" nil (point-min) (point-max)) - (replace-string "\e" "^[" nil (point-min) (point-max)) - (replace-string "" "^?" nil (point-min) (point-max)) - (replace-string "" "^_" nil (point-min) (point-max)) - (replace-regexp "$" "
" nil (point-min) (point-max)) - ) - ) + (save-restriction + (narrow-to-region (region-beginning) (region-end)) + (replace-string "\"" """ nil (point-min) (point-max)) + (replace-string " " " " nil (point-min) (point-max)) + (replace-string ">" ">" nil (point-min) (point-max)) + (replace-string "<" "<" nil (point-min) (point-max)) + (replace-string "\e" "^[" nil (point-min) (point-max)) + (replace-string "" "^?" nil (point-min) (point-max)) + (replace-string "" "^_" nil (point-min) (point-max)) + (replace-regexp "$" "
" nil (point-min) (point-max)) + ) + ) (defun ff/downcase-html-tags () (interactive) - (save-excursion - (beginning-of-buffer) - (while (re-search-forward "<\\([^>]+\\)>" nil t) - (downcase-region (match-beginning 1) (match-end 1))) - ) - ) + (save-excursion + (beginning-of-buffer) + (while (re-search-forward "<\\([^>]+\\)>" nil t) + (downcase-region (match-beginning 1) (match-end 1))) + ) + ) ;; If we enter html mode and there is no makefile around, create a ;; compilation command with tidy (this is cool stuff) @@ -1809,77 +2052,85 @@ a file in /tmp" ;; Create the adequate embryo of a file if it does not exist (defun ff/start-file () (interactive) - (let ((filename (buffer-file-name))) - (when filename - - (when (string-match "\\.sh$" filename) - (sh-mode) - (insert "#!/bin/bash\n\nset -e\n\n") - (save-excursion - (ff/add-copyrights)) - ) + (let ((filename (buffer-file-name))) + (when filename + + (when (string-match "\\.sh$" filename) + (sh-mode) + (insert "#!/bin/bash\n\nset -e\nset -o pipefail\n\n") + (save-excursion + (ff/add-copyrights)) + ) - (when (string-match "\\.html$" filename) - (html-mode) - (ff/start-html) - (previous-line 4) - ) + (when (string-match "\\.lua$" filename) + (lua-mode) + (ff/start-lua) + ) - (when (string-match "\\.h$" filename) - (c++-mode) - (ff/headerize) - (save-excursion - (ff/add-copyrights) - (newline)) - (newline) - (newline) - (previous-line 1) - ) + (when (string-match "\\.py$" filename) + (python-mode) + (ff/start-python) + ) - (when (string-match "\\.c$" filename) - (c-mode) - (ff/add-copyrights) - (ff/start-c)) - - (when (string-match "\.\\(cc\\|cpp\\)$" filename) - (c++-mode) - (ff/add-copyrights) - (let ((headername (replace-regexp-in-string "\\.\\(cc\\|cpp\\)$" ".h" - filename))) - (if (file-exists-p headername) - (insert (concat "\n#include \"" (file-name-nondirectory headername) "\"\n")) - (ff/start-c++)) - )) + (when (string-match "\\.html$" filename) + (html-mode) + (ff/start-html) + (previous-line 4) + ) - (when (string-match "\\.tex$" filename) - (latex-mode) - (ff/start-latex) - )) - ) - (set-buffer-modified-p nil) - ) + (when (string-match "\\.h$" filename) + (c++-mode) + (ff/headerize) + (save-excursion + (ff/add-copyrights) + (newline)) + (newline) + (newline) + (previous-line 1) + ) + + (when (string-match "\\.c$" filename) + (c-mode) + (ff/add-copyrights) + (ff/start-c)) + + (when (string-match "\.\\(cc\\|cpp\\)$" filename) + (c++-mode) + (ff/add-copyrights) + (let ((headername (replace-regexp-in-string "\\.\\(cc\\|cpp\\)$" ".h" + filename))) + (if (file-exists-p headername) + (insert (concat "\n#include \"" (file-name-nondirectory headername) "\"\n")) + (ff/start-c++)) + )) + + (when (string-match "\\.tex$" filename) + (latex-mode) + (ff/start-latex) + )) + ) + (set-buffer-modified-p nil) + ) (if (>= emacs-major-version 22) (add-to-list 'find-file-not-found-functions 'ff/start-file) (add-to-list 'find-file-not-found-hooks 'ff/start-file)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(when (>= emacs-major-version 24) + (define-obsolete-function-alias 'make-local-hook 'ignore "21.1") + (setq send-mail-function 'sendmail-send-it) ;; emacs 24.x stuff -(define-key global-map [f8] 'ff-find-other-file) -(define-key global-map [(shift f8)] (lambda () (interactive) (ff-find-other-file t))) + (custom-set-faces + '(diff-added ((default (:background "gray90" :foreground "green4" :weight bold)))) + '(diff-removed ((default (:background "gray90" :foreground "red2" :weight bold)))) + '(diff-changed ((default (:background "gray90" :foreground "blue" :weight bold)))) + ) + ) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Antiword, htmlize and boxquote ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(autoload 'no-word "no-word") -(add-to-list 'auto-mode-alist '("\\.doc\\'" . no-word)) -;; (add-to-list 'auto-mode-alist '("\\.DOC\\'" . no-word)) - -(autoload 'htmlize-buffer "htmlize" nil t) - -(setq boxquote-top-and-tail "------------------") -(autoload 'boxquote-region "boxquote" nil t) +(define-key global-map [f8] 'ff-find-other-file) +(define-key global-map [(shift f8)] (lambda () (interactive) (ff-find-other-file t))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The compilation hacks @@ -1920,7 +2171,7 @@ a file in /tmp" ) ) -(setq compilation-finish-functions (cons 'ff/restore-windows-if-no-error compilation-finish-functions)) +(add-to-list 'compilation-finish-functions 'ff/restore-windows-if-no-error) (defun ff/fast-compile () "Compiles without asking anything." @@ -1931,23 +2182,34 @@ a file in /tmp" (setq compilation-read-command t compile-command "make -j -k" - compile-history '("make clean" "make DEBUG=yes -j -k" "make -j -k") + ;; compile-history '("make clean" "make DEBUG=yes -j -k" "make -j -k") ) -(defun ff/universal-compile () (interactive) - (funcall (or (cdr (assoc major-mode - '( - (latex-mode . tex-file) - (html-mode . browse-url-of-buffer) - ;; Here you can add other mode -> compile command - ))) - 'ff/fast-compile ;; And this is the failsafe - ))) +(defun ff/universal-compile (universal) (interactive "P") + (funcall (or (cdr (assoc major-mode + '( + (latex-mode . tex-file) + (html-mode . browse-url-of-buffer) + ;; Here you can add other mode -> compile command + ))) + 'ff/fast-compile ;; And this is the failsafe + ))) (define-key global-map [f1] 'ff/universal-compile) (define-key global-map [(shift f1)] 'compile) (define-key global-map [f2] 'next-error) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Horrible hack +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun dont-delay-compile-warnings (fun type &rest args) + (if (eq type 'bytecomp) + (let ((after-init-time t)) + (apply fun type args)) + (apply fun type args))) +(advice-add 'display-warning :around #'dont-delay-compile-warnings) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Related to mail ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1955,14 +2217,27 @@ a file in /tmp" ;; (when (ff/load-or-alert "flyspell-timer" t) ;; (add-hook 'flyspell-mode-hook 'flyspell-timer-ensure-idle-timer)) +(defun ff/start-flyspell () (interactive) + (ff/configure-faces + '( + ;; (flyspell-incorrect :background "#ff0000" :foreground "black") + ;; (flyspell-duplicate :background "#ff9000" :foreground "black") + (flyspell-incorrect :foreground "#ff0000" :weight 'bold) + (flyspell-duplicate :foreground "#ff9000" :weight 'bold) + )) + ;; (flyspell-buffer) + ) + +(add-hook 'flyspell-mode-hook 'ff/start-flyspell) + (defun ff/pick-dictionnary () (interactive) - (when (and (boundp 'flyspell-mode) flyspell-mode) - (if (and current-input-method (string-match "latin" current-input-method)) - (ispell-change-dictionary "francais") - (ispell-change-dictionary "american")) - ;; (flyspell-buffer) - ) - ) + (when (and (boundp 'flyspell-mode) flyspell-mode) + (if (and current-input-method (string-match "latin" current-input-method)) + (ispell-change-dictionary "francais") + (ispell-change-dictionary "american")) + ;; (flyspell-buffer) + ) + ) (defadvice toggle-input-method (after ff/switch-dictionnary nil activate) (ff/pick-dictionnary)) @@ -2015,22 +2290,22 @@ This may be a useful alternative binding for \\[delete-other-windows] ;; Usefull to deal with results in latex files (defun ff/round-floats-in-region () (interactive) - (save-restriction - (condition-case nil - (narrow-to-region (region-beginning) (region-end)) - (error (thing-at-point 'word))) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward "[0-9\.]+" nil t) - (let ((value (string-to-number (buffer-substring (match-beginning 0) (match-end 0))))) - (delete-region (match-beginning 0) (match-end 0)) - (insert (format "%0.2f" value))))))) + (save-restriction + (condition-case nil + (narrow-to-region (region-beginning) (region-end)) + (error (thing-at-point 'word))) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "[0-9\.]+" nil t) + (let ((value (string-to-number (buffer-substring (match-beginning 0) (match-end 0))))) + (delete-region (match-beginning 0) (match-end 0)) + (insert (format "%0.1e" value))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Keymaping ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(require 'info nil t) +(load "info" nil t) (define-key global-map [(shift iso-lefttab)] 'ispell-complete-word) ;; shift-tab going backward is kind of standard @@ -2069,6 +2344,8 @@ This may be a useful alternative binding for \\[delete-other-windows] ;; Compiles the latex file in the current buffer + + (setq tex-start-commands "\\input") (define-key global-map [f3] 'tex-file) (define-key global-map [(shift f3)] 'tex-bibtex-file) @@ -2081,25 +2358,6 @@ This may be a useful alternative binding for \\[delete-other-windows] ;; Closes the current \begin{} -(when (ff/load-or-alert "longlines") - - (setq longlines-show-hard-newlines t - longlines-auto-wrap t - ;; longlines-show-effect #("|\n" 0 2 (face escape-glyph)) - ) - - ;; (defun ff/auto-longlines () - ;; (when (save-excursion - ;; (goto-char (point-min)) - ;; (re-search-forward "^.\\{81,\\}$" nil t)) - ;; (longlines-mode) - ;; (message "Switched on the lonlines mode automatically") - ;; )) - - ;; (add-hook 'latex-mode-hook 'ff/auto-longlines) - - ) - ;; Meta-/ remaped (completion) (define-key global-map [(shift right)] 'dabbrev-expand) @@ -2108,14 +2366,14 @@ This may be a useful alternative binding for \\[delete-other-windows] ;; Change the current window. (defun ff/next-same-frame-window () (interactive) - (select-window (next-window (selected-window) - (> (minibuffer-depth) 0) - nil))) + (select-window (next-window (selected-window) + (> (minibuffer-depth) 0) + nil))) (defun ff/previous-same-frame-window () (interactive) - (select-window (previous-window (selected-window) - (> (minibuffer-depth) 0) - nil))) + (select-window (previous-window (selected-window) + (> (minibuffer-depth) 0) + nil))) (define-key global-map [(shift prior)] 'ff/next-same-frame-window) (define-key global-map [(shift next)] 'ff/previous-same-frame-window) @@ -2129,19 +2387,19 @@ This may be a useful alternative binding for \\[delete-other-windows] ;; (define-key global-map [(control shift next)] 'previous-multiframe-window) ;; I have two screens sometime! +;; (define-key global-map [(meta next)] 'other-frame) +;; (define-key global-map [(meta prior)] (lambda () (interactive) (other-frame -1))) -(define-key global-map [(meta next)] 'other-frame) -(define-key global-map [(meta prior)] (lambda () (interactive) (other-frame -1))) - -(define-key global-map [(shift home)] 'delete-other-windows-vertically) +;; (load "winner") +(winner-mode 1) +;; (define-key global-map [(shift backspace)] 'winner-undo) +;; (define-key global-map [(shift home)] 'delete-other-windows-vertically) ;; (define-key global-map [(control +)] 'enlarge-window) ;; (define-key global-map [(control -)] 'shrink-window) - ;; Goes to next/previous buffer - -(define-key global-map [(control prior)] 'ff/next-buffer) -(define-key global-map [(control next)] 'ff/prev-buffer) +;; (define-key global-map [(control prior)] 'ff/next-buffer) +;; (define-key global-map [(control next)] 'ff/prev-buffer) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; If M-. on a symbol, show where it is defined in another window @@ -2151,12 +2409,12 @@ This may be a useful alternative binding for \\[delete-other-windows] (when (ff/load-or-alert "etags") (defun ff/find-tag-nofocus () (interactive) - "Show in another window the definition of the current tag" - (let ((tag (find-tag-default))) - (display-buffer (find-tag-noselect tag (string= tag last-tag))) - (message "Tag %s" tag) - ) - ) + "Show in another window the definition of the current tag" + (let ((tag (find-tag-default))) + (display-buffer (find-tag-noselect tag (string= tag last-tag))) + (message "Tag %s" tag) + ) + ) (define-key global-map [(meta .)] 'ff/find-tag-nofocus) ) @@ -2189,7 +2447,7 @@ next one. With universal argument, kill all killable buffers." (if (string-match ff/kill-this-buffer-and-delete-window-exceptions (buffer-name)) (ff/next-buffer) (kill-this-buffer))) - ;; (unless (one-window-p t) (delete-window)) + (unless (one-window-p t) (delete-window)) ) (define-key global-map [(control backspace)] 'ff/kill-this-buffer-and-delete-window) @@ -2216,42 +2474,38 @@ next one. With universal argument, kill all killable buffers." (message "elisp debug off"))) (defun ff/create-dummy-buffer (&optional universal) (interactive "P") - (find-file (concat "/tmp/" (ff/non-existing-filename "/tmp/" "dummy" ""))) - (text-mode) - (if universal (ff/insert-url (current-kill 0))) - (message "New dummy text-mode buffer")) + (find-file (concat "/tmp/" (ff/non-existing-filename "/tmp/" "dummy" ""))) + (text-mode) + (if universal (ff/insert-url (current-kill 0))) + (message "New dummy text-mode buffer")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recentf to keep a list of recently visited files. I use it ;; exclusively with my selector.el ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(require 'recentf) - -(setq recentf-exclude - (append recentf-exclude - '("enotes$" "secure-notes$" "media-playlists$" - "bbdb$" - "svn-commit.tmp$" ".git/COMMIT_EDITMSG$" - "\.bbl$" "\.aux$" "\.toc$")) - recentf-max-saved-items 1000 - recentf-save-file "~/private/emacs/recentf" +(load "recentf") + +;; If we just check for file-symlink-p, everytime we start emacs it +;; will check all the remote files listed in recentf-list, so we check +;; that they are not remote first +(defun ff/file-not-remote-but-symlink (filename) + (and (not (file-remote-p filename)) (file-symlink-p filename))) + +(setq recentf-exclude (append recentf-exclude + '( + ff/file-not-remote-but-symlink + "enotes$" "secure-notes$" "media-playlists$" + "bbdb$" + "svn-commit.tmp$" ".git/COMMIT_EDITMSG$" + "\.bbl$" "\.aux$" "\.toc$" + )) + recentf-max-saved-items 10000 + recentf-save-file (concat ff/emacs-dir "/recentf") ) (when (boundp 'recentf-keep) (add-to-list 'recentf-keep 'file-remote-p)) -;; Removes the link if we add the file itself (I am fed up with -;; duplicates because of vc-follow-symlinks) - -(defadvice recentf-add-file (before ff/remove-links (filename) activate) - ;; If we are adding a filename corresponding to the last link we - ;; have added, remove the latter - (when (and recentf-list - (file-symlink-p (car recentf-list)) - (string= filename (file-chase-links filename))) - (setq recentf-list (cdr recentf-list)) - )) - (recentf-mode 1) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2283,16 +2537,19 @@ next one. With universal argument, kill all killable buffers." media/add-current-song-to-interrupted-when-killing t media/duration-to-history 30 media/history-size 1000 - media/playlist-file "~/private/emacs/media-playlists" + media/playlist-file (concat ff/emacs-dir "/media-playlists") + media/continue-mode-hint (if window-system "⤸" "*") media/mplayer/args '( "-framedrop" "-zoom" + "-cache" "512" "-subfont-osd-scale" "3" ;; "-stop-xscreensaver" ;; "-osdlevel" "3" ) - media/mplayer/timing-request-period 5.0 + media/mplayer/timing-request-period 1.0 ) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2302,7 +2559,7 @@ next one. With universal argument, kill all killable buffers." ;; selector.el is one of my own scripts, check my web page (when (ff/load-or-alert "selector" t) - (define-key global-map [(shift return)] 'selector/quick-move-in-buffer) + ;; (define-key global-map [(shift return)] 'selector/quick-move-in-buffer) (define-key global-map [(control x) (control b)] 'selector/switch-buffer) (defun ff/visit-debpkg-file (&optional regexp) @@ -2337,22 +2594,36 @@ proposes to visit them." ) (defun ff/selector-mail-from-bbdb () (interactive) - (selector/select - (mapcar - (lambda (r) (cons (concat (elt r 0) - " " - (elt r 1) - " (" - (car (elt r 6)) - ")") - r)) - (bbdb-records)) - (if (string= mode-name "Mail") - 'ff/selector-insert-record-callback - 'ff/selector-compose-mail-callback) - "*bbdb-search*" - ) - ) + (selector/select + (mapcar + (lambda (r) (cons (concat (elt r 0) + " " + (elt r 1) + " (" + (car (elt r 6)) + ")") + r)) + (bbdb-records)) + (if (string= mode-name "Mail") + 'ff/selector-insert-record-callback + 'ff/selector-compose-mail-callback) + "*bbdb-search*" + ) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; My script to automatically count the number of words and characters +;; between two markers + +(ff/load-or-alert "text-counters.el") + +;; Display them in the modeline when in text-mode + +(add-hook 'text-mode-hook 'tc/add-text-counters-in-modeline) + +;; (add-hook 'text-mode-hook +;; (lambda () +;; (setq comment-start " > "))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; A function to remove temporary alarm windows @@ -2388,62 +2659,100 @@ proposes to visit them." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ff/twin-horizontal-current-buffer () (interactive) - (delete-other-windows) - (split-window-horizontally) - (balance-windows) - ) + (delete-other-windows) + (split-window-horizontally) + (balance-windows) + ) (defun ff/twin-vertical-current-buffer () (interactive) - (delete-other-windows) - (split-window-vertically) - (balance-windows) - ) + (delete-other-windows) + (split-window-vertically) + (balance-windows) + ) (defun ff/flyspell-mode (arg) (interactive "p") - (flyspell-mode) - (when flyspell-mode (flyspell-buffer))) + (if flyspell-mode (flyspell-mode -1) + (flyspell-mode 1) + (flyspell-buffer)) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The fridge! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun ff/move-region-to-fridge () (interactive) - "Cut the current region, paste it in a file called ./fridge +(defun ff/move-region-to-fridge (&optional universal) (interactive "P") + "Cut the current region, paste it in a file called ./fridge with a time tag, and save this file" - (unless (use-region-p) (error "No region selected")) - (let ((bn (file-name-nondirectory (buffer-file-name)))) - (kill-region (region-beginning) (region-end)) - (with-current-buffer (find-file-noselect "fridge") - (goto-char (point-max)) - (insert "\n" - (format-time-string "%Y %b %d %H:%M:%S" (current-time)) - " (from " - bn - ")\n\n") - (yank) - (save-buffer) - (message "Region moved to fridge") - ) - ) - ) + (unless (use-region-p) (error "No region selected")) + (let ((bn (file-name-nondirectory (buffer-file-name)))) + (if universal + (copy-region-as-kill (region-beginning) (region-end)) + (kill-region (region-beginning) (region-end)) + ) + (with-current-buffer (find-file-noselect "fridge") + (goto-char (point-max)) + (insert "\n") + (insert "######################################################################\n") + (insert "\n" + (format-time-string "%Y %b %d %H:%M:%S" (current-time)) + " (from " + bn + ")\n\n") + (yank) + (save-buffer) + (message "Region moved to fridge") + ) + ) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; My own keymap +;; My own keymap mapped to C-` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq ff/map (make-sparse-keymap)) (define-key global-map [(control \`)] ff/map) + +;; (defun ff/start-stop-macro-recording () (interactive) + ;; (if (or defining-kbd-macro executing-kbd-macro) + ;; (kmacro-end-macro) + ;; (kmacro-start-macro)) + ;; ) + +;; (define-key global-map [(shift return)] 'ff/start-stop-macro-recording) + +(unless window-system + ;; (define-key global-map [(control @)] ff/map) + (define-key global-map [(meta O) \`] ff/map) + ) + (define-key esc-map "`" ff/map) -(defun ff/git-status (&optional dir) (interactive) - (if (buffer-file-name) - (git-status (file-name-directory (buffer-file-name))) - (error "No file attached to this buffer"))) +(defun ff/kill-downto-signature () (interactive) + (let ((s (point))) + (when (re-search-forward "^-- $") + (kill-region s (match-beginning 0)) + (goto-char s)))) -(define-key ff/map [(control g)] 'ff/git-status) -(define-key ff/map [(control w)] 'server-edit) +(defun ff/git-status (&optional dir) (interactive) + (if (buffer-file-name) + (git-status (file-name-directory (buffer-file-name))) + (error "No file attached to this buffer"))) + +(defun ff/insert-date (&optional universal) (interactive "P") + (insert (format-time-string "\n * %H:%M:%S %A %B %d, %Y\n\n" (current-time))) + ;; ;; (insert (format-time-string "%Y %b %d %H:%M:%S" (current-time))) + ;; ;; (insert (format-time-string "%d.%m.%y" (current-time))) + ;; (if universal + ;; (insert (format-time-string "%d.%m.%Y %H:%M:%S" (current-time))) + ;; (insert (format-time-string "%d.%m.%Y" (current-time)))) + ) + +(define-key ff/map [(control g)] 'magit) +;;(define-key ff/map [(control g)] 'ff/git-status) +;; (define-key ff/map [(control w)] 'server-edit) (define-key ff/map [(control d)] 'ff/elisp-debug-on) -(define-key ff/map "d" 'diary) +;; (define-key ff/map "d" 'diary) +(define-key ff/map "d" 'ff/insert-date) (define-key ff/map [(control \`)] 'ff/bash-new-buffer) (define-key ff/map [(control n)] 'enotes/show-all-notes) (define-key ff/map [(control s)] 'ff/secure-note-add) @@ -2452,13 +2761,15 @@ with a time tag, and save this file" (define-key ff/map [(control a)] 'auto-fill-mode) (define-key ff/map [(control i)] 'ff/system-info) (define-key ff/map "w" 'ff/word-occurences) -(define-key ff/map [(control c)] 'calendar) +;; (define-key ff/map [(control c)] 'calendar) +(define-key ff/map [(control c)] 'ff/show-compilation-buffer-split-window) ;; (define-key ff/map [(control c)] (lambda () (interactive) (save-excursion (calendar)))) (define-key ff/map [(control l)] 'goto-line) (define-key ff/map "l" 'longlines-mode) (define-key ff/map [(control o)] 'selector/quick-pick-recent) (define-key ff/map "s" 'selector/quick-move-in-buffer) (define-key ff/map "S" 'selector/search-sentence) +(define-key ff/map "t" (lambda () (interactive) (find-file "~/private/TODO.txt"))) (define-key ff/map "h" 'ff/tidy-html) (define-key ff/map "c" 'ff/count-char) (define-key ff/map [(control p)] 'ff/print-to-file) @@ -2468,12 +2779,14 @@ with a time tag, and save this file" (define-key ff/map [(control m)] 'woman) (define-key ff/map "b" 'bookmark-jump) (define-key ff/map [(control =)] 'calc) +(define-key ff/map "=" 'ff/number-beamer-frames) (define-key ff/map [(control shift b)] (lambda () (interactive) (bookmark-set) (bookmark-save))) (define-key ff/map "f" 'ff/move-region-to-fridge) (define-key ff/map [(control f)] 'ff/flyspell-mode) +(define-key ff/map [(control k)] 'ff/kill-downto-signature) (define-key ff/map [?\C-0] 'ff/delete-annoying-windows) (define-key ff/map "1" 'delete-other-windows) @@ -2495,30 +2808,30 @@ with a time tag, and save this file" ;; so that it works in xterm (yes), let's use xclip. This is a bit ;; ugly. - (defun ff/yank-with-xclip (&optional arg) - "Paste the content of the X clipboard with the xclip -command. Without ARG converts some of the '\\uxxxx' characters." - (interactive "P") - (with-temp-buffer - (shell-command "xclip -o" t) - (unless arg - (mapc (lambda (x) (replace-string (concat "\\u" (car x)) (cdr x) nil (point-min) (point-max))) - '(("fffd" . "??") - ("2013" . "-") - ("2014" . "--") - ("2018" . "`") - ("2019" . "'") - ("201c" . "``") - ("201d" . "''") - ("2022" . "*") - ("2026" . "...") - ("20ac" . "EUR") - ))) - (kill-ring-save (point-min) (point-max))) - - (yank)) - - (define-key global-map [(meta y)] 'ff/yank-with-xclip) + ;; (defun ff/yank-with-xclip (&optional arg) + ;; "Paste the content of the X clipboard with the xclip + ;; command. Without ARG converts some of the '\\uxxxx' characters." + ;; (interactive "P") + ;; (with-temp-buffer + ;; (shell-command "xclip -o" t) + ;; (unless arg + ;; (mapc (lambda (x) (replace-string (concat "\\u" (car x)) (cdr x) nil (point-min) (point-max))) + ;; '(("fffd" . "??") + ;; ("2013" . "-") + ;; ("2014" . "--") + ;; ("2018" . "`") + ;; ("2019" . "'") + ;; ("201c" . "``") + ;; ("201d" . "''") + ;; ("2022" . "*") + ;; ("2026" . "...") + ;; ("20ac" . "EUR") + ;; ))) + ;; (kill-ring-save (point-min) (point-max))) + + ;; (yank)) + + ;; (define-key global-map [(meta y)] 'ff/yank-with-xclip) ;; (set-terminal-coding-system 'iso-latin-1) ;; (set-terminal-coding-system 'utf-8) @@ -2649,28 +2962,26 @@ With argument ARG, do this that many times." ;; Privacy ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Where to save the bookmarks and where is bbdb +;; Where to save the bookmarks -(setq bookmark-default-file "~/private/emacs/bmk" - bbdb-file "~/private/bbdb" - custom-file "~/private/emacs/custom") +(setq bookmark-default-file (concat ff/emacs-dir "/bmk") + custom-file (concat ff/emacs-dir "/custom")) ;; enotes.el is one of my own scripts, check my web page -(when (ff/load-or-alert "enotes" t) - (setq enotes/file "~/private/enotes" - enotes/show-help nil - enotes/full-display nil - enotes/default-time-fields "9:30") - - (enotes/init) - ;; (add-hook 'enotes/alarm-hook - ;; (lambda () (ff/play-sound-async "~/local/sounds/three_notes2.wav"))) +;; ** ;; (when (ff/load-or-alert "enotes" t) +;; ** ;; (setq enotes/file "~/private/enotes" +;; ** ;; enotes/show-help nil +;; ** ;; enotes/full-display nil +;; ** ;; enotes/default-time-fields "9:30") +;; ** ;; +;; ** ;; (enotes/init) +;; ** ;; ) + +(when (ff/load-or-alert "goto-last-change.el") + (define-key global-map [(control -)] 'goto-last-change) ) -;; (when (ff/load-or-alert "goto-last-change.el") -;; (define-key global-map [(control x) (control a)] 'goto-last-change)) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; My private stuff (email adresses, mail filters, etc.) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2682,15 +2993,15 @@ With argument ARG, do this that many times." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Runs in server mode, so that emacsclient works -(server-start) +;; ;;(server-start) -(defun ff/raise-frame-and-give-focus () - (when window-system - (raise-frame) - (x-focus-frame (selected-frame)) - (set-mouse-pixel-position (selected-frame) 4 4) - )) +;; (defun ff/raise-frame-and-give-focus () + ;; (when window-system + ;; (raise-frame) + ;; (x-focus-frame (selected-frame)) + ;; (set-mouse-pixel-position (selected-frame) 4 4) + ;; )) -;; Raises the window when the server is invoked +;; ;; Raises the window when the server is invoked -(add-hook 'server-switch-hook 'ff/raise-frame-and-give-focus) +;; (add-hook 'server-switch-hook 'ff/raise-frame-and-give-focus)