emacs
Note: some of the snippets in here I don't use any more, but are kept here for reference
One day, I might organize this better. But in the mean time…
Spam filtering in Gnus
I use spam.el
for spam filtering. I also want to whitelist everyone in
my BBDB address book, so I wrote the following functions:
(defun hc:gnus-spam-if-not-in-bbdb ()
"gnus fancy split function;
if the senders address is not in bbdb, check if spam"
(let ((who (or (message-fetch-field "from")
(message-fetch-field "sender")
(message-fetch-field "reply-to"))))
(if (string-match all-my-addresses-regexp who)
(spam-split)
(if (gnus-if-not-in-bbdb t)
(spam-split)))))
Note that I anti-whitelist my own addresses, using the
all-my-addresses-regexp
variable, because spammers sometimes make the
From:
header the same as the To:
header.
The gnus-if-not-in-bbdb
is based on a lisp recipe from
my.gnus.org that I am no longer able to locate,
and is defined as follows:
(defun gnus-if-not-in-bbdb (target)
"gnus fancy split function;
if the senders address is not in bbdb, return TARGET"
(let ((who (bbdb-canonicalize-address
(cadr (gnus-extract-address-components
(or (message-fetch-field "from")
(message-fetch-field "sender")
(message-fetch-field "reply-to")
"nobody@nowhere.nohow"
)))))
)
(unless (bbdb-search-simple nil who)
target
)
)
)
I use the SpamAssassin backend, so I have the following definitions. (I'm using spamc, communicating with spamd over a UNIX domain socket.)
(setq spam-use-spamassassin t)
(setq spam-split-group "spamkill")
(setq spam-spamassassin-path "spamc")
(setq spam-spamassassin-arguments '("-U" "/var/run/spamd_sock"))
(require 'spam)
(spam-initialize)
Gnus splitting and SpamAssassin
[DEPRECATED] spam.el
from gnus now supports SpamAssassin, so
this is no longer needed with recent versions of gnus.
You need to use fancy splitting for this.
Add this code to your .gnus
file:
(defun hc:fancy-split-spamassassin ()
(save-excursion
(set-buffer " *nnmail incoming*")
(call-process-region (point-min) (point-max) "spamc" t t nil "-f")
(goto-char (point-min))
(when (re-search-forward "^x-spam-flag: yes$" nil t) "spamkill")))
Then add a rule to your nnmail-split-fancy
variable:
(: hc:fancy-split-spamassassin)
Key bindings
Inspired by xkcd (but using Alt-mousewheel):
(global-set-key (kbd "<M-mouse-5>") 'undo)
(global-set-key (kbd "<M-mouse-4>") 'redo)
Match parentheses (e.g. on a close-paren, hit M-] to jump to the corresponding open-paren)
(global-set-key "\e[" 'forward-list)
(global-set-key "\e]" 'backward-list)
Cycle through windows with C-M-next (C-M-pgdn) and C-M-prior
(global-set-key [\C-\M-next] 'other-window)
(global-set-key [\C-\M-prior] (lambda nil (interactive) (other-window -1)))
Setting the mail server by my IP address
Since I'm on a laptop, my Internet connection changes, and so does my
SMTP server. So in my .emacs
, I check my IP address and set my SMTP
server. (Obviously, you'd need to tailor this to your own IP addresses)
(let ((address (shell-command-to-string "ifconfig eth0 | awk '/inet addr/{split($2,x,\":\");print x[2]}'")))
(cond ((string-match "^129\\.97\\." address)
;; UW
(setq message-send-mail-function 'smtpmail-send-it
send-mail-function 'smtpmail-send-it
smtpmail-default-smtp-server "mail.math.uwaterloo.ca"
smtpmail-smtp-server "mail.math.uwaterloo.ca"))
((string-equal "129.128.207.8\n" address)
;; U of A
(setq message-send-mail-function 'smtpmail-send-it
send-mail-function 'smtpmail-send-it
smtpmail-default-smtp-server "mailbox.math.ualberta.ca"
smtpmail-smtp-server "mailbox.math.ualberta.ca"))
;;((string-match "^24\\." address)
;; Rogers (in Waterloo) (their mail server uses AUTH SMTP - not
;; supported (yet) by Gnus)
;;(setq smtpmail-default-smtp-server "smtp.ktchnr.phub.net.cable.rogers.com")
;;(setq smtpmail-smtp-server "smtp.ktchnr.phub.net.cable.rogers.com"))
((string-match "^142\\." address)
;; Telus (in Edmonton)
(setq message-send-mail-function 'smtpmail-send-it
send-mail-function 'smtpmail-send-it
smtpmail-default-smtp-server "smtp.telusplanet.net"
smtpmail-smtp-server "smtp.telusplanet.net"))
(t
;; anywhere else -- send through UW's server over ssh
(setq message-send-mail-function 'feedmail-send-it
send-mail-function 'feedmail-send-it
feedmail-binmail-template "ssh hopper -e none /bin/mail %s"))))
Copying filenames from dired
Mark a bunch of files, and copy their filenames to the kill ring, and paste them into another buffer. I find it handy in eshell sometimes.
(defun my:dired-kill-ring-save-filenames (&optional arg)
"Puts all marked (or next ARG) filenames to the kill ring."
(interactive "P")
(kill-new (mapconcat
#'(lambda (x) x)
(dired-map-over-marks (dired-get-filename 'verbatim)
arg) " ")))
;; dired-find-file is already mapped to "e" and "<RET>", so we can remap
;; "f" to dired-show-file-type, and map "w" to
;; my:dired-kill-ring-save-filenames
(add-hook 'dired-load-hook #'(lambda ()
(define-key dired-mode-map "w"
'my:dired-kill-ring-save-filenames)
(define-key dired-mode-map "f"
'dired-show-file-type)))
HTTP requests
I occasionally need to paste the result of an HTTP request into a buffer.
(defun insert-from-url (url)
(interactive "MURL: ")
(let ((url-request-method "GET")
(dest (current-buffer))
(src (url-retrieve-synchronously url)))
(set-buffer src)
(goto-char (point-min))
(search-forward "\n\n")
(set-buffer dest)
(insert-buffer-substring src (match-end 0))))