dwim-shell-command
dwim-shell-command
to execute DWIM shell commands
Run M-x - Asynchronously.
- Using noweb templates.
- Automatically injecting files (from dired or other buffers) or kill ring.
- Managing buffer focus with heuristics.
- Showing progress bar.
- Quick buffer exit.
- More reusable history.
Bring command-line utilities to your Emacs workflows
Use dwim-shell-command-on-marked-files
to easily integrate command-line utilities into frequent Emacs workflows (ie. operate on current buffer or dired files).
(defun my/dwim-shell-command-convert-to-gif ()
"Convert all marked videos to optimized gif(s)."
(interactive)
(dwim-shell-command-on-marked-files
"Convert to gif"
"ffmpeg -loglevel quiet -stats -y -i <<f>> -pix_fmt rgb24 -r 15 <<fne>>.gif"
:utils "ffmpeg"))
Which files
dwim-shell-command
attempts to guess which file(s) you may want the command to operate on.
If visiting a dired buffer, draw the marked file(s).
If visiting any other buffer with an associated file, use that.
noweb templates
Operate on drawn files using either the following:
<<f>>
(file path)<<fne>>
(file path without extension)<<e>>
(extension)<<td>>
(generate a temporary directory)<<*>>
(all files joined)<<cb>>
(clipboard)
For example:
With drawn files path/to/image1.png
and path/to/image2.png
convert <<f>> <<fne>>.jpg
expands to
convert path/to/image1.png path/to/image1.jpg
convert path/to/image2.png path/to/image2.jpg
while ls -lh <<*>>
expands to
ls -lh path/to/image1.png path/to/image2.png
Focus
dwim-shell-command
creates a process buffer to capture command output, but neither displays nor focuses on it by default. Instead, it tries to guess what’s more convenient to focus on.
While the process is busy, show a spinner in the minibuffer. No focus changes.
After process is finished:
If there were any files created in the default-directory
, jump to a dired buffer and move point to the new file (via dired-jump).
If no new files were created, automatically switch focus to the process buffer and display its output.
Note: You can prevent this automatic focus by prepending your command with whitespace.
” convert <<f>> <<fne>>.jpg”
If the shell command caused any errors, offer to focus the process buffer and display its output.
Easily create utilities
Command-line utilities like ffmpeg can be easily integrated into Emacs flows (without the need to remember any flags or parameters) by wrapping command invocations into functions and invoking via M-x
(or your favorite binding). Same DWIM behavior from dwim-shell-command
is inherited.
All gifs in this README were created via M-x dwim-shell-command-convert-to-gif
, powered by dwim-shell-command-on-marked-files
:
(defun my/dwim-shell-command-convert-to-gif ()
"Convert all marked videos to optimized gif(s)."
(interactive)
(dwim-shell-command-on-marked-files
"Convert to gif"
"ffmpeg -loglevel quiet -stats -y -i <<f>> -pix_fmt rgb24 -r 15 <<fne>>.gif"
:utils "ffmpeg"))
This makes wrapping one-liners a breeze, so let’s do some more…
(defun my/dwim-shell-command-convert-audio-to-mp3 ()
"Convert all marked audio to mp3(s)."
(interactive)
(dwim-shell-command-on-marked-files
"Convert to mp3"
"ffmpeg -stats -n -i '<<f>>' -acodec libmp3lame '<<fne>>.mp3'"
:utils "ffmpeg"))
(defun my/dwim-shell-command-convert-image-to-jpg ()
"Convert all marked images to jpg(s)."
(interactive)
(dwim-shell-command-on-marked-files
"Convert to jpg"
"convert -verbose '<<f>>' '<<fne>>.jpg'"
:utils "convert"))
(defun my/dwim-shell-command-drop-video-audio ()
"Drop audio from all marked videos."
(interactive)
(dwim-shell-command-on-marked-files
"Drop audio" "ffmpeg -i '<<f>>' -c copy -an '<<fne>>_no_audio.<<e>>'"
:utils "ffmpeg"))
Quick exit
Process buffers are read-only and can be quickly closed by pressing q
.
More reusable history
Because of templates, command history becomes automatically reusable in other contexts.
Install
dwim-shell-command
is available on MELPA.
- Install via M-x package-install.
- Require, set edit style, and add company backend:
(require 'dwim-shell-command)
Now you’re ready to run
M-x dwim-shell-command
use-package
Alternatively, can also install via use-package, define your own commands and remap to shell-command
’s existing binding using something like:
(use-package dwim-shell-command
:ensure t
:bind (([remap shell-command] . dwim-shell-command)
:map dired-mode-map
([remap dired-do-async-shell-command] . dwim-shell-command)
([remap dired-do-shell-command] . dwim-shell-command)
([remap dired-smart-shell-command] . dwim-shell-command))
:config
(defun my/dwim-shell-command-convert-to-gif ()
"Convert all marked videos to optimized gif(s)."
(interactive)
(dwim-shell-command-on-marked-files
"Convert to gif"
"ffmpeg -loglevel quiet -stats -y -i <<f>> -pix_fmt rgb24 -r 15 <<fne>>.gif"
:utils "ffmpeg")))
Install command line utilities
I’m including an optional package (dwim-shell-commands.el), with all the command line utilities I’ve brought in via dwim-shell-command-on-marked-files
. Feel free to optionally load it via:
(require 'dwim-shell-commands)
To give you an idea, here’s what I got so far:
dwim-shell-commands-audio-to-mp3
dwim-shell-commands-bin-plist-to-xml
dwim-shell-commands-clipboard-to-qr
dwim-shell-commands-drop-video-audio
dwim-shell-commands-files-combined-size
dwim-shell-commands-git-clone-clipboard-url
dwim-shell-commands-git-clone-clipboard-url-to-downloads
dwim-shell-commands-image-to-grayscale
dwim-shell-commands-image-to-icns
dwim-shell-commands-image-to-jpg
dwim-shell-commands-image-to-png
dwim-shell-commands-pdf-password-protect
dwim-shell-commands-reorient-image
dwim-shell-commands-resize-gif
dwim-shell-commands-resize-image
dwim-shell-commands-resize-video
dwim-shell-commands-speed-up-gif
dwim-shell-commands-speed-up-video
dwim-shell-commands-unzip
dwim-shell-commands-video-to-gif
dwim-shell-commands-video-to-optimized-gif
dwim-shell-commands-video-to-webp