https://github.com/abo-abo/make-it-so.git
git clone 'git://github.com/abo-abo/make-it-so.git'
GNU Emacs package for transforming files with Makefile recipes
Curry command line tools with Makefiles and select a Makefile to call
from dired
dispatching on selected files' extension.
I'm sure you've encountered your share of “How do I transform X to
Y?”-type questions on the web. I know I have. A lot of answers involve
using kitchen-sink tools like ffmpeg
or convert
. These tools are
great: they can transform almost anything into anything else. But
they come with a price of a gazillion switches that are hard to
remember (and to type in, for that matter).
This package solves this problem by moving the complex command to a Makefile with customizable literate parameters at the top. Additionally it catalogs all available Makefiles by the file extension that they work on. It also creates a Makefile template for you when a selected action doesn't exist.
You write the command only once. All the other times, you just customize the literate switches.
It's possible to not have to write the command at all if it's available in the repository.
Since the command is meant to be written just once, you can have a more complex and optimized command, compared to the one that you would normally enter in the terminal.
In case of multiple files, make
allows to use multiple cores
without the actual command knowing about it. This means that people
with different processors can use the same Makefile to the most
efficiency, calling make -j8
or make -j2
where appropriate.
The Elisp layer of this package solves the problem of Makefiles and file names with spaces.
Clone this repository:
$ cd ~/git/
$ git clone https://github.com/abo-abo/make-it-so
Add to .emacs
:
(add-to-list 'load-path "~/git/make-it-so")
(require 'make-it-so)
(setq mis-recipes-directory "~/git/make-it-so/recipes/")
(mis-config-default)
This method means that any Makefile that you create will be under version control.
If you install from MELPA, you only need this:
(mis-config-default)
However beware that your recipes will be in your package-user-dir
and will be wiped when you update the package. Which is fine if
you just want to give it a quick go or don't plan on creating your own
recipes. But if you do, move your recipes directory to a different place
and configure mis-recipes-directory
properly.
As a sample scenario, assume you want to trim (change running time) one or more *.ogv files.
So you navigate to their location with dired
and mark
them in case there's more than one.
Next, you call make-it-so
(bound to ,). It recognizes the “ogv”
extension and offers crop
, to-gif
and trim
actions. You can
navigate with C-n/C-p, select with RET and cancel with C-g.
After you've selected trim
, the selected files and the corresponding
Makefile will be moved to a staging directory within
your current directory. The staging directory will be named after the
action and the first selected file.
The Makefile will be opened for you to customize switches which start out as:
from = 00:00:01
to = 00:00:23
The actual command called will be:
ffmpeg -i $< -ss $(from) -t $(to) -c copy $@
but this complexity is distanced from you, and you can just select
from
and to
if you want.
Next you call mis-save-and-compile
(bound to f5 for make-mode
)
and test your result.
After this you can:
mis-abort
(bound to C-M-,): the staging directory will be deleted and all
files restored to their places. Basically, this is just an undo
with respect to make-it-so
.mis-finalize
(bound to C-,): in addition to mis-abort
the generated files will be
moved to the original directory.mis-replace
(bound to C-M-.): in addition to mis-finalize
the source files will be
moved to trash.Note that in all three cases any modifications to the Makefile
template will be lost, along with all files in the staging directory
except those that were copied when you first called make-it-so
and
those registered by the Makefile in “provide” file.
There's also mis-dispatch (bound to C-.) that allows to call the above three commands by name and remind you their shortcuts.
As a sample scenario, assume you want to convert *.svg to *.png.
An internet search lead to Stack Overflow and this command:
inkscape -z -e test.png -w 1024 -h 1024 test.svg
Navigate to the file(s) in dired
and call make-it-so
with ,.
No default actions are available, so just type “to-png” and hit RET.
The “to-” prefix signifies that this is a conversion, adapting the Makefile to this form:
# This is a template for the Makefile.
# Parameters should go in the upper half as:
# width = 200
# and be referenced in the command as $(width)
# ______________________________________________________________________________
DIRSVG = $(shell dir *.svg)
DIRPNG = $(DIRSVG:.svg=.png)
all: clean Makefile $(DIRPNG)
%.png: %.svg
echo "add command here"
echo $@ >> provide
clean:
rm -f *.png provide
# Insert the install command here.
# e.g. sudo apt-get install ffmpeg
install-tools:
echo "No tools required"
# Use this target when one file requires another.
# See "../../cue/split/Makefile" for an example.
require:
@echo
.PHONY: all install-tools require clean
If the action name doesn't have a “to-” prefix, the transformation is assumed to be e.g. “svg” → “out.svg”. You can change this of course by editing the Makefile.
In case the command name and package name don't coincide, or the
command needs additional packages in order to work you might want to
change echo "No tools required"
to sudo apt-get install inkscape
.
This should serve as a reminder of what you should install when you're
on a new system in order for the Makefile to work. And you can call make install-tools
to install them of course.
Replace echo "add command here"
with inkscape -z -e $@ -w $(width) -h $(height) $^
.
The parameters width
and height
will go to the top of the Makefile, where they
can be customized. $@
refers to the output file, test.png
in this case.
$^
refers to the input file, test.svg
in this case.
That's it. You can see the final Makefile here.
Test if the command works with f5 from the Makefile. If you're
happy with it, call mis-finalize
with C-, from dired
. The
Makefile will be saved for all future calls to make-it-so
.
dired-jump
command to jump from any file (or even
the compilation buffer) to the associated directory.dired-mark-files-regexp
(bound to Shift 85) that will mark all files
of specific type in directory. This is much faster than m when you want
to convert a bunch of files.As you can see, the list of Makefile recipes is quite scarce at the moment. So new Makefile contributions are most welcome.