Hacking gnu-linux things

1 The script

Based on this script on Emacs Wiki I just added the option tu use as protocol to open urls in the form emacsclient:///path/to/file+linenumber

#!/bin/bash

args=""
nw=false

# check if emacsclient is already running
if pgrep -U $(id -u) emacsclient > /dev/null; then running=true; fi

# check if the user wants TUI mode
for arg in "$@"; do
    if [ "$arg" = "-nw" ] || [ "$arg" = "-t" ] || [ "$arg" = "--tty" ]
    then
        nw=true
    fi
done

# if called without arguments - open a new gui instance
    if [ "$#" -eq "0" ] || [ "$running" != true ]; then
        args=(-c $args)                 # open emacsclient in a new window
    fi
    if [ "$#" -gt "0" ]; then
        # if 'Vemacsclient -' open standard input (e.g. pipe)
        if [[ "$1" == "-" ]]; then
            TMP="$(mktemp /tmp/emacsstdin-XXX)"
            cat >$TMP
            args=($args --eval '(let ((b (generate-new-buffer "*stdin*"))) (switch-to-buffer b) (insert-file-contents "'${TMP}'") (delete-file "'${TMP}'"))')

        # If called as protocol syntax of call is emacsclient:///path/to/myfile+line
        elif [[ "$1" == emacsclient:* ]]; then
            args=($args --eval '(let ((protocall (split-string (substring "'$1'" 12) "+")))
                                      (find-file (nth 0 protocall))          
                                       (when (nth 1 protocall)
                                       (goto-char (point-min))
                                       (forward-line (string-to-number (nth 1 protocall)))))')

        else
            args=($@ $args) 
        fi
    fi

    # emacsclient $args
    if $nw; then
        emacsclient "${args[@]}"
    else
        echo ${args[@]} >> /tmp/ecargs
        (nohup emacsclient "${args[@]}" > /dev/null 2>&1 &) > /dev/null
    fi

2 Define the script as handler for emacsclient:/// links

Assuming the script is at home/vic.local/bin/Vemacsclient

2.1 Created a temporary file named vic-emacsclient.desktop

[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Exec=/home/vic/.local/bin/Vemacsclient
Name=Emacsclient
Comment=Maybe launches Victor's emaclient 
Categories=Editor;Development
Icon=emacs
MimeType=x-scheme-handler/emacsclient;

2.2 Installed the protocol

xdg-desktop-menu install vic-emacsclient.desktop
xdg-mime default vic-emacsclient.desktop x-scheme-handler/emacsclient

3 Usage

Open file from commandine
Vemacsclient /path/to/file +line:column
Pipe shell output to emacs buffer
ls / | Vemacsclient -
Open file with emacsclient protocol
emacsclient:///path/to/file+line This is especially useful for Drupal’s (Symfony’s?) Web Profiler plugin. I set its IDE settings to emacsclient:@file+@line and then clicking any file links in the profiler opens the file with Emacs. Can be very useful to understand where a particular bit of code gets generated.

This is a handy way to control running instances of VLC from external scripts (if you invoke vlc in the script, there are better interfaces like rc). It’s also useful if want to control VLC through keyboard shortcuts while it’s running in the background. If your window manager doesn’t pass the shortcuts to the background process (xfwm4 at least doesn’t), you can start by issuing this in a shell:

dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause

It should start/pause the backgrounded player. If it works, you can assign a shortcut to the command using the standard keyboard shortcut editor of your window manager.

VLC adheres to the Media Player Remote Interface Specification (MPRIS) which opens up for the commands listed here.  The usual start/pause etc. are in the .Player interface.

Note that some commands require a numeric argument. Seek for example needs a number of microseconds to seek forward or backward. But you don’t just give it the number. You must manually specify the type of the argument like this:

dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Seek int64:"2000000"

There are other weird (unpredictable ?) syntaxes for rates and volumes. Check this post for more examples.

20160921 093815

20160921 093815
Sonic Visualiser (SV) is a great opensource software to analyse various aspects of sound. Here I explain how to measure the scale of an instrument. I will use this tiny (maybe) Indonesian flute as an example.

The point in finding its scale is to program Yoshimi, a soft synth, to play in tune with it. The microtonal tuning of Yoshimi will be covered in another tutorial.

Useful and (imho) elegant bash script found here to remove duplicate files based on their md5 sum. I use it to get rid on duplicate emails in my mailbox.

#!/bin/bash
declare -A arr
shopt -s globstar

for file in **; do
  [[ -f "$file" ]] || continue

  read cksm _ < <(md5sum "$file")
  if ((arr[$cksm]++)); then 
    echo "rm $file"
  fi
done

Of course, remove the echo on line 10 to put the rm in effect. I actually replace the rm by a mv $file ~/.local/share/Trash/files/, for more safety.

I recently ripped a 5 CDs collection of "1001 sound effects". There was no CDDB info for it, so the tracks came all as "01 - 1001 Sound effects.flac", "02 - 1001 Sound effects.flac" and so on. This makes the ripped files pretty useless. I needed meaningful filenames in order to later find specific effects.

Fortunately, a website had the complete list of 1001 names (someone may have OCRd the booklet). I copied/pasted it in a text file named ListeCD1.txt, one name per line. Then with the help of this stackoverflow answer,  I could batch-rename all the files in the CD1 directory (I actually used cp to a new directory rather than mv in place, just to be safe)

files=( *.flac )

i=0

while read -r newname; do

    cp "${files[$i]}" "renamed/`printf %02d $(( i+1 ))`_$newname.flac";

    (( i++ ));

done < ListeCD1.txt

 

Command to remove older kernels on a linux machine:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge

Check with an extra 'uname -r' that the current kernel is not amongst those being removed.