Share OSX Clipboard With Emacs

Add the following to your .el init files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;; Use M-w to copy Emacs buffer selection; and Cmd-V to paste outside of Emacs.
;; Use Cmd-C to copy selection from OSX; and C-y to paste in Emacs
(defun copy-from-osx ()
(shell-command-to-string "pbpaste"))
(defun paste-to-osx (text &optional push)
(let ((process-connection-type nil))
(let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
(process-send-string proc text)
(process-send-eof proc))))
(setq interprogram-cut-function 'paste-to-osx)
(setq interprogram-paste-function 'copy-from-osx)

Control iTunes with Shell Script at Command-line

Use the following script to control iTunes from the shell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/bin/sh
#
#######################################
# iTunes Command Line Control v1.0.0.1
# written by David Schlosnagle
# created 2001.11.08
# modified 2007.01.28 by David West
# modified 2013.08.02 by ootput
# filename=itunes
#######################################
showHelp () {
echo "-----------------------------";
echo "iTunes Command Line Interface";
echo "-----------------------------";
echo "Usage: `basename $0` ";
echo;
echo "Options:";
echo " status = Shows iTunes' status, current artist and track.";
echo " play = Start playing iTunes.";
echo " pause = Pause iTunes.";
echo " next = Go to the next track.";
echo " prev = Go to the previous track.";
echo " mute = Mute iTunes' volume.";
echo " unmute = Unmute iTunes' volume.";
echo " vol up = Increase iTunes' volume by 10%";
echo " vol down = Increase iTunes' volume by 10%";
echo " vol # = Set iTunes' volume to # [0-100]";
echo " stop = Stop iTunes.";
echo " search = Run query, populate playlist named foo and play. "
echo " playlist = Show playlists saved in iTunes.";
echo " clear = clear playlist foo. ";
echo " quit = Quit iTunes.";
}
if [ $# = 0 ]; then
showHelp;
fi
while [ $# -gt 0 ]; do
arg=$1;
songname=$2;
echo $songname;
case $arg in
"status" ) state=`osascript -e 'tell application "iTunes" to player state as string'`;
echo "iTunes is currently $state.";
if [ $state = "playing" ]; then
artist=`osascript -e 'tell application "iTunes" to artist of current track as string'`;
track=`osascript -e 'tell application "iTunes" to name of current track as string'`;
echo "Current track $artist: $track";
fi
break ;;
"play" ) echo "Playing iTunes.";
osascript -e 'tell application "iTunes" to play';
break ;;
"pause" ) echo "Pausing iTunes.";
osascript -e 'tell application "iTunes" to pause';
break ;;
"next" ) echo "Going to next track." ;
osascript -e 'tell application "iTunes" to next track';
break ;;
"prev" ) echo "Going to previous track.";
osascript -e 'tell application "iTunes" to previous track';
break ;;
"mute" ) echo "Muting iTunes volume level.";
osascript -e 'tell application "iTunes" to set mute to true';
break ;;
"unmute" ) echo "Unmuting iTunes volume level.";
osascript -e 'tell application "iTunes" to set mute to false';
break ;;
"vol" ) echo "Changing iTunes volume level.";
vol=`osascript -e 'tell application "iTunes" to sound volume as integer'`;
if [ $2 = "up" ]; then
newvol=$(( vol+10 ));
fi
if [ $2 = "down" ]; then
newvol=$(( vol-10 ));
fi
if [ $2 -gt 0 ]; then
newvol=$2;
fi
osascript -e "tell application "iTunes" to set sound volume to $newvol";
break ;;
"stop" ) echo "Stopping iTunes.";
osascript -e 'tell application "iTunes" to stop';
break ;;
"quit" ) echo "Quitting iTunes.";
osascript -e 'tell application "iTunes" to quit';
exit 1 ;;
"search" ) echo "Searching Library.";
songname=$2;
osascript -e "tell application "iTunes"" -e "set searchResults to search playlist "Library" for "$songname"" -e "repeat with aTrack in searchResults" -e "copy aTrack to playlist "foo"" -e "end repeat" -e "play playlist "foo"" -e "end tell";
break ;;
"playlist" )
if [ -n "$2" ]; then
echo "Changing iTunes playlists to '$2'.";
osascript -e 'tell application "iTunes"' -e "set new_playlist to \"$2\" as string" -e "play playlist new_playlist" -e "end tell";
break ;
else
# Show available iTunes playlists.
echo "Playlists:";
osascript -e 'tell application "iTunes"' -e "set allPlaylists to (get name of every playlist)" -e "end tell";
break;
fi
break;;
"clear" ) echo "Clearing Query.";
osascript -e "tell application "iTunes" to delete tracks of playlist "foo"";
break ;;
"help" | * ) echo "help:";
showHelp;
break ;;
esac
done

