Ambient Composition 1
May 31, 2009 at 3:24 pm | In Music | CommentsI've always wished that I was a musician, I love music. When I was young, my parents even paid for piano lessons, although I gave that up shortly after. Back then I saw it as tedious, and I never saw any real improvement.
I'm hoping to change direction. I seem to always have a tune inside my head and it needs to get out!
I recently bought a new computer powerful enough to run some pretty amazing software synthesizers, so I've started composing some music. Here's a pretty basic one I wrote today:
(press play or right click here to download)
It's pretty ambient. This is for two reasons:
- I actually like ambient music, eg. Harold Budd or The Dead Texan.
- It's got a low barrier to entry, nice long whole notes.
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.
256 colors on the Linux terminal
January 20, 2009 at 12:30 pm | In Emacs, Linux | CommentsI've been using Linux as my main OS for well over a decade now. I can hardly believe I didn't pick up on this tip before.
On your linux desktop, open up your favorite terminal emulator. Enter this command:
tput colors
What number do you see? 8?
8 stinking colors. That's what my terminal is capable of displaying. It's 2009 folks, and my terminal can only display 8 stinking colors.
Load up emacs in the terminal (emacs -nw) and see for yourselves, M-x list-colors-display shows you all of the different colors your terminal can display.

Pitiful.
Ok, so how to improve this? On ubuntu:
sudo apt-get install ncurses-term
and stick the following in your ~/.bashrc and/or ~/.bash_profile:
export TERM=xterm-256color

