Kupfer Plugins

After getting frustrated with GNOME-Do's memory hogging, I switched to Kupfer. Kupfer is a lightweight, extensible application launcher like Do (as it is now called) but much more powerful and easier to extend (it is written in python).

My Plugins

So far, I've written the following plugins:

  1. gwibber_plugin.py: This plugin allows you to send messages from Kupfer through Gwibber (with no configuration).

  2. exaile_plugin.py: This plugin allows you to pause, play, skip, and go backwards in Exaile. It is based on the Rhytmbox plugin.

+1: evolution_plugin.py: I did not write this plugin (although I did do a fair bit of editing). The Evolution plugin adds an evolution contact source (and works with the built in email plugin).

Download: kupfer-plugins.tar.gz

Start conky only after the root window loads

Every time I logged in, conky would start up before nautilus loaded the desktop. This caused conky to load as a floating window that stayed on top of all other windows. I have finally gotten around to fixing this problem.

~~Here~~ (gone, email if found) is a simple python script that waits for nautilus to load the desktop before starting conky.

This script is probably very inefficient but it gets the job done.

Humanity Icon for Caffeine

For those who don't know, Caffeine is a small program for Linux that lets a user prevent his or her computer from entering a power save state. If a user wishes, he or she can even configure caffeine to automatically inhibit power-saving when watching a flash movie, or running VLC, Totem etc. For more information, visit its website here.

As a user of both Caffeine and the new Humanity icon theme (the default icon theme in karmic), I made a very basic gray-scale version of the Caffeine icon. You can download it here.

Service Manager for Karmic

Annoyingly, as karmic has mostly switched to Upstart, it does not include a service manager. While I hope that the gnome service-manager will be updated to include support for upstart soon I have, for the interim, written a very simple service manager.

Be warned: When I say "very simple" I mean "very simple, noob unfriendly, and potentially dangerous". While it should not harm your computer, I make no guarantees because it is my first PyGTK program and was written in my spare time over a couple of days. A word of warning, the code is very messy and inefficient (understatement).

Link

New Desktop Theme

Just in case anyone is interested, here is my new desktop layout.

Screenshot

This theme works with 1280x800 screens. (If you have a different size screen, you will have to modify it)

Download: theme.tar.gz

Font: Droid Sans

Panel: tint2

  • Install from this PPA
  • the tint2rc file (from my theme package) to "~/.config/tint2/"

Background: custom (includes panel and conky backgrounds)

  • Either use my background (background.png) or replace the background layer in background.xcf with your own image and save it as a png.

Conky:

System Information and Calendar.

You can find them in the theme package.

To install:

  • Create a new folder "~/.conky/"

  • Copy "cal.conkyrc", "cal.py" and "system.conkyrc" to "~/.conky/"

  • Add a new startup item sh -c "conky -d -c ~/.conky/system.conkyrc; conky -d -c ~/.conky/cal.conkyrc"

Theme:

  • Metacity: Nooto
  • GTK2: Ghostship
  • Icons: Elementary

Write a file as root from a non-root vim.

Problem

I often edit config files in vim, try to save them, and then realize that I ran vim as a normal user and the config file is in /etc. In the past I would close vim and redo all of my changes as root (using sudo). This is a real pain especially if I had made a lot of changes.

Solution

Add the following to your ~/.vimrc:

cmap w!! w !sudo tee % >/dev/null<CR>:e!<CR><CR>

A while ago I came across this post that describes how to save a file as root from a non-root vim by adding cmap w!! w !sudo tee % >/dev/null to my .vimrc.

The problem is that, after running this command, vim will notice that the file has changed on disk and ask the user if he or she wants to reload it. After a while this got annoying, therefore the multiple CRs (enters) and the :e! (reloads the file).

Apt Repository Permissions

I just posted a solution to this idea but thought that I should share it here.

Here is the problem: In order to get the latest features on Ubuntu, people are adding a lot of PPAs. For now there hasn't, as far as I know, been a case in which a PPA owner has uploaded a malicious package but this is a possibility. Uploading an end user application, such as shutter, with malicious code would be problematic but not devastating. On the other hand, uploading a malicious sudo package would be devastating. Here is my solution.

Different repositories would "own" packages:

  1. Ownership would be set in a file such as /etc/apt/ownership/.list

  2. A special system packages file would be created that would designate system packages (sudo, pam etc...).