Partition OSX Mounted User Directory As Root Using iPartition

Following an Apple support article entitled: Enabling and using the “root” user in Mac OS X, and with the aid of iPartition, I was able to re-partition my User partition (located on x220’s internal 300GB drive). The use of diskutil was out of the question as I had chosen an MBR scheme during Lion’s installation.

My original partition layout (MBR) was as follows:

root# diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *30.0 GB    disk0
   1:                  Apple_HFS Mac OSX Lion            30.0 GB    disk0s1
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *320.1 GB   disk1
   1:                  Apple_HFS User                    260.0 GB   disk1s1
   2:                  Apple_HFS Backup                   30.0 GB   disk1s2

As you can see, disk1 has available unused space amounting to 30GB. I had planned to expand my User partition (/User is a symlink to /Volumes/User) to 290GB using iPartition as an administrative user, but was unable to do so as disk1 was still in use and couldn’t be mounted. Booting the system in single-user mode was not an option for me as I wanted to use iPartition’s support of non-destructive resize of HFS+.

Fortunately, I was able to enable the root account, whereby I would then kill all processes owned by my user or that had open files on disk1 - using # lsof +D /Volumes/User for the latter. iPartition would then be able to operate unimpeded.

Moving data (upon resizing) takes a while - particularly on a 300GB drive, so it is imperative to use an external power source and to disable any power saving features such as suspend.

OSX Lion on Thinkpad X220

In all my years of computing, I’d never imagined the day where I would find myself working with an Apple OS. I’d always assumed - wrongly - that Mac systems were specifically targeted to cashed-up yuppies who didn’t know any better. I assumed that Windows was the only platform of choice to get things done, and that accumulating quality software designed for Windows was the primary goal of my technosexual existence. Of course, back then, in the days of raging hormones and teenage angst, I had made many incorrect assumptions.

As I eventually found out, both Linux and BSD proved to be rock solid workhorses and viable alternatives to the Windows that I had so admired - and now, it seems I have also taken a strong liking to Apple’s OSX. Of course, any Apple evangelism on my part will be premature, as I have yet to grasp the inner workings of OSX. For now, let’s just say that I have OSX Lion successfully running on my Lenovo X220 (alongside CrunchBang Linux) courtesy of my wife’s Snow Leopard Disk, and this guide, and that I enjoy every minute of using it. It is a very capable system, and a most welcome addition to my heterogeneous network. There were a few hiccups along the way (to be discussed later), but for the most part, the installation ran smoothly.

Thus far, I’ve made many changes to the system to arrive at a more familiar desktop (again, to be discussed later). This is not to say that I have been spending most of my time tinkering with the defaults - in fact, like Crunchbang, OSX proves to be quite operational OOTB. I suppose that I have been spoiled somewhat with Crunchbang’s easy maintenance, that proceeding to use an even simpler system seemed to be a most natural step.

My workflow has not been altered considerably, owing to the many ported software from Unix systems, and for this I am thankful. Running OSX - as opposed to any Linux distribution - does also have its perks: I am able to access a wider pool of quality commercial software for my media creation/management. As much as I admire the tenets of the Free Software movement, I’m not bound to it - nor am I vehemently opposed to commercial offerings. I have not compromised my integrity, and I like to think that I choose software on the basis of what’s right for the proverbial job.

I will try to make as many posts regarding the transition as I can - both for X220 owners considering running a Hackintosh, or for other geeks who have risen above the stigma of Macintosh use and are willing to try.

CrunchBang on Thinkpad X220

Desktop Replacement
Hardware Modifications
Upgrade BIOS From USB
About CrunchBang
System Modifications

Desktop Replacement:

It has been over two and a half years since my last Debian-related post so I thought it necessary to provide an update. I have since donated my desktop machine to a worthy cause in favour of the more-mobile Thinkpad platform. My semi-retired Debian desktop is now providing headache-free internet access at the local library, where one of the librarians had long been toying with the idea of using open source. The successful implementation of my machine prompted their acquisition of a further two Ubuntu machines.

