Commits

Anonymous committed b53fa46

Import from Berlios

Comments (0)

Files changed (6)

+Copyright (c) 2007, Miki Tebeka <miki.tebeka@gmail.com>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of the "TLL" nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+VERSION=$(shell ./tll --version | cut -d' ' -f2)
+DISTDIR=tll-$(VERSION)
+DISTFILE=$(DISTDIR).tar.bz2
+
+all: dist
+
+dist: deldist
+	mkdir $(DISTDIR)
+	cp `svn ls -rHEAD` $(DISTDIR)
+	tar -cjf $(DISTFILE) $(DISTDIR)
+
+README.html: README.txt
+	rst2html $< $@
+
+deldist:
+	(test -d $(DISTDIR) && rm -fr $(DISTDIR)) || true
+
+clean: deldist
+	(test -f README.html && rm README.html) || true
+	(test -f $(DISTFILE) && rm $(DISTFILE)) || true
+
+push:
+	scp $(DISTFILE) tebeka@shell.berlios.de:/home/groups/ftp/pub/tll
+
+fresh: clean all
+
+.PHONY: all dist clean fresh deldist push
+==========================
+"tll" version 0.3.1 README
+==========================
+:Author: Miki Tebeka <miki.tebeka@gmail.com>
+:Date: 01/08/2009
+
+.. contents::
+
+What is "tll"
+=============
+tll is a very minimal application launcher for Linux based systems.
+
+If you are on Mac try QuickSilver_, on Windows try Launchy_ or SlickRun_.
+
+Installation
+============
+Just place `tll` somewhere in your path and edit `~/.tllrc`.
+
+Running
+=======
+Assign a keystroke to invoke it [#]_ and you're done.
+
+`tll` has a simple history, hit <UP-ARROW> or <DOWN-ARROW> to scroll the
+history.
+
+Configuration File
+==================
+`$HOME/.tllrc` has the following syntax:
+::
+    
+    # tll Aliases
+
+    www = firefox
+    mail = thunderbird
+    term = Terminal
+    oo = soffice
+    im = pidgin
+
+Downloading etc
+===============
+See http://developer.berlios.de/projects/tll/.
+
+
+.. _QuickSilver: http://quicksilver.blacktree.com/
+.. _SlickRun: http://www.bayden.com/SlickRun/
+.. _Launchy: http://www.launchy.net/
+.. [#] "Settings->Keyboard Settings->Shortcuts" in XFCE_, see here_ for GNOME_.
+.. _XFCE: http://www.xfce.org
+.. _here: http://www.cyberciti.biz/faq/howto-create-keyboard-shortcuts-in-gnome/
+.. _GNOME: http://www.gnome.org/
+
+
+.. comment: vim:ft=rst spell
+#!/bin/bash
+# Open a file from command line, multi OS
+
+# Miki Tebeka <miki.tebeka@gmail.com>
+
+if [ $# -ne 1 ]; then
+    echo "usage: `basename $0` PATH"
+    exit 1
+fi
+
+# Taken from http://pypi.python.org/pypi/desktop/0.3
+linux_open()
+{
+    if [ -n "$GNOME_DESKTOP_SESSION_ID" ]; then
+        if which gvfs-open > /dev/null; then
+            echo "gvfs-open"
+        else
+            echo "gnome-open"
+        fi
+    elif [ -n "$KDE_FULL_SESSION" ]; then
+        echo "kfmclient exec"
+    elif xprop -root _DT_SAVE_MODE 2>&1 | grep -iq xfce; then
+        echo "exo-open"
+    else
+        echo ""
+    fi
+}
+
+case `uname` in
+    Linux) open=`linux_open`;;
+    Darwin) open=open;;
+    CYGWIN*) open=cygstart;;
+    MINGW*) open=start;;
+esac
+
+if [ -z "$open" ]; then
+    echo "error: no start program for `uname` platform" 1>&2
+    exit 1
+fi
+
+$open "$1" > /dev/null 2>&1
+#!/usr/bin/env python
+'''Simple launcher'''
+
+__author__ = "Miki Tebeka <miki.tebeka@gmail.com>"
+__version__ = "0.3.1"
+
+import Tkinter as tk
+from tkFont import Font
+from tkMessageBox import showerror
+from threading import Timer
+
+from os.path import exists, expanduser, join, isfile
+from os import environ, popen, stat, system
+from stat import S_IEXEC
+from string import strip
+
+def unique(items):
+    seen = set()
+    for item in items:
+        if item in seen:
+            continue
+        seen.add(item)
+        yield item
+
+def config_file(base_file, env_key):
+    filename = ""
+    if env_key in environ:
+        return environ[env_key]
+    elif "HOME" in environ:
+        return join(environ["HOME"], base_file)
+
+    return ""
+
+class History:
+    histnames = (".tll_history", "TLL_HISTORY")
+
+    def __init__(self, history=None):
+        self.history = list(history) if history else []
+        self.index = 0
+
+    def with_config_file(self, func, mode):
+        histfile = config_file(*self.histnames)
+        if (not histfile) or ((mode[0] == "r") and (not isfile(histfile))):
+            return
+
+        try:
+            fo = open(histfile, mode)
+            return func(fo)
+        finally:
+            fo.close()
+
+    def load(self):
+        def _load(fo):
+            history = filter(None, map(strip, fo))
+            history = list(unique(history))
+
+            self.history = history
+
+        self.with_config_file(_load, "r")
+
+    def save(self):
+        def _save(fo):
+            for item in unique(self.history):
+                print >> fo, item
+            fo.close()
+
+        self.with_config_file(_save, "wt")
+
+    def update(self, newline):
+        old = filter(lambda line: line != newline, self.history)
+        self.history = [newline] + old
+
+    def next(self, step):
+        self.index = (self.index + step) % len(self.history)
+        return self.history[self.index]
+
+def load_aliases():
+    rcfile = config_file(".tllrc", "TLLRC")
+
+    if (not rcfile) or (not isfile(rcfile)):
+        return {}
+
+    aliases = {}
+    for line in open(rcfile):
+        line = line.strip()
+        if (not line) or (line[0] == "#"):
+            continue
+        alias, target = map(strip, line.split("=", 1))
+
+        aliases[alias] = target
+
+    return aliases
+
+def is_executable(path):
+    if not isfile(path):
+        return 0
+
+    return S_IEXEC & stat(path).st_mode
+
+def launch(name, args, aliases):
+    fullname = aliases.get(name, name)
+
+    if " " in fullname:
+        fullname, xargs = fullname.split(" ", 1)
+        args = "%s %s" % (xargs, args)
+
+    fullname = expanduser(fullname)
+    if not exists(fullname):
+        fullname = popen("which %s 2>/dev/null" % fullname).read().strip()
+        if not fullname:
+            raise ValueError("can't find %s" % name)
+
+    if is_executable(fullname):
+        system("\"%s\" %s&" % (fullname, args))
+    else:
+        system("start \"%s\"" % fullname)
+
+class TLL:
+    def __init__(self, history):
+        self.user_cancel = 0
+        self.history = history
+        self.root = root = tk.Tk()
+        root.title("TLL")
+        root.bind("<Escape>", self.quit)
+        font = Font(family="Courier", size=40, weight="bold")
+        self.command = cmd = tk.Entry(root, width=20, font=font)
+        cmd.pack(fill=tk.BOTH)
+        cmd.bind("<Return>", lambda e: root.quit())
+        cmd.bind("<Up>", lambda e: self.move(-1))
+        cmd.bind("<Down>", lambda e: self.move(1))
+
+        self.center_on_screen()
+
+    def run(self):
+        self.command.focus()
+        self.root.mainloop()
+
+    def quit(self, event):
+        self.user_cancel = 1
+        self.root.quit()
+
+    def move(self, step):
+        line = self.history.next(step)
+        self.command.delete(0, tk.END)
+        self.command.insert(0, line)
+
+    def get(self):
+        return self.command.get().strip()
+
+    # http://mail.python.org/pipermail/tutor/2006-December/051337.html
+    def center_on_screen(self):
+        root = self.root
+        width = root.winfo_width()
+        height = root.winfo_height()
+        if width == 1 and height == 1:
+            # If the window has not yet been displayed, its size is
+            # reported as 1x1, so use requested size.
+            width = root.winfo_reqwidth()
+            height = root.winfo_reqheight()
+
+        # Place in centre of screen:
+        x = (root.winfo_screenwidth() - width) / 2
+        y = (root.winfo_screenheight() - height) / 3
+        x = max(x, 0)
+        y = max(y, 0)
+        root.geometry('+%d+%d' % (x, y))
+
+def set_user_path():
+    if "HOME" not in environ:
+        return
+
+    new_path = "%s:%s" % (join(environ["HOME"], "bin"), environ["PATH"])
+    environ["PATH"] = new_path
+
+def main(argv=None):
+    if argv is None:
+        import sys
+        argv = sys.argv
+
+    from optparse import OptionParser
+
+    parser = OptionParser(usage="usage: %prog", 
+            version="tll %s" % __version__)
+
+    opts, args = parser.parse_args(argv[1:])
+    if len(args) != 0:
+        parser.error("wrong number of arguments") # Will exit
+
+    set_user_path()
+
+    aliases = load_aliases()
+    history = History()
+    history.load()
+
+    while 1:
+        try:
+            history.index = 0
+            ui = TLL(history)
+            # Quit after 30 seconds
+            timer = Timer(30, ui.quit, (None, ))
+            timer.start()
+            ui.run()
+            timer.cancel()
+
+            if ui.user_cancel:
+                raise SystemExit
+
+            command = ui.get()
+            if not command:
+                showerror("TLL Error", "Please enter *something*")
+                continue
+
+            history.update(command)
+            history.save()
+
+            if " " in command:
+                command, args = command.split(" ", 1)
+            else:
+                args = ""
+            launch(command, args, aliases)
+            break
+        except ValueError:
+            showerror("TLL Error", "Can't launch %s" % command)
+            raise SystemExit
+
+if __name__ == "__main__":
+    main()
+# Launchie Aliases
+
+www = firefox
+mail = Terminal -x mutt
+term = Terminal
+oo = soffice
+im = pidgin
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.