How can you generate a dynamic "Reply-To:" (and "From:") header in emacs/gnus based on Message-ID of the created message? I would like to use external (perl) script to generate a dynamic +detail part based on the "Messaged-ID:" header.
user+detail#example.net
I have managed to create a header with content generated by my external script. The script gets usenet group name as command line parameter. I would like to pass it the message-id value too.
My current code
~/.emacs :
'(gnus-posting-styles ("^pl\\.test$" ("Reply-To" message-make-reply-to)))
~/.gnus
(defun message-make-reply-to()
(my-script ".../reply-to.pl" (message-fetch-field "Message-Id")))
(defun my-script(path &optional param) ....
The problem: the script does not receive message-id as its parameter (my-script gets correctly explicitly set parameter)
;; Make sure the Message-ID header is present in newly created messages
(setq message-generate-headers-first '(Message-ID))
;; Prevent emacs from resetting the Message-ID before the message is sent.
(setq message-deletable-headers
(remove 'Message-ID message-deletable-headers))
(setq gnus-posting-styles
'(("^pl\\.test$"
("Reply-To" '(message-make-reply-to)))))
Note the additional quote and parentheses around message-make-reply-to. The explanation for this is that the function is run at different times, depending on whether it's given as a symbol or as a quoted s-expression.
If given as symbol, it is run when a lambda function is added to message-setup-hook. That happens in a message-mode-hook, i.e. right after the new buffer is created and switched into message-mode. The cause for this is some wild quoting/unquoting of values during creation of the lambda function.
If given as a quoted sexpr, evaluation is delayed until after the buffer is filled with initial values. It is close to the last code which is run on message setup.
Alternative Solution (without gnus-posting-styles)
In cases where the new header should be added to every new message, the Reply-To header can also be set using the message-header-setup-hook. A custom hook needs to be defined to add the header for each new message.
(defun reply-to-message-header-setup-hook ()
(let* ((msg-id (message-fetch-field "Message-ID"))
(reply-to (my-script ".../reply-to-pl" msg-id)))
(message-add-header (concat "Reply-To: " reply-to))))
;; Call the hook every time a new message is created
(add-hook 'message-header-setup-hook 'reply-to-message-header-setup-hook)
;; Make sure the Message-ID header is present in newly created messages
(setq message-generate-headers-first '(Message-ID))
Related
I'm looking to build a capture template that, when run, prompts the user for more information to determine the path of the target file.
I have a few pieces already.
A function which asks the user for data and returns a string:
(defun my/get-121-orgfile ()
"Ask the user for the name of the participant so that we can build"
(interactive)
(read-string "Participant Name: ")
)
An org-capture-template which will run the prompt successfully when emacs loads:
(setq org-capture-templates
`(
("m1" "1-1 meetings")
("m1b" "prep for a 1-1 meeting" entry
(file ,(concat "~/org/meetings/1-2-1/" (my/get-121-orgfile) ".org"))
(file "~/org/templates/meeting-121-prep.org")
:clock-in t)
))
I took the back quote and comma pattern from this SO answer, but I haven't been able to figure out how to scope this behaviour to when I select the template: I want the prompt to pop up each time I hit <org-capture>m1b.
The backquote-comma pattern will not help here: it will call the function at the time that org-capture-template is set. What you are trying to do is to call the function when the capture is executed.
The only way I know to do that would to use the (function foo) target mechanism of org-capture-templates. The doc string says:
(function function-finding-location)
Most general way: write your own function which both visits
the file and moves point to the right location
So you would not be able to use the (file ...) target as you do above. Instead you have to write a function that gets all the information you want and then visit the target file at the target location and add the filled-out template.
This is not a complete answer but it was too long for a comment, but maybe it helps to point you in the right direction.
I have a probably rather simply to solve (Auto-)LISP problem to solve. I have a script which works fine basically, but it requires me to manually select objects (texts in my case) and hit enter.
I want to select all text objects from all layers, and apply the same TCIRCLE operation on all of them. This command should later be applied with a script to automate imports, that's why there must be no manual interaction.
This is the working basic script which requires manual selection:
(defun c:MyTcircle ( / ss)
(if (not bns_tcircle) (load "acettxt.lsp"))
(if (setq ss (ssget '((0 . "TEXT,MTEXT,ATTDEF"))))
(bns_tcircle ss "Variable" "Rectangles" "" 0.35)
)
(princ)
)
I've tried to create a filter collection with setq sset for the same type filters as above. But it doesn't do anything (no error but also no changes). So either my collection is empty, or the command isn't called right.
I'm new to AutoLisp, what am I missing that it doesn't work as expected on the filtered items?
You need to add a filter to your selection set. Simply adding a comma between the different entity types just gives you a malformed entity.
Take a look here for some information to get you started: http://www.afralisp.net/autolisp/tutorials/selection-set-filters.php
I am using gdb under emacs. During a debug session, when emacs/gdb jumps to source code i usually open up another frame (C-x 5 2) and pull that onto my second monitor.
The problem comes when a new source code file needs to be opened (for example when the program enters a function defined in another source file, walking the stack, etc ...) emacs tends to automatically open up the corresponding source code in a new window, but unfortunately in the gdb frame.
I would like for it pull up new source code in the new frame i opened up and leave the gdb frame completely untouched. My question then is this:
How can i set emacs to open up any new file such that the file is displayed in the new frame?
I hope i am making sense.
Not a simple answer, but an appropriate entry in display-buffer-alist could tell display-buffer to always use the frame you want as the destination for new buffers.
In 24.1, the doc is:
display-buffer-alist is a variable defined in `window.el'. Its value
is nil
This variable may be risky if used as a file-local variable.
Documentation: Alist of conditional actions for `display-buffer'. This
is a list of elements (CONDITION . ACTION), where:
CONDITION is either a regexp matching buffer names, or a function
that takes two arguments - a buffer name and the ACTION argument of
`display-buffer' - and returns a boolean.
ACTION is a cons cell (FUNCTION . ALIST), where FUNCTION is a
function or a list of functions. Each such function should accept
two arguments: a buffer to display and an alist of the same form as
ALIST. See `display-buffer' for details.
`display-buffer' scans this alist until it either finds a matching
regular expression or the function specified by a condition returns
non-nil. In any of these cases, it adds the associated action to the
list of actions it will try.
You can customize this variable.
This variable was introduced, or its default value was changed, in
version 24.1 of Emacs.
Let's say I want to create a new document, and cycle quickly through a list.
If it's only for one "word", I think there should be a general way to do this.
For instance:
"blue orange red yellow black white"
Does anyone know a way how to cycle through those items when I create:
\begin{orange}
... and I want to press a key to cycle through this list, replacing orange with the next item on the list (doing this procedure in the opposite direction wouldn't be hard then)?
I tried many different ideas with macro's (placing the list on the top of the document, and doing a whole bunch of i-searches), but that doesn't cut it.
I'd be willing to put the list in an elisp file, though I have no clue how to use that variable from elisp in, let's say, a LaTeX document (.tex).
Well, this might be possible, but depends on how much effort you are willing to put into writing eLisp code to make it work. It's not possible by just some configuration option. I would be looking into extending autocomplete by adding new sources to it, something like:
(defvar tex-tag-ac-sources
'((init . tex-tag-ac-init)
(requires . 0)
(candidates . tex-tag-ac-candidates)
(document . tex-tag-ac-documentation)
(match . tex-tag-completion-filter)
(prefix . tex-tag-ac-prefix-matcher)
(symbol . "s"))
"The source generator for autocompletion needed for interaction
with auto-complete")
Where tex-tag-ac-candidates, tex-tag-ac-documentation, tex-tag-completion-filter and tex-tag-ac-prefix-matcher are function that do autocompletion. I.e. init function is called once when the autocompletion process starts for a specified prefix. It's called w/o arguments. The candidates is the function that is responsible for showing the filtered list of candidates, it's called w/o arguments, you would filter the candidates in the filter function, it is called with the prefix collected so far and the list of candidates so far. Lastly, the matcher function is invoked on the text of the file to see if the completion is needed at point. So, if it returns t, the init is called, and then loops through filter-candidates as you type.
While this is a bit involved... you'd definitely have a completion for anything you want. Obviously, if those functions in source are defined by you, then, if you wanted to, you could read completion arguments dynamically or have them generated dynamically in some way.
Ah, you would add the sources to autocomplete by something like:
(auto-complete (list tex-tag-ac-sources))
if doing it on per call basis, or
(setq ac-sources (list tex-tag-ac-sources <other sources>))
You can find more info here: http://cx4a.org/software/auto-complete/manual.html#Using_Source
EDIT: I translated the macro into a function.
Here is a way I did it. I created a file called "list.list" where my "lists" are saved. I saved the LaTeX templates for Beamer in there. I inserted them like this:
Antibes Bergen Berkeley Berlin ..... Antibes
Note that you should always put the first entry in twice to allow it to loop.
Here is the code:
(defun cycle-list-word ()
(interactive)
(right-word)
(backward-kill-word 1)
(find-file "/emacs-24.1/list.list")
(search-forward (substring-no-properties (car kill-ring)) nil t)
(right-word)
(backward-kill-word 1)
(bury-buffer)
(yank)
)
I have a HTML page, with html-mode enabled. I call function sgml-validate to check for any markup errors. It's based on compilation-mode. I want to remove some warnings from the compilation output, so I wrote a function and hooked it to compilation-filter-hook (this variable is not documented, but compilation-filter invokes it). Everything works. My problem is that how can I ensure my filter function only gets called when I started the compilation process on a HTML page (via sgml-validate)?
I see two methods, but none of them worked:
First, I can check the value of major-mode. But it always returns compilation-mode, since that is enabled on the *compilation* buffer. (I found a filter function in the source code of grep+, and they did check the value of major-mode. I can't figure out how can it work correctly.)
The other idea was than to only hook my filter function to the HTML file's buffer, but for similar reasons it couldn't work as the output of compilation process goes to a seperate buffer.
It sounds like you can advise smgl-validate so that it performs the filtering before it performs all it's other operations. For example:
(defadvice sgml-validate (around fix-filtering command activate)
(let ((return-value ad-do-it))
(filter-function return-value))))
Meanwhile, I found that compilation-start accepts an optional argument mode, which will be the major mode for the compilation buffer. So I can create a major mode derived from compilation-mode, and define there my filter function now hooked to the proper buffer.
The only problem is now that sgml-validate does not allow me to set the mode argument on compilation-start, but that's another question.
(I don't consider this the ultimate solution, of course.)