Default Archive Group in Gnus - emacs

I am using the following code to archive replies to messages in the same group they come from; it works well.
;; Store sent messages in the same group they came from
(setq gnus-message-archive-method '(nnml ""))
(setq gnus-message-archive-group
'((lambda (x)
(cond
;; Store personal mail messages in the same group I started out in
((string-match ".*" group) group)
;; Store everything else in misc until I can sort it out
(t "mail.misc")))))
However, if I use C-x m from a non-GNUs buffer, or create a message without a group selected, there seems to be no archiving at all; the message is lost unless I manually fill in a GCC: mail.misc line. How can I make this happen automatically for all messages not made from within a group?

First you have to set gnus as mail handler.
(setq mail-user-agent 'gnus-user-agent)
Still this doesn't work, if gnus is not running when starting to
write a mail with C-x m. Here a advice helps.
(defadvice gnus-msg-mail (before start-gnus activate)
(require 'gnus-start)
(unless (gnus-alive-p)
(save-window-excursion
(let ((inhibit-redisplay t))
(gnus)))))

Related

How to combine winner and workgroups?

I use many workgroups in my workflow (package workgroups or workgroups2). If I switch to some workgroup and try to winner-undo I get window configuration from previous workgroup.
Can I use separate winner-undo history for each workgroup?
I've just pushed a commit in workgroups2.
Now winner-undo, winner-redo commands are remapped to workgroups' commands which do the same thing as winner but for each workgroup.
Upd. When I tested workgroups2 undo functionality last time, I made a mistake and misunderstood the behaviour of wg-undo-wconfig-change (wg-redo-wconfig-change). So, workgroups2 just has the ability to save the history of each workgroup like winner-mode does it. This solution can be used for workgroups package only.
I wrote this:
(defvar wg-winner-vars nil)
(defvar wg-winner-hash nil)
(setq wg-winner-vars '(winner-ring-alist
winner-currents
winner-point-alist
winner-undone-data
winner-undo-counter
winner-pending-undo-ring))
(setq wg-winner-hash (make-hash-table :test 'equal))
(defun wg-winner-put (winner-name)
(let ((wg (ignore-errors (wg-name (wg-current-workgroup)))))
(if wg
(puthash (list wg winner-name) (eval winner-name) wg-winner-hash))))
(defun wg-winner-get (winner-name)
(let ((wg (ignore-errors (wg-name (wg-current-workgroup)))))
(if wg
(eval `(setq ,winner-name (gethash '(,wg ,winner-name) wg-winner-hash))))))
(defun wg-winner-save ()
(if winner-mode
(progn
(winner-mode -1)
(defun wg-winner-mode-restore ()
(winner-mode 1)))
(defun wg-winner-mode-restore ()))
(mapcar 'wg-winner-put wg-winner-vars))
(defun wg-winner-load ()
(mapcar 'wg-winner-get wg-winner-vars)
(wg-winner-mode-restore))
(defadvice wg-switch-to-workgroup (before wg-winner-before activate)
(wg-winner-save))
(defadvice wg-switch-to-workgroup (after wg-winner-after activate)
(wg-winner-load))
If you're happy to write the elisp:
winner-ring-alist is an alist of window configuration rings keyed by frame (i.e. a ring of window configs per frame).
I would suggest you define a new alist keyed by frame and by the workgroup identifier (whatever that is), in which you can store the workgroup-specific winner config ring for each frame.
I imagine there's a "switch workgroup" hook you can then use to write the current frame's config ring to your alist (for the workgroup you're switching from), and then replace the ring for the current frame with your stored config for the workground you're switching to.
There's probably not much more to it. As long as winner sees the data it needs, it'll probably "just work".
If it works nicely, consider contributing the code back to the workgroups project.

Insert current entry into BBDB

I've read that "The easiest way to insert an entry for a person into BBDB is to press : (colon) in the Summary buffer when a message from him is the selected one. If the person is in the database already, nothing happens; otherwise, Emacs asks you if you want to insert him into the database."
That does not work for me, I guess because I'm using BBDB 3.
EDIT: ':' runs the command 'bbdb-mua-display-sender'.
Is there a workaround to this?
This is what I use in my .emacs to work with BBDB-3 in Gnus, it will give this functionality to the ; key:
(require 'bbdb-autoloads)
(require 'bbdb)
;; initialization
(bbdb-initialize 'gnus 'message)
(bbdb-mua-auto-update-init 'gnus 'message)
;; size of the bbdb popup
(setq bbdb-pop-up-window-size 0.15)
(setq bbdb-mua-pop-up-window-size 0.15)
;; What do we do when invoking bbdb interactively
(setq bbdb-mua-update-interactive-p '(query . create))
;; Make sure we look at every address in a message and not only the
;; first one
(setq bbdb-message-all-addresses t)
;; use ; on a message to invoke bbdb interactively
(add-hook
'gnus-summary-mode-hook
(lambda ()
(define-key gnus-summary-mode-map (kbd ";") 'bbdb-mua-edit-field)))
I got this information from somewhere on the net, but can't quite locate where just now; maybe this can set you on the correct path?

Refactoring in Emacs

I am working on splitting code into smaller files and refactoring it a bit. Consider the following code below as the section I want to extract:
(require 'package)
(add-to-list 'package-archives
'("marmalade" . "http://marmalade-repo.org/packages/") t)
(package-initialize)
(when (not package-archive-contents)
(package-refresh-contents))
(defvar my-packages '(org magit)
"A list of packages to ensure are installed at launch.")
(dolist (p my-packages)
(when (not (package-installed-p p))
(package-install p)))
I want to take the section above and replace it with something like (require `file-name)
Then take the text replaced and place that in a new file in the current directory named file-name.el
And then add a line to the top of the file (provides `file-name)
It would be great if I could hit a keychord and then type a name and have this happen. If there is an easy way to do this then I would love to hear possible solutions.
Edit:
I'm starting a bounty because I think this applies to more types of code than Lisp and I would like to have something a little more general that I can expand upon.
I have considered yasnippet but I don't think it's powerful enough to perform the task at hand. Basically the ideal workflow would be marking the lines to be extracted, replacing that with an appropriate require or include directive and sending the text off to it's own file. Ideally one command and something that is aware of the type of file being edited or at least the major mode so the behavior can be customized, again yasnippet is good at performing different tasks when editing in different major modes however I would have no idea how to make that work or evaluate the possibility of making it work.
Let me know if you need any more information.
A general solution to this type of problem are keyboard macros (not to be confused with (Emacs) LISP macros). Basically Emacs allows you to record a sequence of keystrokes and "play them back" afterwards. This can be a very handy tool in situations where writing custom LISP code seems overkill.
For instance you could create the following keyboard macro (type the key combinations on the left hand side, the right hand side shows explanations for each key stroke):
C-x ( ; start recording a keyboard macro
C-x h ; mark whole buffer
C-w ; kill region
(require 'file-name) ; insert a require statement into the buffer
C-x C-s ; save buffer
C-x C-f ; find file
file-name.el <RET> ; specify the name of the file
M-< ; move to the beginning of the buffer
C-u C-y ; insert the previously killed text, leaving point where it is
(provide 'file-name) <RET> <RET> ; insert a provide statement into the buffer
C-x ) ; stop recording the keyboard macro
Now you can re-play that macro in some other buffer by typing C-x e, or save it for later use. You can also bind a macro to a shortcut just like a function.
However, there is one weakness with this approach: you want to be able to actually specify the file-name, and not just use the string "file-name" every time. That is a bit difficult - by default, keyboard macros provide no general facility for querying the user (except the very minimal C-x q, as documented here).
The Emacs Wiki has some work-arounds for that, however, instead of prompting the user in the minibuffer, it can sometimes be sufficient to start the macro by killing the current line and saving its text to a register.
C-x (
C-e C-<SPC> C-a ; mark current line
C-x r s T ; copy line to register T
C-k C-k ; kill current line
... ; actual macro
C-x )
Now when you want to use your macro, you would first write the desired file-name in an otherwise empty line, and then do C-x e in that line. Whenever the value of the file-name is needed in the macro you can retrieve it from the register T:
C-x r i T ; insert file-name into buffer
For instance, for the provide statement in the above macro, you could write: (provide ' C-x r i T ). Note that this technique (inserting) also works in the minibuffer, and of course you could save multiple lines to different registers.
May sound complicated, but is actually quite easy in practice.
Slightly tested:
(defun extract-to-package (name start end)
(interactive (list (read-string "Package name to create: ")
(region-beginning) (region-end)))
(let ((snip (buffer-substring start end)))
(delete-region start end)
(insert (format "(require '%s)\n" name))
(with-current-buffer (find-file-noselect (concat name ".el"))
(insert snip)
(insert (format "(provide '%s)\n" name))
(save-buffer))))
For a such thing I use the following snippet (with yasnippet):
;; `(buffer-name)`
;; Copyright (C) `(format-time-string "%Y")` name
;; Author: name <email>
;; This program is free software: you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation, either version 3 of
;; the License, or (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
$0
(provide '`(subseq (buffer-name) 0 (- (length (buffer-name)) 3))`)
1st create the file C-xC-ffile-name.elRET
then insert the snippet with C-c&C-s
and add any piece of code you wish.
I've also the following hook:
(add-hook 'after-save-hook 'autocompile)
(defun autocompile ()
"Byte compile an elisp."
(interactive)
(require 'bytecomp)
(let ((filename (buffer-file-name)))
(if (string-match "\\.el$" filename)
(byte-compile-file filename))))
to produce an .elc whenever I save a .el.
(defun region-to-file+require (beg end file append)
"Move region text to FILE, and replace it with `(require 'FEATURE)'.
You are prompted for FILE, the name of an Emacs-Lisp file. If FILE
does not yet exist then it is created.
With a prefix argument, the region text is appended to existing FILE.
FEATURE is the relative name of FILE, minus the extension `.el'."
(interactive "#*r\nG\nP")
(when (string= (expand-file-name (buffer-file-name)) (expand-file-name file))
(error "Same file as current"))
(unless (string-match-p ".+[.]el$" file)
(error "File extension must be `.el' (Emacs-Lisp file)"))
(unless (or (region-active-p)
(y-or-n-p "Region is not active. Use it anyway? "))
(error "OK, canceled"))
(unless (> (region-end) (region-beginning)) (error "Region is empty"))
(unless (or (not append)
(and (file-exists-p file) (file-readable-p file))
(y-or-n-p (format "File `%s' does not exist. Create it? " file)))
(error "OK, canceled"))
(write-region beg end file append nil nil (not append))
(delete-region beg end)
(let ((feature (and (string-match "\\(.+\\)[.]el$" file)
(match-string 1 file))))
(when feature
(insert (format "(require '%s)\n" feature)))))

Gnus: How to force signature to be placed at the bottom/under quoted messages in replies?

I use Gnus 5.13 for emails (on Mac OS X 10.7.2 with emacs 24). I use the gnus-posting-styles entry (eval (set (make-local-variable 'message-cite-reply-position) 'above)) in order to place the point (cursor) on top of the message in replies. This allows me to either top-reply or to reply inline (between the message that I would like to reply to). Unfortunately, the above entry also puts my signature on top of the message I would like to reply to. That's okay if I want to top-reply, but it's wrong if I want to reply inline. How can I force the signature to be placed under the message I reply to?
Discarding the 'message-cite-reply-position' modification, I have added the following to my .gnus.el file, and now when replying to an e-mail or news post, first goes the yanked message, then my signature, and the point is placed at the beginning of the message.
(eval-after-load "gnus-msg"
'(defun gnus-inews-yank-articles (articles)
(let (beg article yank-string)
(message-goto-body)
(while (setq article (pop articles))
(when (listp article)
(setq yank-string (nth 1 article)
article (nth 0 article)))
(save-window-excursion
(set-buffer gnus-summary-buffer)
(gnus-summary-select-article nil nil nil article)
(gnus-summary-remove-process-mark article))
(gnus-copy-article-buffer nil yank-string)
(let ((message-reply-buffer gnus-article-copy)
(message-reply-headers
;; The headers are decoded.
(with-current-buffer gnus-article-copy
(save-restriction
(nnheader-narrow-to-headers)
(nnheader-parse-naked-head)))))
(message-yank-original)
(setq beg (or beg (mark t))))
(when articles
(insert "\n")))
(push-mark)
; (goto-char beg))) -- Original
(message-goto-body) ; -- Modified, so point will be moved to beginning of article
(insert "\n\n") ; -- and two empty lines will be added.
(message-goto-body)))) ; --

Emacs: reopen buffers from last session on startup?

Every day I start up emacs and open the exact same files I had open the day before. Is there something I can add to init.el file so it will reopen all the buffers I was using when I last quit emacs?
You can use the Emacs Desktop library:
You can save the desktop manually with
the command M-x desktop-save. You can
also enable automatic saving of the
desktop when you exit Emacs, and
automatic restoration of the last
saved desktop when Emacs starts: use
the Customization buffer (see Easy
Customization) to set
desktop-save-mode to t for future
sessions, or add this line in your
~/.emacs file:
(desktop-save-mode 1)
Although I suspect the question was looking for the emacs "desktop" functionality (see above answer), Lewap's approach can be useful if the set of files one uses really is the exact same file set. In fact, one can go a step further and define 'profiles' if one has different sets of regularly used files... Quickie example:
(let ((profile
(read-from-minibuffer "Choose a profile (acad,dist,lisp,comp,rpg): ")
))
(cond
((string-match "acad" profile)
(dired "/home/thomp/acad")
(dired "/home/thomp/acad/papers")
)
((string-match "lisp" profile)
(setup-slime)
(lisp-miscellany)
(open-lisp-dirs)
)
((string-match "rpg" profile)
(find-file "/home/thomp/comp/lisp/rp-geneval/README")
(dired "/home/thomp/comp/lisp/rp-geneval/rp-geneval")
... etc.
If you find that you regularly switch back and forth between different sets of regularly-used files as you work, consider using perspectives and populating each perspective with the desired set of regularly-used files.
For storing/restoring the buffers/tabs (specifically elscreen tabs): I use elscreen and the way I manage storing/restoring the desktop session and the elscreen tab configuration is the following code in my .emacs file (the names used are self-explanatory and if the storing/restoring functions should not be executed every time emacs starts just comment out the lines with "(push #'elscreen-store kill-emacs-hook)" and "(elscreen-restore)"):
(defvar emacs-configuration-directory
"~/.emacs.d/"
"The directory where the emacs configuration files are stored.")
(defvar elscreen-tab-configuration-store-filename
(concat emacs-configuration-directory ".elscreen")
"The file where the elscreen tab configuration is stored.")
(defun elscreen-store ()
"Store the elscreen tab configuration."
(interactive)
(if (desktop-save emacs-configuration-directory)
(with-temp-file elscreen-tab-configuration-store-filename
(insert (prin1-to-string (elscreen-get-screen-to-name-alist))))))
(push #'elscreen-store kill-emacs-hook)
(defun elscreen-restore ()
"Restore the elscreen tab configuration."
(interactive)
(if (desktop-read)
(let ((screens (reverse
(read
(with-temp-buffer
(insert-file-contents elscreen-tab-configuration-store-filename)
(buffer-string))))))
(while screens
(setq screen (car (car screens)))
(setq buffers (split-string (cdr (car screens)) ":"))
(if (eq screen 0)
(switch-to-buffer (car buffers))
(elscreen-find-and-goto-by-buffer (car buffers) t t))
(while (cdr buffers)
(switch-to-buffer-other-window (car (cdr buffers)))
(setq buffers (cdr buffers)))
(setq screens (cdr screens))))))
(elscreen-restore)
There are useful enhancements you can make to the basic desktop feature. Particular handy (IMO) are methods of auto-saving the desktop during the session, as otherwise if your system crashes you will be stuck with the desktop file you had started that session with -- pretty annoying if you tend to keep Emacs running for many days at a time.
http://www.emacswiki.org/emacs/DeskTop
The wiki also has useful information about persisting data between sessions in general:
http://www.emacswiki.org/emacs/SessionManagement
For desktops specifically, I thought that Desktop Recover looked particularly promising, however I've not yet tried it out.
(find-file-noselect "/my/file") will open it silently, ie w/o raising the buffer. Just saying.
EDIT This command is not interactive ; To test it you have to evaluate the expression, for example by positioning the cursor after the last parenthesis and hitting C-x C-e
Downvoting this is not cool ; this command definitely works and is in the scope of the question.