Apt repositories would have permissions:

  1. Ultimate Trust: Update and Install packages from this repository regardless of ownership including system packages

  2. All: Update and Install new packages from this repository regardless of ownership (except system owned packages).

  3. Owned only: Update and install only owned packages.

  4. No Updates: Install owned packages from this repository but do not download updates from it.

Flags:

  1. Warning: There would be a warning flag that a user could set on a repository that would warn when packages are updated or installed from that repository.

  2. System: There would be a system flag that could be set on security related packages (sudo, bash etc...) that would prevent all but "Ultimate Trust" repositories from installing/updating them.

Navigate text with vi(m) keys on linux

Intro

Lifehacker recently posted a AutoHotkey script for windows that allows text navigation using letters instead of the arrow keys. In response to @wersdaluv's post, I wrote a very simple script that allows users to navigate text using the standard vim keys (hjkl) when the caps-lock key is toggled. Feel free and add to my very basic script

Steps

  1. Download my script (via copy and paste) from ~~here~~. Lost (email if found).
  2. Save the script somewhere where you will not delete it and mark it as executable (chmod u+x /path/to/script.sh)
  3. Add the script to the startup programs with the argument init (i.e. /path/to/script.sh init). If you don't know how to add startup programs in your Desktop Environment, Google it.
  4. Assign F13 (the now remapped capslock key), as a hotkey in your window manager. Set the command to '/path/to/script.sh toggle'. Again, if you don't know how to add a hotkey, Google it.
  5. Now either log out and then in or run '/path/to/script.sh init' in order to remap the capslock key.
  6. Pressing the capslock key should now toggle navigation mode.

Bash completion with aptitude aliases

Problem

  1. If I used my alias for installing an application (inst application), I would have to know the full application name because I would not have bash completion. This was very annoying when installing libraries because they often have weird version strings tacked on to their ends.
  2. If I used the full command (sudo aptitude install application), I would have bash completion and would therefore not have to know the whole application name. I could simply type libxul and get libxul0d.

On one hand, I would type a short command plus a complected application name, on the other I would type a long command and a simple application name. I wanted to be able to type a short command with a simple application name.

Solution

I wrote my own bash completion rules. They are based on the default aptitude bash completion rules but customized for aliases.

# Install Completion
#
_aptitude_all()
{
        local cur dashoptions
 
        COMPREPLY=()
        cur=`_get_cword`
 
        dashoptions='-S -u -i -h --help --version -s --simulate -d \
                     --download-only -P --prompt -y --assume-yes -F \
                     --display-format -O --sort -w --width -f -r -g \
                     --with-recommends --with-suggests -R -G \
                     --without-recommends --without-suggests -t \
                     --target-release -V --show-versions -D --show-deps\
                     -Z -v --verbose --purge-unused'
       
        if [[ "$cur" == -* ]]; then
            COMPREPLY=( $( compgen -W "$dashoptions" -- $cur ) )
        else
                COMPREPLY=( $( apt-cache pkgnames $cur 2> /dev/null ) )
        fi
        return 0
}
_aptitude_installed()
{
        local cur dashoptions
 
        COMPREPLY=()
        cur=`_get_cword`
 
        dashoptions='-S -u -i -h --help --version -s --simulate -d \
                     --download-only -P --prompt -y --assume-yes -F \
                     --display-format -O --sort -w --width -f -r -g \
                     --with-recommends --with-suggests -R -G \
                     --without-recommends --without-suggests -t \
                     --target-release -V --show-versions -D --show-deps\
                     -Z -v --verbose --purge-unused'
       
        if [[ "$cur" == -* ]]; then
            COMPREPLY=( $( compgen -W "$dashoptions" -- $cur ) )
        else
                COMPREPLY=( $( _comp_dpkg_installed_packages $cur ) )
        fi
        return 0
}
complete -F _aptitude_all $default inst
complete -F _aptitude_all $default upgrade
complete -F _aptitude_all $default apt-info
complete -F _aptitude_all $default apt-changes
complete -F _aptitude_all $default apt-download
complete -F _aptitude_installed $default uninst
complete -F _aptitude_installed $default reinst
complete -F _aptitude_installed $default purge

Just copy it into a file such as ~/.bash_completion and source the file in your ~/.bashrc by adding ". ~/.bash_completion".

Change/Add/Remove the aliases at the end of the file. The lines that start with complete -F _aptitude_all complete any available or installed package and lines that start with complete -F _aptitude_installed complete only installed packages.

inst, upgrade, apt-info, apt-changes.... are my aliases. You must use YOUR ALIASES for this to work. To add aliases, read this.