* Macros in dired - Is it possible?
@ 2009-07-17 18:41 zeek peters
0 siblings, 0 replies; 8+ messages in thread
From: zeek peters @ 2009-07-17 18:41 UTC (permalink / raw)
To: help-gnu-emacs
[-- Attachment #1: Type: text/plain, Size: 1637 bytes --]
[ *Question* ]
Is it possible to mark files in dired and then run a macro on all
the selected files?
[ *Background* ]
The macro finds and deletes certain portions/paragraphs from text
files to cut them down in size so that I can read them easier and quicker.
But I am getting tired of loading one file at a time into Emacs to
run the macro ( via ^u 0 MX macro1 ). I do this about 100x/day. So is there
a
quicker/better way to run a macro en mass?
[ *What I Have Tried, but Hasn't Worked* ]
As an example
1. I load 10 text files into emacs, thus creating 10 separate
buffers.
2. Then tried creating another macro that calls the first macro,
and also saves the edited and much smaller file, and then kills the buffer
3. So, for 10 files, I would call macro2 via [ ^u 10 Mx macro2 ]
4. The problem, I am having is that the 2nd macro doesn't record
the save or the kill. So, I tried to edit the saved macro2 via [
Mx edit-named-k TAB RET macro2 ]. I add the commands [ ^x ^s ]
and [ ^x k RET ], and do a [ c ^c ]. The changes are saved, but
when I try again, the 2nd macro calls macro1 to do its magic, but
the modifications aren't saved, nor is the buffer killed. So,
only one of the 10 files files has been modified.
[ *What I have learned* ]
A lot, since I am a completely new to this. Learned a little bit about Git,
compiling, Org-mode. Currently, reading the both manuals ( emacs
and Lisp how2 ).
I'm looking forward to learning more, but starting to get a bit
frustated. Hope you could offer some insight/assistance. Thanks
[ *Info* ]
emacs-snapshot ( GNU Emacs 23.0.95.1 (i486-pc-linux-gnu, GTK+
Version 2.16.4) of 2009-07-03
[-- Attachment #2: Type: text/html, Size: 1785 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Macros in dired - Is it possible?
[not found] <mailman.2744.1247896840.2239.help-gnu-emacs@gnu.org>
@ 2009-07-18 9:14 ` Xah Lee
2009-07-18 17:19 ` zeek
2009-07-18 21:02 ` muede
2009-07-18 21:08 ` Anselm Helbig
2 siblings, 1 reply; 8+ messages in thread
From: Xah Lee @ 2009-07-18 9:14 UTC (permalink / raw)
To: help-gnu-emacs
On Jul 17, 11:41 am, zeek peters <zp1z...@gmail.com> wrote:
> [ *Question* ]
> Is it possible to mark files in dired and then run a macro on all
> the selected files?
>
> [ *Background* ]
> The macro finds and deletes certain portions/paragraphs from text
> files to cut them down in size so that I can read them easier and quicker.
>
> But I am getting tired of loading one file at a time into Emacs to
> run the macro ( via ^u 0 MX macro1 ). I do this about 100x/day. So is there
> a
> quicker/better way to run a macro en mass?
>
> [ *What I Have Tried, but Hasn't Worked* ]
> As an example
> 1. I load 10 text files into emacs, thus creating 10 separate
> buffers.
> 2. Then tried creating another macro that calls the first macro,
> and also saves the edited and much smaller file, and then kills the buffer
> 3. So, for 10 files, I would call macro2 via [ ^u 10 Mx macro2 ]
> 4. The problem, I am having is that the 2nd macro doesn't record
> the save or the kill. So, I tried to edit the saved macro2 via [
> Mx edit-named-k TAB RET macro2 ]. I add the commands [ ^x ^s ]
> and [ ^x k RET ], and do a [ c ^c ]. The changes are saved, but
> when I try again, the 2nd macro calls macro1 to do its magic, but
> the modifications aren't saved, nor is the buffer killed. So,
> only one of the 10 files files has been modified.
>
> [ *What I have learned* ]
> A lot, since I am a completely new to this. Learned a little bit about Git,
> compiling, Org-mode. Currently, reading the both manuals ( emacs
> and Lisp how2 ).
>
> I'm looking forward to learning more, but starting to get a bit
> frustated. Hope you could offer some insight/assistance. Thanks
>
> [ *Info* ]
> emacs-snapshot ( GNU Emacs 23.0.95.1 (i486-pc-linux-gnu, GTK+
> Version 2.16.4) of 2009-07-03
seems what you wanted certainly can be done. But it is very unclear to
me exactly what you want to be done.
can you give description in terms of what you watn to do exactly?
e.g.
which files you want to process? are they all html files? files with
certain line? etc?
what do you want to do to each file? delete certain lines, then save?
what text pattern does the line needs to match? etc.
kbd macros are typically one session use only. they are not meant to
be edited, and they are pretty unreadable. They simply are record of
keystrokes. In your case, of calling kbd macros on kbd macros, is
probably much simpler having a elisp function.
Xah
∑ http://xahlee.org/
☄
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Macros in dired - Is it possible?
2009-07-18 9:14 ` Macros in dired - Is it possible? Xah Lee
@ 2009-07-18 17:19 ` zeek
2009-07-18 21:10 ` Anselm Helbig
0 siblings, 1 reply; 8+ messages in thread
From: zeek @ 2009-07-18 17:19 UTC (permalink / raw)
To: help-gnu-emacs
> can you give description in terms of what you watn to do exactly?
> e.g.
> which files you want to process? are they all html files? files with
> certain line? etc?
First, thank you for replying.
Sorry for the confusion, simplified it too much. Let me try again
60% of all the files are just plain text files
40% are html files
I have 2 macros: one for plain text files and another for html files
a) The macro for the plain text files looks for certain individual
words, and then tries to delete the paragraph that contains that word
(actually, it just deletes the line that contains the words and the
line above and the line below it (as you astutely surmised). I would
like it to delete paragraphs, but this is the best I could do.
b) The macro for the html files looks for the same certain words, and
then deletes everything between these two tags: <file> and </file>
Then, I manually save the file so that I can read the text and html
versions later on in the day. Generally, for the text files, the size
gets reduced by about 20-50%.
Why am I doing this? Over the years I have learned that certain
individuals take for ever to get to the point, and that when these
individuals use certain words or phrases, the entire paragraph
containing those words/phrases is just bla, bla, bla. So the macro
just deletes them for me before I read them.
Do the paragraphs that get deleted contain information that I am
interested in knowing about? Yes, but very rarely. So far it has
never been a problem.
So I do the following for every file from these certain individuals:
Open the file in a buffer
Type C-u 0 M-x macro.name RET
Manually save the file.
Kill the buffer
Now, do the exact same thing for the next file, and the next, and the
next, etc
What would be nice is to just do this one time. So I was thinking
would it be possible to mark all the text files in dired and run the
macro on all the marked files?
The macros run ok, but I have to manually save the file and manually
kill the buffer before moving on to the next file. I could never get
the macros to save and the kill the buffer for me, so that is why I am
saving and killing the buffer manually.
Both macros (the one for the text files and the one for the html
files) are saved in Lisp code in my .emacs file.
>
> what do you want to do to each file? delete certain lines, then save?
> what text pattern does the line needs to match? etc.
>
For text files, delete every paragraph that contains those certain
words and save the file
For html files, delete everything between the two tags: <file> </file>
and save the file
Example of word searched for: "vacation"
Example of phrase searched for "when I was"
These are not the actual words/phrases that I search for, but does get
the point across. I search for 6 words and 1 phrase.
> kbd macros are typically one session use only. they are not meant to
> be edited, and they are pretty unreadable. They simply are record of
> keystrokes. In your case, of calling kbd macros on kbd macros, is
> probably much simpler having a elisp function.
>
Oh, I see, that is why you are asking for the pattern to match. Never
thought of a function. Don't know how to do that yet. Not there yet
in the Emacs Lisp tutorial.
Snippet of html macro via M-x edit-named-kbd-macro
--------------------------------
3*<C-home> ;; beginning-of-buffer
C-s ;; isearch-forward
v ;; self-insert-command
a ;; self-insert-command
c ;; self-insert-command
a ;; self-insert-command
t ;; self-insert-command
i ;; self-insert-command
o ;; self-insert-command
n ;; self-insert-command
RET ;; org-return
C-c C-b ;; outline-backward-same-level
C-SPC ;; set-mark-command
C-c C-f ;; outline-forward-same-level
C-w ;; kill-region
C-d ;; delete-char
C-a ;; org-beginning-of-line
--------------------------------
Cheers
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Macros in dired - Is it possible?
[not found] <mailman.2744.1247896840.2239.help-gnu-emacs@gnu.org>
2009-07-18 9:14 ` Macros in dired - Is it possible? Xah Lee
@ 2009-07-18 21:02 ` muede
2009-07-18 21:08 ` Anselm Helbig
2 siblings, 0 replies; 8+ messages in thread
From: muede @ 2009-07-18 21:02 UTC (permalink / raw)
To: help-gnu-emacs
On Jul 17, 8:41 pm, zeek peters <zp1z...@gmail.com> wrote:
> [ *Question* ]
> Is it possible to mark files in dired and then run a macro on all
> the selected files?
>
You could write a function like this one.
(defun dired-do-apply-form (form &optional arg)
(interactive "xApply form: \nP")
(save-window-excursion
(dolist (f (dired-get-marked-files
nil arg 'dired-nondirectory-p))
(let ((visiting-p (find-buffer-visiting f))
(buffer (find-file f)))
(condition-case nil
(eval form)
(error))
(unless (or visiting-p
;; form may have killed the buffer
(not (buffer-live-p buffer)))
(with-current-buffer buffer
(save-buffer)
(kill-this-buffer)))))))
Mark some files in a dired buffer, then
M-x dired-do-apply-form RET
(kmacro-call-macro 0) RET
to run the last macro till an error occurs
on each file.
-ap
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Macros in dired - Is it possible?
[not found] <mailman.2744.1247896840.2239.help-gnu-emacs@gnu.org>
2009-07-18 9:14 ` Macros in dired - Is it possible? Xah Lee
2009-07-18 21:02 ` muede
@ 2009-07-18 21:08 ` Anselm Helbig
2009-07-19 2:29 ` zeek
2 siblings, 1 reply; 8+ messages in thread
From: Anselm Helbig @ 2009-07-18 21:08 UTC (permalink / raw)
To: help-gnu-emacs
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2716 bytes --]
Hi!
> [ *Question* ]
> Is it possible to mark files in dired and then run a macro on all
> the selected files?
>
> [ *Background* ]
> The macro finds and deletes certain portions/paragraphs from text
> files to cut them down in size so that I can read them easier and quicker.
>
> But I am getting tired of loading one file at a time into Emacs to
> run the macro ( via ^u 0 MX macro1 ). I do this about 100x/day. So is there a
> quicker/better way to run a macro en mass?
>
> [ *What I Have Tried, but Hasn't Worked* ]
> As an example
> 1. I load 10 text files into emacs, thus creating 10 separate
> buffers.
> 2. Then tried creating another macro that calls the first macro,
> and also saves the edited and much smaller file, and then kills the buffer
> 3. So, for 10 files, I would call macro2 via [ ^u 10 Mx macro2 ]
> 4. The problem, I am having is that the 2nd macro doesn't record
> the save or the kill. So, I tried to edit the saved macro2 via [
> Mx edit-named-k TAB RET macro2 ]. I add the commands [ ^x ^s ]
> and [ ^x k RET ], and do a [ c ^c ]. The changes are saved, but
> when I try again, the 2nd macro calls macro1 to do its magic, but
> the modifications aren't saved, nor is the buffer killed. So,
> only one of the 10 files files has been modified.
I didn't do any experiments myself, but I guess what happens is this:
- You're executing your text-mangling macro in a buffer with a
numeric prefix argument, a large number, larger than the number of
times your macro actually needs to get called.
- At the end of the buffer, your macro beeps (i.e., signals an
error) and finishes.
- When you record your second macro, the macro definition is aborted
because your first macro beeps. This makes sense, sort of, since a
beep signals an error. Therefore, the macro definition never comes
to the point where you save and then kill your buffer
- Even when you add these commands manually, they are never executed
because the beep comes first.
This is a bit unfortunate. I can't think of a solution that doesn't
include some programming, replacing either one of the macros with a
bit of elisp code. Replacing the outer macro could look like this
(assuming that you named your keyboard macro `foo'):
(defun dired-foo-marked-files ()
(interactive)
(mapc (lambda (file)
(find-file file)
(goto-char (point-min))
(condition-case nil
(dotimes (i 100)
(execute-kbd-macro 'foo))
(error nil))
(save-buffer)
(kill-buffer))
(dired-get-marked-files)))
HTH,
Anselm
--
Anselm Helbig
mailto:anselm.helbig+news2009@googlemail.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Macros in dired - Is it possible?
2009-07-18 17:19 ` zeek
@ 2009-07-18 21:10 ` Anselm Helbig
0 siblings, 0 replies; 8+ messages in thread
From: Anselm Helbig @ 2009-07-18 21:10 UTC (permalink / raw)
To: help-gnu-emacs
Hi!
> (actually, it just deletes the line that contains the words and the
> line above and the line below it (as you astutely surmised). I would
> like it to delete paragraphs, but this is the best I could do.
M-h runs the command mark-paragraph, which is an interactive compiled
Lisp function in `paragraphs.el'.
HTH,
Anselm
--
Anselm Helbig
mailto:anselm.helbig+news2009@googlemail.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Macros in dired - Is it possible?
2009-07-18 21:08 ` Anselm Helbig
@ 2009-07-19 2:29 ` zeek
2009-07-19 16:04 ` Xah Lee
0 siblings, 1 reply; 8+ messages in thread
From: zeek @ 2009-07-19 2:29 UTC (permalink / raw)
To: help-gnu-emacs
Thank you Anselm Helbig and Muede for the functions
Looking forward to trying them out. Already learning more Lisp. There
is no way I could have come up with them.
Now I understand why I couldn't get the macros to save & kill the
buffer - makes sense. Well written.
Thank you again for responding so quickly with your solutions.
Cheers
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Macros in dired - Is it possible?
2009-07-19 2:29 ` zeek
@ 2009-07-19 16:04 ` Xah Lee
0 siblings, 0 replies; 8+ messages in thread
From: Xah Lee @ 2009-07-19 16:04 UTC (permalink / raw)
To: help-gnu-emacs
On Jul 18, 7:29 pm, zeek <zp1z...@gmail.com> wrote:
> Thank you Anselm Helbig and Muede for the functions
>
> Looking forward to trying them out. Already learning more Lisp. There
> is no way I could have come up with them.
>
> Now I understand why I couldn't get the macros to save & kill the
> buffer - makes sense. Well written.
>
> Thank you again for responding so quickly with your solutions.
>
> Cheers
To apply a function to marked files in dired, use “dired-get-marked-
files”, like this:
;; idiom for processing a list of files in dired's marked files
;; suppose myProcessFile is your function that takes a file path
;; and do some processing on the file
(defun dired-myProcessFile ()
"apply myProcessFile function to marked files in dired."
(interactive)
(require 'dired)
(mapc 'myProcessFile (dired-get-marked-files))
)
See:
• Emacs Lisp Idioms
http://xahlee.org/emacs/elisp_idioms.html
you just need to write the myProcessFile function ... it's pretty easy
to do what you want. The function should open the file, use search-
forward to move cursor to the place of the word, then delete that
paragraph, repeat, then save the file. I'd say this code would be less
than 20 or 30 lines, and will take (me) about 20 min.
Xah
∑ http://xahlee.org/
☄
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-07-19 16:04 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <mailman.2744.1247896840.2239.help-gnu-emacs@gnu.org>
2009-07-18 9:14 ` Macros in dired - Is it possible? Xah Lee
2009-07-18 17:19 ` zeek
2009-07-18 21:10 ` Anselm Helbig
2009-07-18 21:02 ` muede
2009-07-18 21:08 ` Anselm Helbig
2009-07-19 2:29 ` zeek
2009-07-19 16:04 ` Xah Lee
2009-07-17 18:41 zeek peters
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).