Ahhhhh…
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.
Extending Emacs with Advice
January 14, 2009 at 4:30 pm | In Emacs | CommentsThe greatest single thing about Emacs is it's extensibility. If you think Emacs is missing something, or don't like how something works, you can change it. But that's true of any open-source software. The difference with Emacs is how easy it is to make that change.
There are several different strategies to extend Emacs. I'll list a few of them in order of hardest to easiest (and arguably from worst to best):
- Write your own major or minor mode from scratch.
- Edit someone else's mode (and hopefully submit a patch.)
- Write an Advice function.
- Write a Mode Hook.
Where Advice fits in
(Don't worry, I get into the meat of it in the next section. For the impatient, skip down.)
Mode hooks are almost always the easiest and best way to extend a particular mode, but they are also limited in scope. The author of the mode created these hooks specifically to allow you to extend his mode, and are therefore the best maintainable way to extend a mode (the author is unlikely to remove those hooks in future versions). However, if the author didn't anticipate certain functionality and there is no appropriate hook provided, you'll have to come up with a different solution.
At this point, obviously, you could just write your own mode — but what a pain that would be if you already have something that's close to what you want. So why not just edit that particular mode to suit your needs (perhaps creating that missing mode hook yourself?) This approach is probably the best one especially if the feature you want is something other people would benefit from. You can submit your changes as a patch to the original author and (if he accepts them) your changes go into the next release.
But what if for some reason your changes are not acceptable to the author? You can still use your changes on your local machine, but every time a new version of the original mode comes out you'll have to merge your changes back into that new version. At this point you've successfully "forked" the project, but that's usually a bad thing in the long run.
One other option exists to Emacs developers: advice. Advice allows you to wrap existing functions with your own functions. This allows some types of behavior to be modified without even having to change the original file at all. You can keep your changes completely separated in your own customized files. This gives you the benefit of inheriting new versions of the mode by simply downloading the new version and putting it in your load path. In most cases your advice function will continue to work on the new version and you didn't have to merge any changes at all. If significant changes have been made you may need to modify your advice function, or create a new one, but you still won't need to merge any changes.
Continue reading and I'll give you a real-world example of how I've used advice, but I want to first re-iterate the proper use cases of advice:
- If you can use the mode hooks provided by the author, use them instead.
- If there is a bug in the original mode, just fix it in the original code and submit a patch.
- If there is a new feature you want, add it to the original mode and submit a patch. Talk to the author, work with him, and it will most likely end up in the next release.
- If you are an Emacs developer, working on Emacs itself, or one of the modes shipped with Emacs, never use advice. It's the least maintainable method of extending Emacs with the exception of a pure fork, and since you're working on Emacs itself, it's not a fork.
- If your patch is not accepted, or you know that what you want is fringe enough or hackish enough to not warrant submitting a patch, only then should you use advice or fork the project.
Using Advice
Alright, onward to the example I promised. I really liked the tip over at Minor Emacs Wizardry on combining EasyPG with Org mode — it's an awesome way to keep a lot of things in an organized and encrypted way — I use it all the time now.
My main machine is running Ubuntu and it's default GnuPG agent is Seahorse. It's actually a pretty nice manager for encryption (SSH and PGP) and is completely integrated with the Gnome desktop. The one problem I have with it is that I use Multi-TTY Emacs and when I'm using a terminal on a remote connection and I try and open an encrypted file, Seahorse pops up on the desktop instead of prompting me for the passphrase on my remote connection. In the past I've had to fire up VNC to my desktop just so that I could enter the password; damn inconvenient.
I could setup something like keychain, it's a real nice GPG agent that works equally well on the desktop as on the console. I've used it in the past and liked it. Seahorse requires no setup though, it comes with Ubuntu by default, and like I said, I really quite like it.
So, when I'm on my remote connection and Seahorse doesn't have my password cached, I'd like to be able to bypass the GPG agent entirely and just enter my password. EasyPG doesn't appear to have this functionality so I added it with advice:
(defadvice epg--start (around advice-epg-disable-agent disable) "Make epg--start not able to find a gpg-agent" (let ((agent (getenv "GPG_AGENT_INFO"))) (setenv "GPG_AGENT_INFO" nil) ad-do-it (setenv "GPG_AGENT_INFO" agent)))
That little bit of code wraps the main EasyPG function that will ask for a password. It temporarily removes the environment variable that EasyPG looks for to connect to the GPG agent, and therefore EasyPG asks the user for the password as if there were no agent running.
Let's analyze the different parts of that advice function:
- All advice starts with a "defadvice" definition.
- "epg–start" is the name of the original function I'm wrapping.
- "around" is indicating that I'm specifying code to run both before and after the function I'm wrapping (other options would include "before" and "after")
- The word "disable" means that the advice is initially turned off (you could say "activate" to have it immediately turned on, read the manual for more options here)
- Starting with the "let" function is the body of my custom function
- The "ad-do-it" line in the middle is the point in the function where the original function gets executed. (This would not be used in a "before" or "after" style function.)
One more important thing to understand about advising a function is that you aren't creating a new function with a new name. You are adding data to the existing function definition. Wherever the original function gets called, your advice will be called along with it. However, advice does offer the convenience of turning on or off your changes. For the above example I added two user commands to turn on and off the GPG agent (bound to M-x epg-disable-agent and M-x epg-enable-agent):
(defun epg-disable-agent () "Make EasyPG bypass any gpg-agent" (interactive) (ad-enable-advice 'epg--start 'around 'advice-epg-disable-agent) (ad-activate 'epg--start) (message "EasyPG gpg-agent bypassed")) (defun epg-enable-agent () "Make EasyPG use a gpg-agent after having been disabled with epg-disable-agent" (interactive) (ad-disable-advice 'epg--start 'around 'advice-epg-disable-agent) (ad-activate 'epg--start) (message "EasyPG gpg-agent re-enabled"))
These functions use the (ad-enable-advice) and (ad-disable-advice) functions respectively. Whenever advice is switched on or off, a call to (ad-activate) must also be made on the function to update it.
The manual goes into more depth about how to advice functions. Hopefully you got something useful out of this, I sure learned a lot in writing it.
Emacs ansi-term tricks
December 26, 2008 at 11:30 am | In Emacs | CommentsBeing on vacation is soo nice. With some of my free time I'm planning on revamping my emacs environment, so hopefully that means a few more articles showing up here on that topic.
I read some great tips on ansi-term. Ansi-term is a terminal emulator written in emacs lisp that is as close to a real terminal as possible. That means you can run virtually all command line programs, even the ones that use ncurses like top or screen, all within emacs. You can still switch between line and char modes which means you can still edit the buffer as you could in a regular (emacs) shell too.
F2 Keybinding
In the above mentioned article Joseph wrote a nice little bit of elisp to get to a running ansi-term efficiently, by hitting F2. The nice thing about it is that it does what I mean:
- If I'm already in an ansi-term, but it's called "*ansi-term*" rename it.
- If I'm already in an ansi-term, but it's called something else, start a new ansi-term called "*ansi-term*"
- If I'm in another non-terminal buffer, switch to a buffer called "*ansi-term*" or create a new one if it doesn't exist
There's one more catch though, as Joseph explains, an ansi-term can be considered "stopped" such that it is no longer running but the buffer still exists. In that case I don't want the third rule to switch me to a defunct terminal, so instead I want it to kill the buffer and create a new ansi-term. Here is my enhanced elisp:
(require 'term) (defun visit-ansi-term () "If the current buffer is: 1) a running ansi-term named *ansi-term*, rename it. 2) a stopped ansi-term, kill it and create a new one. 3) a non ansi-term, go to an already running ansi-term or start a new one while killing a defunt one" (interactive) (let ((is-term (string= "term-mode" major-mode)) (is-running (term-check-proc (buffer-name))) (term-cmd "/bin/bash") (anon-term (get-buffer "*ansi-term*"))) (if is-term (if is-running (if (string= "*ansi-term*" (buffer-name)) (call-interactively 'rename-buffer) (if anon-term (switch-to-buffer "*ansi-term*") (ansi-term term-cmd))) (kill-buffer (buffer-name)) (ansi-term term-cmd)) (if anon-term (if (term-check-proc "*ansi-term*") (switch-to-buffer "*ansi-term*") (kill-buffer "*ansi-term*") (ansi-term term-cmd)) (ansi-term term-cmd))))) (global-set-key (kbd "<f2>") 'visit-ansi-term)
TRAMP Integration
This is cool.
Put the following inside of your .bash_profile on any computer that you ssh into frequently:
#Emacs ansi-term directory tracking # track directory, username, and cwd for remote logons if [ $TERM = eterm-color ]; then function eterm-set-cwd { $@ echo -e "\033AnSiTc" $(pwd) } # set hostname, user, and cwd function eterm-reset { echo -e "\033AnSiTu" $(whoami) echo -e "\033AnSiTc" $(pwd) echo -e "\033AnSiTh" $(hostname) } for temp in cd pushd popd; do alias $temp="eterm-set-cwd $temp" done # set hostname, user, and cwd now eterm-reset fi
Now when you ssh into a machine from within ansi-term and open a file with C-x C-f you'll be loading a file via TRAMP from the current working directory on the remote machine. Amazingly cool.
Ubuntu: coping with a height restricted display
December 10, 2008 at 1:06 pm | In Linux | CommentsI'm eagerly awaiting my new Samsung NC10 to be shipped from Amazon. It's a nice little netbook that I can use when traveling and when going to social occasions. I'm specifically buying this laptop because of its small size, but I know that one thing specifically will bother me: the screen resolution, at 1024×600 is wide enough for most tasks, but not very tall at all.
So while I'm waiting, I'm playing around with Ubuntu 8.10 inside a VirtualBox instance. I've got the window resized to 1024×600 and am playing around with different settings to make maximum use of the screen. Here are my tweaks:
Gnome Panel (the toolbar):
Open gconf-editor (Alt-F2 'gconf-editor') and navigate to apps -> panel -> toplevels -> top_panel_screen0 and change the following:
- auto_hide: checked — makes the main toolbar panel autohide
- auto_hide_size: 0 — makes the toolbar completely hide instead of leaving a few pixels visible
- enable_animations: unchecked — make the hiding/unhiding as fast as possible
- hide_delay: 500 — makes the toolbar stay on screen for half a second after using it
- unhide_delay: 0 — makes the toolbar immediately popup when your mouse goes to the very top (or bottom) of the screen
Gnome Terminal:
Open the default profile properties, right click in the window and click "Edit Current Profile"
- Turn off the menu bar: on the General tab uncheck "Show menubar by default in new terminals"
- Turn off the scrollbar: on the Scrolling tab select "Scrollbar is: Disabled"
Oversized windows:
Uncheck the following key in gconf-editor:
/apps/compiz/plugins/move/allscreens/options/constrain_y
Now you can Alt-left-click any window and drag it around even above the top of the screen.
Firefox:
- Move the bookmarks bar up to the file menu bar and get rid of the bookmarks bar:
- Right click on the Home button and click customize.
- Your bookmarklets should now disappear and read "Bookmarks Toolbar items."
- Drag "Bookmarks Toolbar items" along the right hand side of the File .. Edit …. Help menus.
- Click "Done."
- Right click on the now empty bookmarks toolbar and uncheck "Bookmarks Toolbar."
- Get rid of the status bar: Go to View -> uncheck "Status Bar."
- Install a theme that uses smaller buttons and text: I like Classic Compact.
- Remember that Firefox has a nice fullscreen option : F11.
- Check out Tree Style Tabs. It puts the tabs vertically on the left side of the browser and visually keeps track of what sites you were at that prompted you to open a new tab, all in a tree like fashion.
Here is the desktop with gnome panel completely hidden and one terminal with menu bar hidden (click to see native size):

Here is firefox maximised with two tabs open (click to see native size):

Here is firefox in fullscreen (click to see native size):

Firefox maximized with Tree Style Tabs:

In Pursuit of the Aggressor
December 5, 2008 at 12:08 pm | In Free State Project, Pissed Off | CommentsI've been feeling pretty good lately, I have a decent job, a wonderful wife, awesome friends, and a new-found purpose in life: liberty activism in New Hampshire. In a world as messed up as ours, its been a profound comfort to have found such peace and purpose. But I've also been a bit startled recently including having feelings of helplessness, distrust, and insecurity.
My truck got broken into.
I had just gotten home from work and not 10 minutes transpired before I heard a loud crash and some rustling outside. As I rushed out the door, I saw someone had broken the window of my truck and was diving inside to grab my video camera. Before I knew it, I was several blocks away from my house, running full speed 10 feet behind the guy who was also running like hell. I kept chasing him, never quite closing the gap between him and myself until I ran out of energy. He turned the corner and I followed a bit more slowly. Knowing he was hiding, I looked closely in the darkness for him and I finally saw the guy dash from his hiding spot and continue running away. I said a few more unkind words in his direction as he fled, but there was nothing more for me to do. Out of breath, dejected, and quite frustrated, I walked back home. Kellie was already outside at this point wondering what had happened, we assessed the damage and confirmed that he had destroyed the passenger side window of my truck and managed to steal my video camera.
My Landlord had already called the cops and they showed up about 10 minutes later. Since they were there anyway, I gave them my take on what happened, although I had never really gotten a good look at the guy. I really didn't have much hope that the police would ever do anything (and in an ideal world we wouldn't have such agents of force). Kellie left to do her own reconnaissance at the corner store and surprised me when she told me that she saw the same cops doing actual detective work, questioning the store manager. Although I'm almost sure that these same men have violated the rights of peaceful individuals before, and will most likely continue to do so in their roles as agents of the state, I'm glad that they take their jobs seriously enough to want to protect peace when they can.
I don't really leave anything that valuable in my truck. The camera is a somewhat cheap Samsung SC-MX10, I had it mounted to my dash with a Modifry camera mount (The mount got ripped out with the camera), this setup was supposed to record the cops if I ever got pulled over. Sadly, I never got to try that out. I'm sure that the way I had it mounted made it stand out as an easy target for a thief.
I called up my insurance rep as well as an auto glass shop and got things taken care of pretty quickly, the auto glass shop was even willing to drive out to my house the next day and repair it right there even while I went to work that day. I love how market competition makes this so easy.
In total, I'm out $200 for the camera, $25 for the mount, and $163.15 for the glass. Yea, $388 is kind of a lot. However I was much more irritated with the inconvenience of it all, as well as the knowledge that there are people right in my neighborhood that have no reservations in actively destroying their society. The reason I'm here in NH is to work towards creating a civil and voluntary society. Its one thing to disagree with my ideas, I'm used to that. Its quite another to find that you live in a community where some percentage of the people do the exact opposite; creating a society of violence and distrust.
I'm left with a renewed sense of the importance of security, including responsible firearms ownership and carrying whenever possible. I don't actually think that a gun would have been useful in this situation, especially after the incident was carried onto the open street at 12 mph, but knowing first hand that desperation has led people to such forceful actions, it makes me much more cautious.
Powered by WordPress.
Entries and comments feeds.
XML Sitemap
TEST NEW