My new Thinkpad, on the other hand, has been running CrunchBang Linux (#!) for over a year and a half, and I could not be happier. Although not a pure Debian system, #! is still a lean derivative.

Hardware Modifications:

Hardware changes I’ve made so far include: installing an Intel 30GB 525s MLC mSATA SSD drive to act as my system drive; and running 2 x 4 GB Corsair PC3-10600 DDR3-1333 RAM in dual channel mode.

Upgrade BIOS From USB:

After grabbing the latest BIOS-update bootable iso from the Lenovo support site, it is necessary to extract its [otherwise hidden] contents via a perl script called geteltorito.pl.

To fetch the script:
$ wget 'http://userpages.uni-koblenz.de/~krienke/ftp/noarch/geteltorito/geteltorito.pl'

Then, extract the contents of the downloaded *.iso file to any new target file:
$ perl ./geteltorito.pl /path/to/_bios_update_cd.iso > /path/to/_target_image_.img

To write the image to your USB (located at /dev/sdX):
$ sudo dd if=/path/to/_target_image_.img of=/dev/sdX bs=512K

Then hit F12 at bootup to choose the bootable medium.

About CrunchBang:

Out-of-the-box, #! does everything I need it to do on a laptop (wifi management; power-saving; keyboard accessibility-support,) at a fraction of the resources required were I to customize a larger/slimmer distribution to suit my needs. Were I to install Debian, I would have arrived at my ideal setup at a much later date.

Crunchbang provides a superb arsenal of open-source productivity applications, and I found myself bored witless during post-install. It defaults to using Openbox - which is not exactly a tiling WM that I’m accustomed to using - but I have made peace with that by implementing split-panes in tmux which, considering the smaller LCD screen real-estate, works reasonably well.

For work-purposes, I have implemented KVM + Qemu to manage a guest Windows XP OS - the guide I used can be found here - and I have been able to leverage the power of this fantastic little unit to conduct business.

System Modifications:

System changes I’ve made so far include: switching from grub2 to syslinux (see here); colourizing init feedback (see here); mounting system paths on the SSD drive with TRIM support (with fstab: -o discard); enabling Thinkpad-specific battery savings (with tlp and thinkpad-smapi); relocating /var paths and browser profiles to tmpfs (with profile-sync-daemon).

To get wifi working again after a system suspend-resume event, my executable /etc/pm/sleep.d/20_fix_wifi contains:
case "${1}" in resume|thaw) rmmod iwlwifi && modprobe iwlwifi ;; esac

Additionally, I had CrunchBang show verbose shutdown messages by modifying /etc/slim.conf to show:

xserver_arguments -nolisten tcp -novtswitch

As my Crunchbang box is essentially a Debian Wheezy machine, I will henceforth address it as my debian box in all future blog entries.

Address Merged Ports

My most recent # portmaster -Da revealed a package conflict: py-setuptools was merged with py-distribute.

From FreshPorts:

2013-03-05
Affects: users of devel/py-setuptools (i.e you)
Author: rm@FreeBSD.org
Reason: devel/py-setuptools was replaced with devel/py-distribute. py-setuptools port will be removed shortly.

To fix this:
# portmaster -o devel/py-distribute devel/py-setuptools

From man 8 portmaster:

-o new port dir in /usr/ports installed port:replace the installed port with a port from a different origin

Relocate iOS Backups

There are currently 3 different iPhones and 2 different iPads in my household that need updating - from iOS versions 3.x, 4.x, and 5.x. In order to make the transition to iOS version 6.0.1 (current), I first have to back up each device via iTunes. Unfortunately, my meagre 60GB SSD system drive will not suffice. I have decided to use NTFS’ junction function to link directories on separate hard drives. I had to move %APPDATA%\Apple Computer from my system drive to a separate D:\, using cmd.exe:

move "%APPDATA%\Apple Computer" D:\

then issue the following command in cmd.exe (as admin):

mklink /J "%APPDATA%\Apple Computer" "D:\Apple Computer"

For the curious, %APPDATA% contains the full path to the Application Data folder of the logged-in user, e.g., C:\Users\ootput\AppData\Roaming

CouchPotato on FreeBSD

For CouchPotato in FreeBSD, firstly acquaint yourself with my previous blog entry on Sabnzbd+Sickbeard on FreeBSD, and then perform the following additional steps:

At Step 3, fetch CouchPotato’s source code:

# cd /usr/local && git clone git://github.com/RuudBurger/CouchPotato.git couchpotato

Also, it is advisable to change the permission and ownership of the CouchPotato folder:

# chown root:_sabnzbd /usr/local/couchpotato

# chmod g+w /usr/local/couchpotato

At Step 4, add the following to /etc/rc.conf:

1
2
couchpotato_enable="YES"

