2014-11-19

Autocompletion for C and C++ with Emacs 24

I have already done a blog post on auto completion using Emacs. But that was back in Emacs 23 days. Long ago...

Since then a lot has happened. Emacs 24 has been released, package managers like MELPA or ELPA have become standard, and company-mode seems to be winning against auto-complete. Also, clang has made huge strides forward.

So it is time to revisit the task of developing C or C++ using Emacs. I have put online an easy-to-install Emacs init.el that you can use as a start for your own development environment. I am using the OS X version of Emacs, but this should also work on Linux, given that you have clang and git installed.

You can install this init.el by issuing the following commands:

cd
git clone https://github.com/root42/yet-another-emacs-init-el
mkdir ~/.emacs.d
cd ~/.emacs.d
ln -snf ../yet-another-emacs-init-el/init.el .

The file will make sure that upon startup of Emacs all necessary packages are installed, like company, magit but also LaTeX tools like aucTeX or refTeX. You can disable this check (or individual packages) in the init.el.

The code is up on github, so feel free to fork and/or contribute.

When doing simple C++ programming using only standard libraries, you should be ready to go. For more complex projects, you have to tweak the clang parameters, so that the compiler will find the header files. Completion happens automatically after ".", "->" and "::" but also when pressing M-/. You can rebind this key in the init.el, of course. This is what the completion looks like:


My most commonly used keys that I have re-bound are as follows:
  • f3 - Runs ff-find-other-file, trying to switch between header and implementation for C/C++ programs.
  • f4 - Toggles the last two used buffers.
  • f5, f6 - If tabbar is enabled (tabbar-mode), navigates back/forward through tabs.
  • f7 - Toggle ispell dictionaries (german/english).
  • f8 - Kill current buffer.
  • f9 - Run compile.
  • M-? - Run grep.
  • M-n - Go to next error in compilation buffer.
  • M-S-n - Go to previous error in compilation buffer.
  • M->, M-< - Go to next/previous Emacs frame.
  • M-/ - Run autocompletion using company mode.
  • C-x o, C-x C-o - Go to next/previous Emacs window
Very nice is also the magit-mode, which is a very sane interface to git for Emacs. It looks like this:
You can run it by executing M-x magit-status. Just type ? to get online help. Magit uses simple one-character-commands, like s for stage, c for commit, p for push and so on.

Currently I am evaluating the integration of lldb into Emacs, but haven't come far enough to say that I have found a powerful and flexible interface, apart from the standard command line. So there's more to come, hopefully!

2014-08-31

How to view clojure docs in Emacs Cider

Developing clojure with Emacs Cider is great. To be able to view summaries for clojure functions and special forms, type this in you Cider REPL:

(use 'clojure.repl)

Afterwards, you can do stuff like this:
my.repl> (doc conj)
-------------------------
clojure.core/conj
([coll x] [coll x & xs])
  conj[oin]. Returns a new collection with the xs
    'added'. (conj nil item) returns (item).  The 'addition' may
    happen at different 'places' depending on the concrete type.
nil

2014-08-20

How to automatically refresh Cider when saving a clojure file in Emacs

Emacs has a great mode for using Clojure called Cider. Cider comes with an interactive REPL. The REPL allows you to test your code, start web apps, if you are using Luminus, and all in all accelerates  development. One annoying thing though is that you have to refresh Cider every time you saved your sources. The good thing is that you can do this automatically. Just add the following to your init.el. I took the function from a blog post by Kris Jenkins:

  (add-hook 'cider-mode-hook 
     '(lambda () (add-hook 'after-save-hook 
      '(lambda () 
         (if (and (boundp 'cider-mode) cider-mode)
      (cider-namespace-refresh)
           )))))

  (defun cider-namespace-refresh ()
    (interactive)
    (cider-interactive-eval
     "(require 'clojure.tools.namespace.repl)
    (clojure.tools.namespace.repl/refresh)"))

  (define-key clojure-mode-map (kbd "C-c C-r") 'cider-namespace-refresh)

Additionally, you can now run the refresh command manually, by hitting C-c C-r.

Update: I changed the after-save-hook to only trigger if we are in a buffer that has cider-mode enabled. Otherwise every save command in Emacs would have triggered the refresh!

2014-08-17

Forwarding emails using fetchmail and msmtp

My goal here was to forward emails from my GMX freemail account to my iCloud account. Up until now, I used GMX's own forwarding capability, which is a bit hidden in the filters settings. However, iCloud cranked up its spam filtering, and is now using spamhaus blacklists, which very often label the GMX forwarding servers as bad.

Hence I would only get bounce mails instead of the actual mails. Since this is no good, I set up fetchmail and msmtp on my root server to do the forwarding for me. First, fetchmail will get all mail on GMX via POP3 and pass it on to msmtp, which will in turn pass it on to the iCloud mx server.

At first I tried to deliver it via authenticated SMTP, but iCloud refuses mails sent this way, if the header from field does not contain any of your own iCloud aliases. This will most of the time be a problem, since we are trying to forward emails that were sent to you, not sent from you.

So first let's see the ~/.fetchmailrc (make sure to chmod 0600 it):

poll pop.gmx.net
with proto POP3
user "user@gmx.net"
there with password "secretpassword"
mda "/usr/bin/msmtp -- someuser@icloud.com"
options
no keep
ssl
sslcertck
sslcertpath /etc/ssl/certs
set daemon 300

This will poll GMX every 300 seconds and pass the received mails to msmtp for delivery to someuser@icloud.com.

The corresponding ~/.msmtprc looks like this:

account default
host mx6.mail.icloud.com
port 25
auto_from off
from "user@localdomain"
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile ~/.msmtp.log
domain mx.of.localdomain

You can find out the valid mx entries for iCloud by running nslookup -type=mx icloud.com.

The settings above are assuming Debian stable. Other distributions or operating systems may have the SSL certs at different places in the file system.

2014-07-30

hal+json is the way to go for representing REST resources

If you are implementing REST APIs, and are thinking about using application/json as your content type, please consider application/hal+json. It allows you to represent link relations and embedded resources in a standardized manner.

The content type offers three things:

  1. Semantic link relations using the _link key. The self link is a good example.
  2. Embedded resources using the _embedded key, which are a subset of the link relations
  3. Properties with arbitrary keys

As an example, you might have a programmable power strip with three sockets. The strip itself can be modeled as a resource. It will have three optionally embedded resources with the link relation sockets. These resources themselves will have a link relation called toggle. Doing e.g. a POST on this resource will allow you to toggle it. The lovely thing here is that the API will give you the correct URL to turn on or off the socket. An example request and response:

GET http://foo.com/powerstrip/1
Accept: application/hal+json

{
    "_links" : {
 "self" : { "href" : "http://somedomain/powerstrip/1" },
 "sockets" : [
     { "href" : "http://somedomain/powerstrip/1/sockets/1", "name" : "Socket 1" },
     { "href" : "http://somedomain/powerstrip/1/sockets/1", "name" : "Socket 2" },
     { "href" : "http://somedomain/powerstrip/1/sockets/1", "name" : "Socket 3" }
 ]
    },
    "_embedded" : {
 "sockets" : [
     { 
  "_links" : {
      "self" : { "href" : "http://somedomain/powerstrip/1/sockets/1" },
      "toggle" : { "href" : "http://somedomain/powerstrip/1/sockets/1/off" }
  }
  "state" : "on"
     },
     { 
  "_links" : {
      "self" : { "href" : "http://somedomain/powerstrip/1/sockets/2" },
      "toggle" : { "href" : "http://somedomain/powerstrip/1/sockets/2/on" }
  }
  "state" : "off"
     },
     { 
  "_links" : {
      "self" : { "href" : "http://somedomain/powerstrip/1/sockets/3" },
      "toggle" : { "href" : "http://somedomain/powerstrip/1/sockets/3/on" }
  }
  "state" : "off"
     }
 ]
    },
    "numberOfSockets" : 3,
    "voltage" : 230
}

The content type is described in an RFC draft, and is well on its way to become a standard. Make sure to also read the associated web linking RFC.

Amazon is already using this content type in its AppStream API.

The strength of using link relations and a content type such as HAL is that you can actually document your link relations, which are a fundamental part of your API. You should actively design the link relations and make them meaningful.

For resources, I recommend that you document the following aspects:

  1. Expected link relations and their embeddedness
  2. Attributes of the resource
  3. Example method calls for all allowed methods (GET, POST, ...) with example responses 

For link relations you should document these aspects:

  1. Synopsis what the link relation means or represents, and which resource is to be expected
  2. Allowed methods with optional templated arguments
I place the example method calls with the resource documentation, since they might be redundant if specified with the link relations. But you should link to the resource documentation from the associated link relation documentation.

2014-07-15

Extracting Names from Email Addresses

Given a CSV file with the following format:
;;firstname.lastname@somehost.com
The task is to extract the names from the email addresses. We assume that the names are seperated by periods (.) and that all the names are supposed to be capitalized and printed with strings:
#!/usr/bin/env python

import sys

if len( sys.argv ) < 2:
    print "Usage: %s filename" % sys.argv[ 0 ]
    sys.exit( 1 )

textFileName = sys.argv[ 1 ]
textFile = open( textFileName, "r" )

for line in textFile:
    fields = line.strip().split( ';' )
    email = fields[ 2 ].split( "@" )
    emailName = email[ 0 ].split( '.' )
    capitalizedName = [ x[:1].upper() + x[1:].lower() for x in emailName ]
    print '%s;%s;%s' % ( capitalizedName[ 0 ], ' '.join( capitalizedName[ 1: ] ), fields[ 2 ] )

2014-03-22

How to backup your Raspberry Pi SD-Card

In the following I will explain on how you can backup your Pi's SD-card, so that whenever it breaks down, you can simply restore the backup image to a fresh SD-Card. This may also help with tinkering, when you totally screwed up your Pi's Linux-installation. I will explain the first step specifically for Mac OS X, but you can do this similarly on other UNIXes and Linux, by using the mount and umount commands.

So, shut down your Pi using the command sudo shutdown -h now and remove the SD-card after the Pi has done so. Take the card and insert it into your Mac's SD-card slot.

First of all, we need to find out which disk device has been assigned to the card. We can do this with diskutil list:

user@mymacintosh:~ $ diskutil list                                                                
/dev/disk0                                                                                            
   #:                       TYPE NAME                    SIZE       IDENTIFIER                        
   0:      GUID_partition_scheme                        *512.1 GB   disk0                             
   1:                        EFI EFI                     209.7 MB   disk0s1                           
   2:                  Apple_HFS M4                      511.1 GB   disk0s2                           
   3:                 Apple_Boot Recovery HD             784.2 MB   disk0s3                           
/dev/disk1                                                                                            
   #:                       TYPE NAME                    SIZE       IDENTIFIER                        
   0:     FDisk_partition_scheme                        *15.9 GB    disk1                             
   1:             Windows_FAT_32                         58.7 MB    disk1s1                         
   2:                      Linux                         15.9 GB    disk1s2                           

Then unmount the card using diskutil unmountDisk:

user@mymacintosh:~ $ diskutil umountDisk /dev/disk1                                              
Unmount of all volumes on disk1 was successful                                                     

Next we will use dd to produce an image, which we can compress using bzip2, or pbzip2 for more performance. You can use MacPorts to install pbzip2.

user@mymacintosh:~ $ sudo dd if=/dev/disk1 | pbzip2 > raspberry_pi_$(date "+%Y-%m-%d").img.bz2 
31116288+0 records in                                                                                                           
31116288+0 records out                                                                                                        
15931539456 bytes transferred in 2347.692010 secs (6786043 bytes/sec)                                                           

Restoring the image is also easy:

user@mymacintosh:~ $ bunzip2 raspberry_pi_2014-03-22.img.bz2 | sudo dd of=/dev/disk1      

2014-03-16

Getting Emacs for Mac OS X to honour the shell environment

If your are using the excellent Emacs for Mac OS X distribution, you may have noticed that it does not use the environment you may have defined in your ~/.bashrc. This can be a problem if you are using MacPorts, for example to install clojure and Leiningen. You will get an error message like this, when trying to run inferior-lisp in clojure-mode:

apply: Searching for program: No such file or directory, lein

This can be avoided by using the excellent exec-path-from-shell package for Emacs. It is available via (M)ELPA, just install it using list-packages, or download it from github. You can enable it, especially for OS X, by putting this in your init.el:

(when (memq window-system '(mac ns))
    (exec-path-from-shell-initialize))

2014-02-01

How to use find and rsync to copy a bunch of files to a local or remote destination

I use rsync a lot. And I use find a lot. You can use them both together, by using the magnificent xargs command. Two problems are there to solve: xargs usually just pastes the arguments from find at the end of the specified command. No way to specify the destination directory. Second, file names with spaces are a problem.

The solutions are:

  • The -print0 option of find uses 0-bytes to separate results, instead of spaces and newlines
  • The -0 option of xargs tells xargs to look for said 0-bytes
  • The -J option of xargs allows us to tell xargs where to put the file names that we feed to it.
So let's put it together:

pi@raspberrypi ~ $ find . -name 'your*pattern.jpg' -print0 | xargs -J % -0 rsync -aP % user@host:some/dir/

Thanks to redeyeblind for the insightful blog post.

2014-01-19

How to resize tmux windows using OS X terminal

A while back I pointed out a blog post by someone else, which described how to get C-left and C-right working in tmux and OS X. Now I noticed that I cannot resize windows in tmux. This is because tmux seems to expect xterm keys for C-arrow. The xterm keycodes for the arrow keys are:

  • left key: ^[[D
  • right key: ^[[C
  • up key: ^[[A
  • down key: ^[[B
  • C-left: ^[[1;5D
  • C-right: ^[[1;5C
  • C-up: ^[[1;5A
  • C-down: ^[[1;5B

I can now configure OS X terminal to send those key codes, and tmux works fine. However, other apps running in tmux will break, because they don't expect to get xterm key codes. I found a workaround in the ArchWiki, which suggests to create your own terminfo entry. I will try that and report back here.

Update: The solution is adding two lines to the ~/.tmux.conf file:

set -g default-terminal "xterm-256color"
setw -g xterm-keys on                   

Update 2: And here is my OS X Terminal.app configuration:

Update 3: And a very last update... It seems that tmux does not support bce (background color erase), which xterm does. This is a problem for progams like htop, vim, or mc. You will see rendering errors, if you do not fix this.

So you need to make your own terminfo file and own terminal type, called xterm-256color-nobce. You can do this on the command line:

pi@raspberrypi ~ $ infocmp xterm-256color | sed 's/bce, //' | sed 's/xterm-256color/xterm-256color-bce/g' > xterm-256color-nobce

This will create a new terminfo source file, which does not advertise the bce feature. You can install this with the following command:

pi@raspberrypi ~ $ sudo tic ./xterm-256color-nobce

This makes the terminal type xterm-256color-nobce available. After this, change your ~/.tmux.conf once again, to use the new terminal type per default:

set -g default-terminal "xterm-256color-nobce"

Update 4: To make the Ctrl+Arrow keys also work in regular OS X Terminal, you need to edit or create ~/.inputrc to contain this:

# xterm keys for skipping a word
"\e[1;5C": forward-word
"\e[1;5D": backward-word
"\e[5C": forward-word
"\e[5D": backward-word

The "1;" variant is otherwise not recognized by GNU readline on OS X.

2014-01-02

How to setup an OpenWRT router as a WiFi bridge to an Ethernet router

You can use an OpenWRT router or access point to connect WiFi enabled devices to a router, which only has wired Ethernet. For this to work, I am assuming you already have an access point or router running OpenWRT, in this case version 12.09, Attitude Adjustment.

Log into your router, using the LuCi frontend, and go to the Network/Interfaces tab:


There you should see your LAN device. Edit it to have an appropriate IP address from your local subnet. Most often your network will be 192.168.0.0 and your existing router will have the IP 192.168.1.1. But your mileage may vary...

Lets put in a static IP address, so we can find our router in case something goes wrong. Also make sure to set the netmask (in this case 255.255.255.0), gateway and DNS server (both probably should point to your router, 192.168.1.1).


Now go to the Physical Settings tab. Here, it's important to check "Bridge interfaces" and to select both the ethernet adapter, most likely eth0, and the wireless network. One of the ethernet devices will say "wan", if your are using a router instead of an access point for this. You don't want that device.


Hit "Save & Apply" when you are ready. And be sure to have the de-bricking guide ready, if something goes wrong...

2014-01-01

How to run tmux via ssh instantly

With my Raspberry Pi, what I do very, very often is this:

localhost$ ssh raspberrypi.local    # Here I already type the next command and wait a while
raspberrypi$ tmux attach

This is all well and good, but sometimes the Pi is down, and I will attach to one of my local tmux sessions. Very annoying. Instead you could try to do this:

localhost$ ssh raspberrypi.local tmux attach
not a terminal

Well, that did no good. So a look at the man-page of ssh or a quick search reveals this gem:

localhost$ ssh raspberrypi.local -t tmux attach

This allocates a pseudo terminal, which is needed by tmux to function correctly. This is also done by ssh, if no command is given, but a login shell is spawned.