Distributing Jython Apps in a Single JAR file
May 20, 2009 at 2:20 pm | In Java, Python | CommentsI've been writing a lot of one-off type applications at work lately, which is always kind of a joy for me because these sorts of applications don't need to be maintained or supported in any way, which means I can write them however I want.
So I write them in Python
Jython allows me to interface with all the plethora of Java libraries that we use at work, and it lets me program in a language that not only I can tolerate, but one that I respect and love.
But even though these are one-off applications, they still need to be easy to use, and in some cases I won't even be the one running the application. I want these applications to just work damnit.
So, packaging my Jython application into a single executable jar file that contains all of the third party dependancies inside is my goal. I want to send the user the jar file, have them double click on it, and have it immediately start running. It can't get a whole lot easier than that.
The Jython wiki has a page about doing something along these lines. The recipe there called the Jar Method works quite well. The one drawback that it has is that all of the Java dependancies need to be exploded into the main jar root, which when you're dealing with dozens of jar dependancies, it can start to get tedious, messy, and in some cases will even violate the license of a particular library.
One-Jar is a special class loader that can load a jar file that is inside of another jar file, something that the regular class loader from Sun is incapable of doing. Using One-Jar lets my application reside inside of a jar file and contain all my dependancies as seperate jar files inside the main jar file.
I've created a sample project that shows how I normally create a new Jython project hosted inside a single jar file with One-Jar. You'll need the following tools to check out the project:
* A Java SDK (tested with OpenJDK 1.6)
* Apache Ant (tested with version 1.7)
* Git (to checkout the project)
Check out the project like so:
git clone git://enigmacurry.com/single-jar-jython-example
Build the project:
cd single-jar-jython-example
antRun the example by double clicking it or via the command line:
java -jar JythonExcelExample.jarThis is just a demonstration app, it doesn't do a whole lot, it outputs an excel file in the current directory listing some computer parts. The point of the application is to show how Jython can integrate with existing Java third-party libraries (in this case Apache POI.)
Instructions for basing your own application on this example are contained inside the README.txt file.
Jython Shell Server — Adding a REPL to any Java app
March 1, 2009 at 2:10 pm | In Java, Python | CommentsI love programming in Python. I get paid to write Java though. Due to Java's verboseness, and lack of a REPL, this can be very frustrating for me.
In Python, the usual way I explore a new library or mock up a new idea is to immediately start coding in Python's interactive interpreter (or REPL). This is often times more efficient than reading (let alone finding) the documentation for the library. I can quickly see if something is going to work before I code inside my larger application.
Java doesn't have an interactive interpreter.. but Jython does! However, setting up Jython, especially interfacing with an already large Java application, can be difficult. One such difficult situation I deal with at work is in Weblogic. With Weblogic, I deploy my application directly to a running Weblogic server, and I never get to see a console in this process, so how am I ever going to run a Jython interactive interpreter?
This morning I got bored and wrote up a quick solution: JythonShellServer. JythonShellServer embeds into any Java application and starts a Telnet server that serves up Jython interactive shells. You can push any Java object that you want to manipulate into Jython's local environment. Run "telnet localhost 7000" and you can use Python code to explore your entire application's running environment.
JythonShellServer works, but I only just wrote it this morning, so consider it alpha quality at the moment. Check out the project page on github.
AutoComplete.el : Python Code Completion in Emacs
January 21, 2009 at 10:01 pm | In Emacs, Linux, Python | Comments
A friend of mine and I like to show off to each other little Emacs tips and tricks we learn. Today, he introduced to me the very cool AutoComplete.el package. AutoComplete.el is intriguing to me because, unlike ropemacs mode which I've blogged about before, the completions AutoComplete.el provides are inline with your code in a dropdown box instead of in a seperate window (windows in Emacs are what most people call frames). However, AutoComplete is only a completion framework, it doesn't know anything about Python. Instead, it allows the user to plug into it, feeding it whatever sorts of intelligent completion you want, including Rope.
Setup
The two most important completions I want to integrate into it are Rope and yasnippet. AutoComplete can handle both of them nicely. You'll need to install the very latest development version (as of December '08) of Rope, Ropemacs and Ropemode:
sudo apt-get install mercurial mkdir /tmp/rope && cd /tmp/rope hg clone http://bitbucket.org/agr/rope hg clone http://bitbucket.org/agr/ropemacs hg clone http://bitbucket.org/agr/ropemode sudo easy_install rope ln -s ../ropemode/ropemode ropemacs/ sudo easy_install ropemacs
You'll also need to install Pymacs and Yasnippet if you haven't already:
mkdir -p ~/.emacs.d/vendor && cd ~/.emacs.d/vendor wget http://pymacs.progiciels-bpi.ca/archives/Pymacs-0.23.tar.gz tar xfv Pymacs-0.23.tar.gz cd Pymacs-0.23 make sudo easy_install . cd ~/.emacs.d/vendor wget http://yasnippet.googlecode.com/files/yasnippet-0.5.9.tar.bz2 tar xfv yasnippet-0.5.9.tar.bz2 cd ~/.emacs.d ln -s vendor/yasnippet-0.5.9/snippets/ .
Make sure Pymacs and Yasnippet get into your load path, in your .emacs:
(add-to-list 'load-path "~/.emacs.d/vendor") (progn (cd "~/.emacs.d/vendor") (normal-top-level-add-subdirs-to-load-path))
Install AutoComplete.el 0.1.0 (0.2.0 is now out, and is not compatible with this post, I'll try and update later):
cd ~/.emacs.d/vendor wget http://www.emacswiki.org/emacs/?action=browse;id=auto-complete.el;raw=1;revision=5
Now to add some more elisp to your .emacs somewhere:
(require 'python) (require 'auto-complete) (require 'yasnippet) (autoload 'python-mode "python-mode" "Python Mode." t) (add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode)) (add-to-list 'interpreter-mode-alist '("python" . python-mode)) ;; Initialize Pymacs (autoload 'pymacs-apply "pymacs") (autoload 'pymacs-call "pymacs") (autoload 'pymacs-eval "pymacs" nil t) (autoload 'pymacs-exec "pymacs" nil t) (autoload 'pymacs-load "pymacs" nil t) ;; Initialize Rope (pymacs-load "ropemacs" "rope-") (setq ropemacs-enable-autoimport t) ;; Initialize Yasnippet ;Don't map TAB to yasnippet ;In fact, set it to something we'll never use because ;we'll only ever trigger it indirectly. (setq yas/trigger-key (kbd "C-c <kp-multiply>")) (yas/initialize) (yas/load-directory "~/.emacs.d/snippets") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Auto-completion ;;; Integrates: ;;; 1) Rope ;;; 2) Yasnippet ;;; all with AutoComplete.el ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun prefix-list-elements (list prefix) (let (value) (nreverse (dolist (element list value) (setq value (cons (format "%s%s" prefix element) value)))))) (defvar ac-source-rope '((candidates . (lambda () (prefix-list-elements (rope-completions) ac-target)))) "Source for Rope") (defun ac-python-find () "Python `ac-find-function'." (require 'thingatpt) (let ((symbol (car-safe (bounds-of-thing-at-point 'symbol)))) (if (null symbol) (if (string= "." (buffer-substring (- (point) 1) (point))) (point) nil) symbol))) (defun ac-python-candidate () "Python `ac-candidates-function'" (let (candidates) (dolist (source ac-sources) (if (symbolp source) (setq source (symbol-value source))) (let* ((ac-limit (or (cdr-safe (assq 'limit source)) ac-limit)) (requires (cdr-safe (assq 'requires source))) cand) (if (or (null requires) (>= (length ac-target) requires)) (setq cand (delq nil (mapcar (lambda (candidate) (propertize candidate 'source source)) (funcall (cdr (assq 'candidates source))))))) (if (and (> ac-limit 1) (> (length cand) ac-limit)) (setcdr (nthcdr (1- ac-limit) cand) nil)) (setq candidates (append candidates cand)))) (delete-dups candidates))) (add-hook 'python-mode-hook (lambda () (auto-complete-mode 1) (set (make-local-variable 'ac-sources) (append ac-sources '(ac-source-rope) '(ac-source-yasnippet))) (set (make-local-variable 'ac-find-function) 'ac-python-find) (set (make-local-variable 'ac-candidate-function) 'ac-python-candidate) (set (make-local-variable 'ac-auto-start) nil))) ;;Ryan's python specific tab completion (defun ryan-python-tab () ; Try the following: ; 1) Do a yasnippet expansion ; 2) Do a Rope code completion ; 3) Do an indent (interactive) (if (eql (ac-start) 0) (indent-for-tab-command))) (defadvice ac-start (before advice-turn-on-auto-start activate) (set (make-local-variable 'ac-auto-start) t)) (defadvice ac-cleanup (after advice-turn-off-auto-start activate) (set (make-local-variable 'ac-auto-start) nil)) (define-key python-mode-map "\t" 'ryan-python-tab) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; End Auto Completion ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Github
These changes are also applied to my Emacs environment on Github. I'm continuously trying to improve my emacs setup, so if you're reading this a few months/years after this post was made, you may want to check there for improvements.
Update Jan 30 2009: I made some modifications to the tab complete order, a regular indent is applied first before autocompletion. Autocompletion is also not applied unless you are at the end of a word. This is useful when you press Tab at the beginning of a line to indent/outdent.
Usage
Once you got everything setup, usage is real easy:
- Open up a python (.py) file
- Press TAB when you want to use code completion or to insert a snippet.
The first time you attempt to use code completion you'll be prompted to enter the root of your project directory.
Future
It wasn't too long ago when Python code completion inside Emacs was just a pipedream. So now that we have it, let's make some more pipedreams: I'd like to popup some nice contextual help for method arguments as well as python documentation for the current method/class being completed.
The possibilities are pretty much endless. I love Emacs.
My Emacs config on Github
January 19, 2009 at 5:01 pm | In Emacs, Python | CommentsThe most popular post on this blog is Emacs as a powerful Python IDE. I get quite a few emails regarding that post and I realized the other day that I've done a lot of customizations to my .emacs, and subsequently that post is starting to get a little dated. Time is a curious creature, it seems like yesterday that I wrote that post, but it's been almost 9 months now.
I've been learning and playing around with git recently, so I've decided to post my entire .emacs config on github.
Here are the latest instructions for emulating my Emacs environment on Ubuntu 8.10:
- Enable the universe repository
- sudo apt-get update
- sudo apt-get install emacs-snapshot git-core automake libgconf2-dev texinfo python-setuptools
- cd ~
- git clone git://github.com/EnigmaCurry/emacs .emacs.d
- cd ~/.emacs.d
- git submodule init
- git submodule update
- cd ~/.emacs.d/vendor
- ./vendor-compile.sh
- sudo easy_install "http://downloads.sourceforge.net/rope/rope-0.9.1.tar.gz?modtime=1225268769&big_mirror=0"
- sudo easy_install "http://downloads.sourceforge.net/rope/ropemacs-0.6.tar.gz?modtime=1223039342&big_mirror=0"
I've done some reorganization of the directory structure:
- There actually is no ~/.emacs file anymore, having realized that Emacs looks for ~/.emacs.d/init.el. Convenient!
- All third party packages are now installed in ~/.emacs.d/vendor. This was a great tip I saw in the Emacs Peepcode screencast. (it's $9, but worth it).
- I've taken the suggestion that greg made in the comments to use submodules for some of the vendor packages. The vendor-compile.sh script does the compiling of those packages.
- All private code goes in ~/.emacs.private. This lets me keep passwords and such outside of the main git repository and allows me to publish my config more easily. Before I did this I had to spend time sanitizing the code before each release.
I have appreciated your many encouraging Emails and comments.
Shortened URLs in Emacs using is.gd (like tinyurl)
September 15, 2008 at 11:11 am | In Emacs, Python | CommentsI've casually been teaching myself emacs lisp lately. Today I wrote a utility that shortens long urls within regions using the http://is.gd URL shortening service. There's plenty of existing code out there that is more lisp like, but this is supposed to be a learning experience for me so I did it myself. I like python and so I used python for most of the heavy lifting.
I created a directory to hold all of my emacs specific python functions: ~/.emacs.d/ryan-pymacs-extensions
I wrote the following python function, shorten_url.py in that directory:
!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = "Ryan McGuire (ryan@enigmacurry.com)" __date__ = "Mon Sep 15 12:27:14 2008" import doctest import urllib2 import re def shorten_with_is_gd(url): """Shorten a URL with is.gd >>> shorten_with_is_gd('http://www.enigmacurry.com') 'http://is.gd/FFP' """ u = urllib2.urlopen("http://is.gd/api.php?longurl="+url) return u.read() def shorten_in_text(text): """Shorten all the urls found inside some text >>> shorten_in_text('Hi from http://www.enigmacurry.com') 'Hi from http://is.gd/FFP' """ replacements = {} #URL -> is.gd URL #Only check for urls that start with "http://" for now for m in re.finditer("http://[^ \n\r]*", text): try: replacements[m.group()] = shorten_with_is_gd(m.group()) except: replacements[m.group()] = m.group() for url,replacement in replacements.items(): text = text.replace(url, replacement) return text if __name__ == '__main__': doctest.testmod(verbose=True)
and the following lisp makes "M-x shorten-url" do the rest of the replacement work:
;add ~/.emacs.d/ryan-python-extensions to python path (pymacs-exec "import sys, os") (pymacs-exec "sys.path.append(os.path.join(os.path.expanduser('~'),'.emacs.d','ryan-pymacs-extensions'))") ;;Shorten URLs with is.gd (pymacs-exec "import shorten_url") (defun shorten-url (start end) (interactive "r") (let ((region (buffer-substring start end))) (let ((rt (pymacs-eval (format "shorten_url.shorten_in_text('''%s''')" region)))) (kill-region start end) (insert rt) ) ))
Importing foreign (non-iCal) calendars into Google Calendar
August 19, 2008 at 3:24 pm | In Free State Project, Python | CommentsGoogle Calendar is highly useful. I use it to keep track of all my appointments and due dates and I get helpful reminders when dates approach via email and SMS. Not only that, but it allows me to collaborate with other people's calendars as well, and they don't even have to use Google Calendar because Google supports the industry standard iCalendar format. Things are great.
Unfortunately, iCalendar format is pretty new, and not everyone is using it.
Because Google Calendar is so useful, it is annoying when you find a calendar that is not in iCal format. Two of note that I want to follow are
Both of these calendars are running Simple Machines Forum, version 1.x which does not support iCalendar format (presumably they will in 2.0).
So I wrote an exporter: Download SMF iCal exporter
The exporter scrapes the calendar page on an SMF enabled site and dumps out an iCal compatible file.
Usage: smf_ical_converter.py -u http://yourforum.com/index.php -o cal.ics
Download a SMF 1.x forum calendar and dump in iCal format
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-u URL, --url=URL URL of forum (up to and including /index.php)
-n Name, --name=Name Name of the Forum / Calendar (name goes in .ics file)
-i EXPR, --ignore-re=EXPR
Ignore any event containing this regular expression
(specify as many -i as you want)
-o File, --output=File
iCal filename to write
-v, --verbose Be verbose about process
--months-backward=NUM
Number of months to go backward
--months-forward=NUM Number of months to go forward
I have this tool running in a cron job to keep up to date with the two above mentioned calendars. You can import these URLs directly into your Google Calendar:
- NHUnderground.com iCal calendar
- FreeKeene.com iCal calendar
(Includes just events, I use "-i 'Birthdays:'" for this one)
Update 09/16/08: I uploaded version 2 of this application. It has a better README and it now supports user specific date ranges.
Emacs IRC (ERC) with Noticeable Notifications
August 7, 2008 at 12:35 am | In Emacs, Linux, Lisp, Python | CommentsI use ERC for all my IRC chatting. I finally got fed up with not noticing someones message because I didn't have emacs focused. So I spent my evening concocting a more noticeable messaging system through Pymacs and libnotify.
Half way though implementing this, wouldn't you know it, I found ErcPageMe which does exactly what I wanted. I figured I was learning quite a bit and I continued writing my own version. I expanded on their code and (at least for me) made some improvements. So kudos go to whoever wrote ErcPageMe
The following code will pop up a message on your gnome desktop alerting you whenever you receive a personal message or when someone mentions your nickname in a channel. It also avoids notification for the same user in the same channel if they triggered a message within the last 30 seconds.

Here is my lisp and embedded python/pymacs code:
(defun notify-desktop (title message &optional duration &optional icon) "Pop up a message on the desktop with an optional duration (forever otherwise)" (pymacs-exec "import pynotify") (pymacs-exec "pynotify.init('Emacs')") (if icon (pymacs-exec (format "msg = pynotify.Notification('%s','%s','%s')" title message icon)) (pymacs-exec (format "msg = pynotify.Notification('%s','%s')" title message)) ) (if duration (pymacs-exec (format "msg.set_timeout(%s)" duration)) ) (pymacs-exec "msg.show()") ) ;; Notify me when someone wants to talk to me. ;; Heavily based off of ErcPageMe on emacswiki.org, with some improvements. ;; I wanted to learn and I used my own notification system with pymacs ;; Delay is on a per user, per channel basis now. (defvar erc-page-nick-alist nil "Alist of 'nickname|target' and last time they triggered a notification" ) (defun erc-notify-allowed (nick target &optional delay) "Return true if a certain nick has waited long enough to notify" (unless delay (setq delay 30)) (let ((cur-time (time-to-seconds (current-time))) (cur-assoc (assoc (format "%s|%s" nick target) erc-page-nick-alist)) (last-time)) (if cur-assoc (progn (setq last-time (cdr cur-assoc)) (setcdr cur-assoc cur-time) (> (abs (- cur-time last-time)) delay)) (push (cons (format "%s|%s" nick target) cur-time) erc-page-nick-alist) t) ) ) (defun erc-notify-PRIVMSG (proc parsed) (let ((nick (car (erc-parse-user (erc-response.sender parsed)))) (target (car (erc-response.command-args parsed))) (msg (erc-response.contents parsed))) ;;Handle true private/direct messages (non channel) (when (and (not (erc-is-message-ctcp-and-not-action-p msg)) (erc-current-nick-p target) (erc-notify-allowed nick target) ) ;Do actual notification (ding) (notify-desktop (format "%s - %s" nick (format-time-string "%b %d %I:%M %p")) msg 0 "gnome-emacs") ) ;;Handle channel messages when my nick is mentioned (when (and (not (erc-is-message-ctcp-and-not-action-p msg)) (string-match (erc-current-nick) msg) (erc-notify-allowed nick target) ) ;Do actual notification (ding) (notify-desktop (format "%s - %s" target (format-time-string "%b %d %I:%M %p")) (format "%s: %s" nick msg) 0 "gnome-emacs") ) ) ) (add-hook 'erc-server-PRIVMSG-functions 'erc-notify-PRIVMSG)
cycle_xrandr.py : dual and single displays on Ubuntu
July 10, 2008 at 6:24 am | In Linux, Python | CommentsLinux power management has gotten good recently. My last two laptops (HP dv9000 and Macbook Pro) have supported hardware suspend mode out of the box. I'm impressed!
Being that I hardly ever turn off the laptop (I just suspend now) I'm left with an annoyance: I use two displays at work and one everywhere else. In Ubuntu, I was easily able to setup dual and single modes such that when I boot up, Xorg detects how many displays are connected appropriately. But now that I don't turn off the machine, I want to be able to just plug in another monitor and go. I don't want to have to reboot the computer. I don't even want to have to log out. I want to plug the monitor in, leave all my apps running and in the state they are in.
Xrandr does this and it works great. But what if I'm in dual display mode but I only actually have one monitor connected? Can I get to an open terminal to use xrandr? Easily? Probably not.
I wrote the following python script to take care of this. It detects all of the modes that xrandr knows about and cycles to the next size listed. I then bind this script to a custom keyboard shortcut so I don't have to type or even see anything on the screen:
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = "Ryan McGuire (ryan@enigmacurry.com)" __date__ = "Thu Jul 10 15:27:18 2008" """Cycle through all screen resolutions detected by xrandr""" from subprocess import Popen, PIPE import re size_re = re.compile("^ ([0-9]*x[0-9]*)\W*[0-9]*\.[0-9]*(\*)?") def list_sizes(): """List all sizes detected by xrandr, ordered by the next resolution to cycle to""" p1 = Popen(['xrandr'], stdout=PIPE) sizes = [] current_size_index = 0 for line in p1.communicate()[0].split("\n"): m = size_re.match(line) if m: sizes.append(m.group(1)) if m.group(2) == "*": current_size_index = len(sizes) - 1 return sizes[current_size_index+1:] + sizes[:current_size_index+1] if __name__ == '__main__': Popen(['xrandr','-s',list_sizes()[0]])
Emacs as a powerful Python IDE
May 9, 2008 at 3:27 pm | In Emacs, Enigma Curry, Python | CommentsUpdate 01/2009: this post is still valid, but see updated installation instructions here.
Last night at the Python user group I gave a short demo on using Emacs as a Python editor/IDE. My macbook pro refused to display on the projector so I thought my demo was going to be a 'no go'. Thankfully, sontek allowed me to use his Linux laptop. I hurriedly copied over my emacs environment, installed a few packages and was able to present after all. I think the demo went fairly well even though I think it was a bit hurried and I forgot to cover a few things, I think I was pretty nervous at the same time because of the fact that the mac didn't work and got me flustered. Oh well, I think people enjoyed it.
My Emacs Environment
Below are the Emacs features most applicable to Python development:
- Rope and Ropemacs
Rope is a general (non-emacs specific) Python IDE library. It has awesome support for multiple refactoring methods and code introspection. Inside Emacs, this gives us:- Full (working!!) code-completion support of modules, classes, methods etc. (M-/ and M-?)
- Instant documentation for element under the cursor (C-c d)
- Jump to module/class/method definition of element under the cursor (C-c g). This works for any Python code it finds in your PYTHONPATH, including things from the stdlib.
- Refactoring of code (like rename — C-c r r)
- List all occurences of of a name in your entire project
- and More.
- YASnippet
YASnippet is a snippet tool like TextMate. You can expand user defined keywords into whole blocks of predefined code. This is especially useful for the usual boilerplate that would go into a python file like#!/usr/bin/env python
and
if __name__ == '__main__':Granted, Python doesn't require much boilerplate, and therefore this package is much more suited to languages like Java, but I bring it up because I think its cool and if you get into the habit of using it, then a few keystrokes saved here and there will add up over time.
- Subversion support with psvn.el
Psvn is a comprehensive subversion client for Emacs. It integrates well with ediff mode so you can use it to check changes between versions. It does all of the other boring subversion stuff well too. - Ido-mode for buffer switching and file opening.
Emacs, to the uninitiated, can be confusing because by default there is only one view into a single file at a time. How does one get to another file? Instead of cluttering the interface with GUIness and making the user click somewhere (and thereby forcing the user to waste their time by moving their hand off of the keyboard), Emacs gives powerful ways to switch between files. Ido-mode is one of these useful ways — it makes a list of open files starting with the most frequently visted files and widdles this list down as you type part of the filename. You can have dozens of files open and only be a few keystrokes away from any one of them.
A lot of people, for whatever reason, don't feel that Emacs is an IDE at all. I don't personally care what you define it as — the fact remains — Emacs is a powerful Python environment and despite being over 32 years old has proven to be just as modern as any IDE today, and remains THE most configurable editor (operating system?) ever.
I've tarred up my Emacs environment for general consumption. Instructions:
- Install Pymacs
- Install Rope and Ropemacs
- BTW, those three packages should be the only packages other than Emacs you'll need. Everything else is self contained.
- Extract the tarball to your home directory. This creates a directory called ryan-emacs-env.
- Rename "ryan-emacs-env" to ".emacs.d"
- Symlink my dot-emacs file to your .emacs. Run "ln -s .emacs.d/dot-emacs .emacs".
- If you also want to do Java development run "tar xfvz jde-2.3.5.1.tar.gz". I leave it tarred because you don't need to pollute your environment if you're not going to use Java. (Also for whatever reason, jde doesn't like to be stuck in my subversion repository so I just leave it tarred up and untar on every machine I check it out on.)
Extra tips:
- Put your .emacs.d directory under version control. Never rely on your distros emacs packages, install all future elisp files yourself in your .emacs.d file and commit to your repository often. This way you've got an environment that is easily transportable and synchronizable across multiple machines. This is the major reason why my emacs environment was so fast to trasnfer from my macbook pro to sontek's laptop during the demo.
- Speaking of sontek, he brought up an excellent point in #utahpython the other day, he's not going to be using my emacs environment except for reference, instead he's starting with a clean slate. This is by far the best and most prudent thing to do. My emacs environment is a culmination of several years of plugging in and deleting various packages and writing various snippets of elisp. Your needs are always going to be different than mine and you are also going to be better off by educating yourself along the way by creating your own.
Some more fun Emacs evangelism:
- a fascinating screencast of Emacs in the role of Ruby editor (many tips here apply to Python too)
- Emacs blogs I read:
- Emacs life
- Life is too short for bad code
- Minor Emacs Wizardry
- M-x all-things-emacs
- Platypope.org
- Know of any other good ones? Let me know.
New Slacker Screenlet released
April 4, 2008 at 10:43 pm | In Linux, Python | CommentsCheck it out: I updated my Slacker Screenlet today.
New in this version:
- Bug fixed where the screenlet-manager would respawn infinitely
- Integrated LastSlacker support
You can read more about the original version in my previous post.
LastSlacker is a way to scrobble what you listen to on Last.FM. This lets you share a log of what you listen to with friends. I've been meaning to add this feature for a long time now, until today it's been in a sorta working state for months! It feels good to have finally gotten this project pretty much finished.
Powered by WordPress.
Entries and comments feeds.
XML Sitemap
TEST NEW