.. and create /usr/local/etc/rc.d/couchpotato containing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/bin/sh
#
# PROVIDE: couchpotato
# REQUIRE: DAEMON sabnzbd
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# couchpotato_enable (bool): Set to NO by default.
# Set it to YES to enable it.
# couchpotato_user: The user account Couch Potato daemon runs as what
# you want it to be. It uses '_sabnzbd' user by
# default. Do not sets it as empty or it will run
# as root.
# couchpotato_dir: Directory where Couch Potato lives.
# Default: /usr/local/couchpotato
# couchpotato_chdir: Change to this directory before running Couch Potato.
# Default is same as couchpotato_dir.
# couchpotato_pid: The name of the pidfile to create.
# Default is couchpotato.pid in couchpotato_dir.
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
. /etc/rc.subr
name="couchpotato"
rcvar=${name}_enable
load_rc_config ${name}
: ${couchpotato_enable:="NO"}
: ${couchpotato_user:="_sabnzbd"}
: ${couchpotato_dir:="/usr/local/couchpotato"}
: ${couchpotato_chdir:="${couchpotato_dir}"}
: ${couchpotato_pid:="${couchpotato_dir}/couchpotato.pid"}
WGET="/usr/local/bin/wget" # You need wget for this script to safely shutdown Couch Potato.
HOST="127.0.0.1" # Set Couch Potato address here.
PORT="5000" # Set Couch Potato port here.
SBUSR="" # Set Couch Potato username (if you use one) here.
SBPWD="" # Set Couch Potato password (if you use one) here.
status_cmd="${name}_status"
stop_cmd="${name}_stop"
command="/usr/sbin/daemon"
command_args="-f -p ${couchpotato_pid} python ${couchpotato_dir}/CouchPotato.py ${couchpotato_flags} --quiet"
# Check for wget and refuse to start without it.
if [ ! -x "${WGET}" ]; then
warn "Couchpotato not started: You need wget to safely shut down Couch Potato."
exit 1
fi
# Ensure user is root when running this script.
if [ `id -u` != "0" ]; then
echo "Oops, you should be root before running this!"
exit 1
fi
verify_couchpotato_pid() {
# Make sure the pid corresponds to the Couch Potato process.
pid=`cat ${couchpotato_pid} 2>/dev/null`
ps -p ${pid} | grep -q "python ${couchpotato_dir}/CouchPotato.py"
return $?
}
# Try to stop Couch Potato cleanly by calling shutdown over http.
couchpotato_stop() {
echo "Stopping $name"
verify_couchpotato_pid
${WGET} -O - -q --user=${SBUSR} --password=${SBPWD} "http://${HOST}:${PORT}/home/shutdown/?pid=${pid}" >/dev/null
if [ -n "${pid}" ]; then
wait_for_pids ${pid}
echo "Stopped"
fi
}
couchpotato_status() {
verify_couchpotato_pid && echo "$name is running as ${pid}" || echo "$name is not running"
}
run_rc_command "$1"

NTFS-Write in FreeBSD

NTFS-write in FreeBSD is possible with NTFS-3G from ports. From tuxera.com:

NTFS-3G is a stable, full-featured, read-write NTFS driver for Linux, Android, Mac OS X, FreeBSD, NetBSD, OpenSolaris, QNX, Haiku, and other operating systems. It provides safe handling of the Windows XP, Windows Server 2003, Windows 2000, Windows Vista, Windows Server 2008 and Windows 7 NTFS file systems.

To install NTFS-3G, do:

# portmaster sysutils/fusefs-ntfs

Next, create a symbolic link from the newly-installed /usr/local/bin/ntfs-3g into /usr/sbin/:

# ln -s $(which ntfs-3g) /usr/sbin/mount_ntfs-3g

Modify your /etc/rc.conf to contain:

1
2
fusefs_enable="YES"

Provided you know on which hard-disk (based on make/model/capacity of the device) your NTFS partition resides, you can figure out it’s exact device node in FreeBSD:

# egrep 'ad[0-9]|cd[0-9]|da[0-9]' /var/run/dmesg.boot

ad0: 35303MB  at ata0-master
ad2: 57240MB  at ata1-master
ad4: 286168MB  at ata2-master

My NTFS partition resides on a 300GB WD Velociraptor drive, ad4. To confirm that /dev/ad4 does indeed contain the NTFS partition, do:

# gpart show -p ad4

=>        34  586072064    ad4 GPT  (286G)
          34  586072064  ad4p1 ntfs (286G)

To mount the partition manually, do:

# ntfs-3g /dev/ad4s1 /mnt/windows7

Finally, add the appropriate line to /etc/fstab to have the NTFS partition mounted at the next system boot. For instance, my /etc/fstab contains:

/dev/ad4s1              /mnt/windows7            ntfs-3g rw,late         0       0

Code and Gists in Wordpress

While WordPress.com doesn’t allow you to use potentially harmful code on your blog, it does allow you to post source code for general viewing. Provided that you enclose the source code within a [sourcecode] [/sourcecode] shortcode wrapper, you will be able to preserve the code’s formatting; enable syntax highlighting for the programming language used; and highlight specific lines in the code. For example, for a CSS snippet, do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[sourcecode language="css" highlight="3,4,5,6,7"]
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
[/sourcecode]

Alternatively, wordpress.com permits embedding github.com gists by using the [gist] shortcode. With [gist]2927943[/gist], you’ll achieve:

… which certainly isn’t as pretty as wordpress.com‘s solution. You can make a gist more presentable by way of CSS customizations, but this isn’t possible on wordpress.com. It is also impossible to tell gists to highlight specific lines of code.