Use vidir to quickly edit filenames in your editor

If you have installed moreutils (see below), you can type vidir to open up the current working directory in your $EDITOR. You can use all the power of your editor to edit and/or delete filenames and directories. Editing a line will rename the file or directory, deleting a line will remove the file or directory.

The following will list all your JPEG pictures in the current directory in your editor:

$ vidir *.jpeg

vidir is not recursive by default: if you want to recursively edit filenames, you can do:

$ find -type f -name '*.jpeg' | vidir -  # take note of the trailing dash -

Deleting non-empty directories

When trying to delete a non-empty directory, vidir will complain:

/usr/bin/vidir: failed to remove ./non-empty-directory: Directory not empty

We can use find again:

$ ls -1 non-empty-dir
file1.txt
file2.txt
$ find | vidir -
1   ./non-empty-dir
2   ./non-empty-dir/file1.txt
3   ./non-empty-dir/file2.txt

When we delete all the files from the directory and the directory itself, the directory will be deleted.

To see what vidir is actually doing, you can pass it the -v or --verbose flag:

$ find | vidir -v -
removed './non-empty-dir/file2.txt'
removed './non-empty-dir/file1.txt'
removed './non-empty-dir'

How to install

In Arch Linux, you can install the moreutils package with sudo pacman -S moreutils. On Debian distros, you can run sudo apt install moreutils.

Use pandoc with Pygments to highlight source code

I am someone who has JavaScript disabled by default in his browser (I use uMatrix in Firefox for that). Only when I trust a site and I need to use functionality that truly depends on JavaScript will I turn it on. This hopefully protects me from most of the known and unknown bad stuff out there on the internet. It also makes me appreciate people who go through the trouble of making their webpages work without JavaScript.

Until recently, I used a JavaScript plugin on this blog to format source code. This bothered me, since using JavaScript just to display some source code seems like overkill and makes people have to turn on JavaScript in their browsers just to see the source code formatted nicely. I wanted to do better than that.

The way I normally write my blog posts is, I start with a Markdown article and then use pandoc to convert it to HTML which I then copy and paste into WordPress (if there is a better way to do this, please contact me). I noticed pandoc provides a switch --filter where you can specify a executable that can transform the pandoc output. The only problem is, you have to write a filter. Luckily, I found a GitHub gist that has already figured out how to write one. Here is some Haskell for you:

import Text.Pandoc.Definition
import Text.Pandoc.JSON (toJSONFilter)
import Text.Pandoc.Shared
import Data.Char(toLower)
import System.Process (readProcess)
import System.IO.Unsafe

main = toJSONFilter highlight

highlight :: Block -> Block
highlight (CodeBlock (_, options , _ ) code) = RawBlock (Format "html") (pygments code options)
highlight x = x

pygments:: String -> [String] -> String
pygments code options
         | (length options) == 1 = unsafePerformIO $ readProcess "pygmentize" ["-l", (map toLower (head options)),  "-f", "html"] code
         | (length options) == 2 = unsafePerformIO $ readProcess "pygmentize" ["-l", (map toLower (head options)), "-O linenos=inline",  "-f", "html"] code
         | otherwise = "<div class =\"highlight\"><pre>" ++ code ++ "</pre></div>"

Note that this program invokes another program, pygmentize to actually highlight the source code (pygmentize is part of the Pygments project). So, install pygmentize with your favorite package manager, install Haskell if you have not done so already, and then compile pygments.hs with:

$ ghc -dynamic pygments.hs

That’s it! Putting it all together, to create a blog post, I can now do:

$ pandoc -F pygments -f markdown -t html5 -o blogpost.html blogpost.md

I added some CSS that makes use of the Pygments classes and voilà: you can now view this blog without having to worry about a JavaScript cryptocurrency miner hijacking your CPU. You’re welcome.

Remove all files except a few in Bash

$ ls -1
153390909910_first
15339090991_second
15339090992_third
15339090993_fourth
15339090994_fifth
15339090995_sixth
15339090996_seventh
15339090997_eighth
15339090998_nineth
15339090999_tenth
15339091628_do_not_delete
root
root.sql

We want to delete all files that start with a timestamp (seconds since the epoch), except the newest file (15339091628_do_not_delete) and the files root and root.sql. The easiest way to do this, is enabling the shell option extglob (“extended globbing”), which allows us to use patterns to include or exclude files of operations:

$ shopt -s extglob
$ rm !(*do_not_delete|root*)

The last command will tell Bash to remove all files, except the ones that match either one of the patterns (everything ending with do_not_delete and everything starting with root). We delimite the patterns by using a pipe character |.

Other patterns that are supported by extglob include:

?(pattern-list)
      Matches zero or one occurrence of the given patterns

\*(pattern-list)
      Matches zero or more occurrences of the given patterns

+(pattern-list)
      Matches one or more occurrences of the given patterns

@(pattern-list)
      Matches one of the given patterns

!(pattern-list)
      Matches anything except one of the given patterns

To disable the extended globbing again:

$ shopt -u extglob

References

To read about all the options that extglob gives you, refer to man bash (search for Pathname Expansion). Searching for shopt in the same manual page will turn up all shell options. To see which shell options are currently enables for your shell, type shopt -p at the prompt.