<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7044907287770355906</id><updated>2012-01-02T23:42:17.671-05:00</updated><category term='apache'/><category term='scripting'/><category term='pastebin'/><category term='php'/><category term='bzr'/><category term='td'/><category term='perl'/><category term='gnucash'/><category term='FOSS'/><category term='ssh'/><category term='irssi'/><category term='bash'/><category term='gnome'/><category term='life'/><category term='ledger'/><category term='gajim'/><category term='blogger'/><category term='cli bash'/><category term='css'/><category term='python'/><category term='tracker'/><category term='rss'/><category term='html'/><category term='beryl'/><category term='vim'/><category term='mono'/><category term='solaris'/><category term='vcs'/><category term='gmail'/><category term='laptop'/><category term='backup'/><category term='google'/><title type='text'>It Feels Like ~</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-4281401080591486116</id><published>2008-04-03T19:31:00.001-05:00</published><updated>2008-04-03T19:31:24.432-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cli bash'/><title type='text'>Command Line Bookmarks</title><content type='html'>
&lt;p&gt;I wish I'd known about this tool years ago. Today I discovered a little utility called &lt;code&gt;cdargs&lt;/code&gt;. Basically it lets you browse your directory tree very quickly, and allows you to create bookmarks to your most often used directories.
&lt;/p&gt;
&lt;p&gt;The bookmarks are stored at &lt;code&gt;~.cdargs&lt;/code&gt; in a simple format that's easily edited whenever you want to modify them, but I'm getting ahead of myself now...
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cdargs&lt;/code&gt; has a directory browsing tool which is invoked by the &lt;code&gt;cv&lt;/code&gt; command. In this tool, you can use arrow keys, Vim bindings, or even Emac bindings to navigate. Pressing &lt;code&gt;a&lt;/code&gt; on a directory in the browser adds it as a bookmark, and pressing &lt;code&gt;Enter&lt;/code&gt; opens it back in the shell. To see more of the available commands, press &lt;code&gt;H&lt;/code&gt; or &lt;code&gt;?&lt;/code&gt; in the browser.
&lt;/p&gt;
&lt;p&gt;Outside, back in the shell, you can copy files and move files to your bookmarked directories using the &lt;code&gt;cpb&lt;/code&gt; and &lt;code&gt;mvb&lt;/code&gt; commands respectively. For example, &lt;code&gt;cpb foo bar&lt;/code&gt; will move the file called &lt;code&gt;foo&lt;/code&gt; from the current directory to the directory that I have bookmarked as &lt;code&gt;bar&lt;/code&gt;. You guessed it, &lt;code&gt;cdb bar&lt;/code&gt; would change you to the directory bookmarked by &lt;code&gt;bar&lt;/code&gt; as well.
&lt;/p&gt;
&lt;p&gt;This tool has several more features as well, but I'll leave those up to you to discover. The &lt;code&gt;man&lt;/code&gt; page is a good read, and I don't want to take &lt;em&gt;all&lt;/em&gt; the fun away from you :). The only problem I can see with this tool is that it may be difficult getting used to the different commands. Typically the commands they replace or supplement are used quite quickly. By the time I stop to recall the applicable &lt;code&gt;cdargs&lt;/code&gt; command I've waited too long. If I can get past that, there's no doubt I'll get some good use out of this one.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-4281401080591486116?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/4281401080591486116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/04/command-line-bookmarks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4281401080591486116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4281401080591486116'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/04/command-line-bookmarks.html' title='Command Line Bookmarks'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-3479216784279747416</id><published>2008-03-15T11:03:00.001-05:00</published><updated>2008-03-15T11:03:30.757-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='solaris'/><title type='text'>Change the Solaris Shell to Bash</title><content type='html'>
&lt;p&gt;For those of us that are stuck working in Solaris environments with either &lt;code&gt;csh&lt;/code&gt; or &lt;code&gt;ksh&lt;/code&gt; as the default shell, there is hope. Some of these environments have the &lt;code&gt;chsh&lt;/code&gt; command to change shells, but for those that don't, here is how to change your shell to &lt;code&gt;bash&lt;/code&gt;. First of all, make sure it is available on your system. It's typically found in &lt;code&gt;/bin/bash&lt;/code&gt;. If it's there, you can edit your &lt;code&gt;~/.profile&lt;/code&gt; to make it run the new shell when you login.
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;IMPORTANT&lt;/em&gt;: Before doing this, open two separate shells. Keeping one open and unaltered is a good way to recover if something goes wrong in this process. If you break something and can't log in, you may piss off your system admin when you have to call him to fix it for you. Leave one of these open shells alone during this process.
&lt;/p&gt;
&lt;p&gt;In one of your open shells, add the following two lines to the bottom of your &lt;code&gt;~/.profile&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;export SHELL=/bin/bash
exec $SHELL
&lt;/pre&gt;&lt;p&gt;You can now log out of that shell and back in again to see if it worked. If so, all went well and you can close the other shell. If not, use your "safety" shell to repair your &lt;code&gt;~/.profile&lt;/code&gt; so that you can log in again.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-3479216784279747416?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/3479216784279747416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/03/change-solaris-shell-to-bash.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3479216784279747416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3479216784279747416'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/03/change-solaris-shell-to-bash.html' title='Change the Solaris Shell to Bash'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-9170966719516491549</id><published>2008-02-24T14:27:00.001-05:00</published><updated>2008-02-24T14:27:30.230-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Google Makes Me Stupid</title><content type='html'>
&lt;p&gt;Does anyone else find that sometimes their first response to a problem is to search &lt;a href='http://www.google.com'&gt;Google&lt;/a&gt;? I just had the good ol' &lt;code&gt;500 Internal Server Error&lt;/code&gt; in an &lt;a href='http://apache.org'&gt;Apache&lt;/a&gt; request and immediately I searched Google for assistance. Given that the web server in question was my own, the reasonable person would first check the server &lt;code&gt;error.log&lt;/code&gt;, but I'm apparently not that guy. In my defence, it didn't take long for me to remember this, but still, Google was my initial reaction.
&lt;/p&gt;
&lt;p&gt;A quick check of said log file suggested an &lt;code&gt;.htaccess&lt;/code&gt; issue, and now all is well. Perhaps we're (I'm?) becoming too dependant on our search engine overlords...
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-9170966719516491549?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/9170966719516491549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/02/google-makes-me-stupid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9170966719516491549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9170966719516491549'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/02/google-makes-me-stupid.html' title='Google Makes Me Stupid'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-3349788876163279199</id><published>2008-02-24T14:14:00.001-05:00</published><updated>2008-02-24T14:16:28.154-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='vcs'/><title type='text'>Vim and Perforce</title><content type='html'>
&lt;p&gt;&lt;a href='http://www.tvworks.com'&gt;My employer&lt;/a&gt; has used &lt;a href='http://www.perforce.com'&gt;Perforce&lt;/a&gt; as a VCS for several years now. Perforce itself maintains integration plugins for &lt;a href='http://eclipse.org'&gt;Eclipse&lt;/a&gt;, but of course not for editors like &lt;a href='http://vim.org'&gt;Vim&lt;/a&gt; so it's up to the community to do so. Lucky for me, extremely capable Vim scripters like &lt;a href='http://www.vim.org/account/profile.php?user_id=292'&gt;Hari Krishna Dara&lt;/a&gt; also use Perforce from time to time :). This is the same author who brought us the &lt;a href='http://www.vim.org/scripts/script.php?script_id=240'&gt;genutils.vim&lt;/a&gt; plugin as well as many other powerful scripts as his &lt;a href='http://www.vim.org/account/profile.php?user_id=292'&gt;vim profile&lt;/a&gt; lists. Among these is a fantastic &lt;a href='http://www.vim.org/scripts/script.php?script_id=240'&gt;perforce script set&lt;/a&gt; that I downloaded to try about a week ago. It was more than I'd hoped for.
&lt;/p&gt;
&lt;p&gt;This is a very featureful Perforce integration script with a complete set of menus (although I have menus hidden in my vim) and commands. I'm not sure whether the author still uses it or not however because there was a bug in spec-based commands that broke it pretty badly. Of course, there is the possibility that I'm using it incorrectly too. Regardless, I've "fixed" a couple of these bugs and emailed the author with a patch. I also uncovered a bug in the &lt;a href='http://www.vim.org/scripts/script.php?script_id=240'&gt;genutils.vim&lt;/a&gt; script that it depends on. The author also mentions this in the script page for the Perforce plugin:
&lt;/p&gt;
&lt;pre&gt;--------------------------------------------------------------------------------
Lately, I am not finding enough time to add features to this, so if anybody is
interested to help me add new features or even take over the responsibility, you
are very much welcome.
--------------------------------------------------------------------------------
&lt;/pre&gt;&lt;p&gt;Although I sent him a small patch in his Inbox, he may not have the time to make a bug fix release, so I've made a little &lt;a href='http://bazaar-vcs.org'&gt;bazaar&lt;/a&gt; branch of the complete script on my own little server &lt;a href='http://arker.homelinux.org/~dcraven/bazaar/vim-perforce/'&gt;here&lt;/a&gt; for the time being. This branch includes the fixes for a couple of little bugs, and some extra syntax hinting for pending changelists and closed jobs. Aside from that, it's unaltered. You can get it using this command, assuming you have bzr installed.
&lt;/p&gt;
&lt;pre&gt;$ bzr branch http://arker.homelinux.org/~dcraven/bazaar/vim-perforce vim-perforce
&lt;/pre&gt;&lt;p&gt;I might add a few features or commands that have been included in the p4 client since his last release of the script at some point too. Depending on his email reply (if he replies) we'll see if he'd like my changes included in his next release or not. My additions unfortunately won't be of the same quality as the stuff he's already written. I'm not exactly a seasoned vim-scriptor...
&lt;/p&gt;
&lt;p&gt;All in all, it's a fantastic script. Check it out if you use Vim with the Perforce VCS, and big kudos and thanks go out to the original author!
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-3349788876163279199?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/3349788876163279199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/02/vim-and-perforce.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3349788876163279199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3349788876163279199'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/02/vim-and-perforce.html' title='Vim and Perforce'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-6901024870393012285</id><published>2008-02-19T20:07:00.001-05:00</published><updated>2008-02-19T20:07:34.430-05:00</updated><title type='text'>Stumped by a Captcha</title><content type='html'>
&lt;p&gt;Does anyone see the security code in this captcha?
&lt;/p&gt;
&lt;p&gt;&lt;img alt='Bad Captcha Image' src='http://arker.homelinux.org/images/captcha.png'/&gt;
&lt;/p&gt;
&lt;p&gt;This one has me stumped...
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-6901024870393012285?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/6901024870393012285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/02/stumped-by-captcha.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6901024870393012285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6901024870393012285'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/02/stumped-by-captcha.html' title='Stumped by a Captcha'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-4046309125918343419</id><published>2008-02-18T22:06:00.001-05:00</published><updated>2008-02-18T22:06:42.586-05:00</updated><title type='text'>GnuCash Broke My Ledger :(</title><content type='html'>
&lt;p&gt;For the past year and a bit, I've been happily &lt;a href='http://djcraven5.blogspot.com/2006/11/gnucash-and-ledger-combo.html'&gt;using GnuCash with Ledger&lt;/a&gt; and it had been a fantastic duo. Several days ago, I upgraded to &lt;a href='http://www.gnucash.org/'&gt;GnuCash 2.2.3&lt;/a&gt; and the combo doesn't work so well anymore. The problem stems from an &lt;a href='http://wiki.gnucash.org/wiki/FAQ#Q:_I_downgraded_from_GnuCash_2.2_to_2.0.3B_what.27s_up_with_this_ROOT_account.3F'&gt;internal change&lt;/a&gt; that adds a "Root Account" as the top level account in the tree. To say the two don't work together anymore might be a little harsh, but they at least don't work as &lt;em&gt;well&lt;/em&gt; together as they used to. For example, this used to work to get a quick net worth:
&lt;/p&gt;
&lt;pre&gt;$ ledger bal ^ass ^liab
&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;^ass&lt;/code&gt; and &lt;code&gt;^liab&lt;/code&gt; bits are regular expressions that match all accounts that start with the letters &lt;code&gt;ass&lt;/code&gt; and &lt;code&gt;liab&lt;/code&gt; (assets and liabilities) respectively. This would result in a little chart showing my total assets minus my total liabilities, since "Assets" and "Liabilities" used to be top level accounts. Now with the new structure, these accounts are no longer roots. Instead they look like "Root Account:Assets" and "Root Account:Liabilites". Long story short, this new "Root Account" is the only top level account. To make matters worse, the bloody account name has a &lt;em&gt;space&lt;/em&gt; in its name, and we all know how well spaces work on the command line...
&lt;/p&gt;
&lt;p&gt;Needless to say, the combination became a lot less useful with this update. I'm not sure whether to downgrade to GnuCash 2.0 or not. What a shame.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-4046309125918343419?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/4046309125918343419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/02/gnucash-broke-my-ledger.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4046309125918343419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4046309125918343419'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/02/gnucash-broke-my-ledger.html' title='GnuCash Broke My Ledger :('/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-400590093557852419</id><published>2008-02-16T18:03:00.001-05:00</published><updated>2008-02-16T18:18:03.693-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Changing the Default Text Editor in GNOME</title><content type='html'>
&lt;p&gt;The "Preferred Applications" menu item in GNOME runs a little app that allows you to change some of the default programs used for various tasks like web browsing, music playing etc. One thing that's been missing for me is the ability to change the default text editor. Sure you can open up Nautilus, right click on a text file, and chose that way, but there are &lt;em&gt;many&lt;/em&gt; types of text files, and they are each treated independantly. 
&lt;/p&gt;
&lt;p&gt;Recently I discovered the &lt;code&gt;~/.local/**&lt;/code&gt; path. I'll use &lt;a href='http://www.vim.org'&gt;gvim&lt;/a&gt; as an example for this excersise. This is the ticket for swapping default editors once and for all! First, use the method described above (the right click in Nautilus way). Now you should have a &lt;code&gt;~/.local/share/applications/gvim.desktop&lt;/code&gt; file. That's good. Next, create a &lt;code&gt;~/.local/share/applications/defaults.list&lt;/code&gt; file, and put this in it: 
&lt;/p&gt;
&lt;pre&gt;    [Default Applications]
    text/plain=gvim.desktop
    application/x-perl=gvim.desktop
    text/x-chdr=gvim.desktop
    text/x-csrc=gvim.desktop
    text/x-dtd=gvim.desktop
    text/x-java=gvim.desktop
    text/mathml=gvim.desktop
    text/x-python=gvim.desktop
    text/x-sql=gvim.desktop
&lt;/pre&gt;&lt;p&gt;The contents above were taken from my own system wide &lt;code&gt;/usr/share/applications/defaults.list&lt;/code&gt;, just with &lt;code&gt;:%s/gedit/gvim/&lt;/code&gt;. This should at least cover the file types that gedit keeps popping open for. You could always modify the system wide &lt;code&gt;defaults.list&lt;/code&gt;, but be prepared to lose those changes during your next update. Also, since the &lt;code&gt;gvim.desktop&lt;/code&gt; file already existed in my local home path, I never tried just copying the one from &lt;code&gt;/usr/share/applications&lt;/code&gt;. That might work too. 
&lt;/p&gt;
&lt;p&gt;I can't believe I've been using GNOME for so long and never knew this :( 
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-400590093557852419?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/400590093557852419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/02/changing-default-text-editor-in-gnome.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/400590093557852419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/400590093557852419'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/02/changing-default-text-editor-in-gnome.html' title='Changing the Default Text Editor in GNOME'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-1536144571018033641</id><published>2008-02-16T17:13:00.001-05:00</published><updated>2008-02-16T17:13:17.933-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='FOSS'/><category scheme='http://www.blogger.com/atom/ns#' term='rss'/><title type='text'>Tiny Tiny RSS Feed Reader</title><content type='html'>
&lt;p&gt;Lately, I've been missing something in a feed reader. In the past six months or so I've tried a plethora of different readers of different forms. I tried the desktop application style like &lt;a href='http://liferea.sourceforge.net/'&gt;Lifrea&lt;/a&gt;, the online flavors like &lt;a href='http://www.google.com/reader'&gt;Google Reader&lt;/a&gt;, and the &lt;a href='http://getfirefox.com'&gt;Firefox&lt;/a&gt; extension kind like &lt;a href='http://sage.mozdev.org'&gt;Sage&lt;/a&gt;. All have their benefits, but also disadvantages. For example offline readers make it a pain when one uses different machines, online reader services felt slow or sluggish, and cluttered. Not to mention they can't be modified.
&lt;/p&gt;
&lt;p&gt;I forget now how I heard about &lt;a href='http://tt-rss.org/trac/wiki'&gt;Tiny Tiny RSS&lt;/a&gt; now, but if I remember I'll update this post with well deserved props. This thing is perfect in my opinion. It's fast, it's open source, it's written in PHP/MySQL, and it's pretty feature complete. Even setup was a breeze and went without a hitch.
&lt;/p&gt;
&lt;p&gt;The interface is very clean and well organized. One can tell pretty early that some of the interface ideas in TTRSS were inspired by Google's great GMail interface like the ability to star articles as well as the familiar actions list, and in fact it very much has the feel of using your typical desktop email application. This reader can run in either single or multi-user modes, and you can publish your feeds and articles with others with a single click.
&lt;/p&gt;
&lt;p&gt;I'll not provide a list of features here since they do a pretty good job of that on their &lt;a href='http://tt-rss.org/trac/wiki'&gt;website&lt;/a&gt;. If you are not in love with your current reader, I very strongly suggest this gem!
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-1536144571018033641?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/1536144571018033641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/02/tiny-tiny-rss-feed-reader.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1536144571018033641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1536144571018033641'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/02/tiny-tiny-rss-feed-reader.html' title='Tiny Tiny RSS Feed Reader'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-2246627383281779070</id><published>2008-01-20T16:16:00.001-05:00</published><updated>2008-02-16T18:20:08.450-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>It's Been Almost a Year</title><content type='html'>
&lt;p&gt;I'm about as interested in writing a reasons-for-not-posting-for-a-year blog entry as you are in reading one. Instead, I'll just say that since my last post I've gotten a &lt;a href='http://www.tvworks.com'&gt;job&lt;/a&gt; and I've gotten my wife pregnant. 
&lt;/p&gt;
&lt;p&gt;The baby is due in May! 
&lt;/p&gt;
&lt;p&gt;P.S. I really should take that terrible picture of my head down from up there...
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-2246627383281779070?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/2246627383281779070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2008/01/it-been-almost-year.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/2246627383281779070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/2246627383281779070'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2008/01/it-been-almost-year.html' title='It&amp;#39;s Been Almost a Year'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-6623766006759362229</id><published>2007-01-24T16:33:00.001-05:00</published><updated>2007-01-24T16:37:03.149-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='beryl'/><title type='text'>Beryl and the ATI IGP 340M</title><content type='html'>&lt;p&gt;I can't believe nobody told my that &lt;a href='http://www.beryl-project.org/'&gt;Beryl&lt;/a&gt; would work with my cruddy 340M graphics chip. I threw caution to the wind today and tried it only to find out that it worked quite nicely! Sure, it's not as smooth as on my desktop machine with an NVidia chip, but it is very usable and pretty. I basically just followed &lt;a href='http://wiki.beryl-project.org/index.php/Install/Ubuntu/Edgy/AiGLX#How-to_install_Beryl_with_AIGLX_on_Edgy_Eft'&gt;these instructions&lt;/a&gt; and boom. All was well. Oh, I also changed the driver in my &lt;code&gt;/etc/X11/xorg.conf&lt;/code&gt; file to &lt;code&gt;radeon&lt;/code&gt; from &lt;code&gt;ati&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;Anyways, here is the cool screenshot...
&lt;center&gt;
&lt;a href="http://arker.homelinux.org/images/beryl-screen.png"&gt;&lt;img src="http://arker.homelinux.org/images/beryl-screen_thumb.png"&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-6623766006759362229?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/6623766006759362229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2007/01/beryl-and-ati-igp-340m-graphics-card.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6623766006759362229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6623766006759362229'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2007/01/beryl-and-ati-igp-340m-graphics-card.html' title='Beryl and the ATI IGP 340M'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-7293022627297163727</id><published>2007-01-04T14:30:00.001-05:00</published><updated>2007-01-05T12:14:06.463-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='backup'/><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Rotating Backups with Rsync</title><content type='html'>
&lt;p&gt;The Christmas break was pretty good, with one exception. The hard drive on my laptop gave me some serious grief. Long story short, I wiped it, made new partitions, and reinstalled the OS. Now luckily, I was smart enough to keep partial daily backups on my server for just these occasions so nothing too important was lost (thesis). However, the keywords here are &lt;em&gt;partial backups&lt;/em&gt;. This means that most of my settings and non-crucial data was &lt;em&gt;not&lt;/em&gt; backed up, and that has turned out to be a bit of a drag. 
&lt;/p&gt;
&lt;p&gt;Anyways, the hard drive appears to be functioning correctly now, I purchased an el cheapo (some of us never learn) external drive, and I'm looking to do full backups of my &lt;code&gt;$HOME&lt;/code&gt; directory from now on. A quick search took me to the concepts outlined &lt;a href='http://www.mikerubel.org/computers/rsync_snapshots/'&gt;here&lt;/a&gt;. This scheme is pretty clever, is suprisingly fast, and very efficient on drive space. The result is a &lt;a href='http://arker.homelinux.org/files/backup'&gt;simple Python script&lt;/a&gt; that seems to do the trick. Well, it's mostly Python with a bunch of Bash calls via &lt;code&gt;os.system()&lt;/code&gt;, but close enough. 
&lt;/p&gt;
&lt;p&gt;Basically, it uses &lt;a href='http://samba.anu.edu.au/rsync/'&gt;rsync&lt;/a&gt; to synchronize data over an ssh connection to my remote server. That remote machine has the external drive attached and mounted. Given a remote destination directory, it creates a series of backup directories based on the local machine's hostname. For example, my laptop's hostname is &lt;em&gt;sigma&lt;/em&gt; and the script creates the directories &lt;code&gt;sigma/sigma&lt;/code&gt;, &lt;code&gt;sigma/sigma.1&lt;/code&gt;, &lt;code&gt;sigma/sigma.2&lt;/code&gt; etcetera all the way up to &lt;code&gt;sigma/sigma.7&lt;/code&gt;. These numbered directories contain &lt;em&gt;snapshots&lt;/em&gt; of the data back seven runs. So if you run the script once per day, you have a snapshot for the past seven days. Instead of storing all of the data seven times however, it uses hard links to save space. I'll let you read up on this concept &lt;a href='http://www.mikerubel.org/computers/rsync_snapshots/'&gt;here&lt;/a&gt; if you are interested. 
&lt;/p&gt;
&lt;p&gt;Several assumptions are made in this script. One is that you have &lt;a href='http://hacks.oreilly.com/pub/h/66'&gt;passwordless ssh logins&lt;/a&gt; setup correctly. Also, the script requires a configuration file called &lt;code&gt;~/.backuprc&lt;/code&gt; where several custom settings are stored and read. Here is an example of such a file. 
&lt;/p&gt;
&lt;pre&gt;EXCLUDES = *.iso,*.avi,*.mpg,*.mp3,*.ogg,*.wma,*.wmv,*.mov,*.LNK,*.LCK
SOURCES = ~/
DEST_HOST = arker.homelinux.org
LOG_DIR = ~/.backup_logs/
DEST_PATH = /media/backup_drive/home_backup/
&lt;/pre&gt;&lt;p&gt;The variables in this file break down as follows... 
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     &lt;strong&gt;EXCLUDES&lt;/strong&gt;: A comma separated list of patterns matching files that are &lt;em&gt;not&lt;/em&gt; to be backed up. 
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;SOURCES&lt;/strong&gt;: A comma separated list of directories to be backed up. The example instructs the script to back up the user's entire home directory. 
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;DEST_HOST&lt;/strong&gt;: The host of the remote server where the backups will be sent. 
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;LOG_DIR&lt;/strong&gt;: The location where log files should be saved. 
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;DEST_PATH&lt;/strong&gt;: The destination on the remote machine where the backups will be stored. 
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I put an entry in my user's crontab to run the script at 12:05pm every day. The entry looks like this: 
&lt;/p&gt;
&lt;pre&gt;5 12 * * * /home/dcraven/bin/backup
&lt;/pre&gt;&lt;p&gt;The script is located in my ~/bin directory. If you need help with cron, have a look at &lt;a href='http://www.unixgeeks.org/security/newbie/unix/cron-1.html'&gt;this tutorial&lt;/a&gt;. Keep in mind that when run this way, cron will only execute the command if the machine is on when it is scheduled. It will &lt;em&gt;not&lt;/em&gt; automatically run when the machine is started when a scheduled time is missed. For this behaviour, look into &lt;code&gt;/etc/cron.daily&lt;/code&gt; and friends. 
&lt;/p&gt;
&lt;p&gt;At the moment, all of these settings are required in the file. At some point I might write something a little more robust and clean, but for now this works and I have other things that should be given a higher priority. 
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-7293022627297163727?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/7293022627297163727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2007/01/rotating-backups-with-rsync_04.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/7293022627297163727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/7293022627297163727'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2007/01/rotating-backups-with-rsync_04.html' title='Rotating Backups with Rsync'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-8930956131873163661</id><published>2006-12-20T14:49:00.001-05:00</published><updated>2007-10-29T21:45:58.472-05:00</updated><title type='text'>Searchable Tags in td</title><content type='html'>&lt;p&gt;I'm starting to really like writing console apps in Python. To add a feature takes no time at all since there is little UI to deal with. Over the last hour I've implemented tagging for your tasks in &lt;a href='http://djcraven5.blogspot.com/2006/12/td-command-line-todo-list-manager.html'&gt;td&lt;/a&gt;. Tags for searching and grouping items seem to be pretty popular in current applications, so I thought why not a todo list manager? I think I like this better than the &lt;a href='http://djcraven5.blogspot.com/2006/12/td-gets-project-stuff.html'&gt;projects&lt;/a&gt; I implemented a couple of weeks ago. The projects stuff is of course still available and fully functional, I just don't think I'll be using it as much anymore because the new tags are much handier. In fact, you can still use both at the same time. Here is how the new &lt;code&gt;tags&lt;/code&gt; command works... 
&lt;/p&gt;
&lt;p&gt;When you create a new task, a group of tags can be associated with it by including a space separated list, enclosed in square brackets, in the task summary. 
&lt;/p&gt;
&lt;pre&gt;$ td add [tag1 tag2 tag3]This is a new task.
&lt;/pre&gt;&lt;p&gt;Now, if I want to see what tags are being used: 
&lt;/p&gt;
&lt;pre&gt;$ td tags
--&amp;gt; Available tags:
--&amp;gt; tag1(1) tag2(1) tag3(1)
&lt;/pre&gt;&lt;p&gt;Issuing the new &lt;code&gt;tags&lt;/code&gt; command with no arguments lists all tags, and the number of tasks with that tag. If you want to see a list of tasks by tag: 
&lt;/p&gt;
&lt;pre&gt;$ td tags tag1
--&amp;gt;  #   P H  Created    Description
--&amp;gt;  1        12/20/06   This is a new task.
&lt;/pre&gt;&lt;p&gt;Maybe you want to see a list of tags that are associated with a specific task? 
&lt;/p&gt;
&lt;pre&gt;$ td tags 1
--&amp;gt; [tag1 tag2 tag3]
&lt;/pre&gt;&lt;p&gt;Want to remove the "tag2" tag from that task? No problem... 
&lt;/p&gt;
&lt;pre&gt;$ td tags 1 -tag2
$ td tags 1
--&amp;gt; [tag1 tag3]
&lt;/pre&gt;&lt;p&gt;Let's remove "tag3" now, and add "newtag" to this task: 
&lt;/p&gt;
&lt;pre&gt;$ td tags 1 -tag3 +newtag
$ td tags 1
--&amp;gt; [tag1 newtag]
&lt;/pre&gt;&lt;p&gt;You can still use the &lt;code&gt;replace&lt;/code&gt; command to replace all of them at once. 
&lt;/p&gt;
&lt;pre&gt;$ td replace 1 [foo bar]This is a new task.
$ td tags 1
--&amp;gt; [foo bar]
&lt;/pre&gt;&lt;p&gt;And of course you can easily combine hidden status, tags, and projects all at once. 
&lt;/p&gt;
&lt;pre&gt;$ td add .[tag1 tag2] p:MyProject This is yet another new task.
$ td tags tag1
--&amp;gt;  #   P H  Created    Description
--&amp;gt;  2     *  12/20/06   This is yet another new task.
$ td project MyProject
--&amp;gt;  #   P H  Created    Description
--&amp;gt;  2     *  12/20/06   This is yet another new task.
&lt;/pre&gt;&lt;p&gt;Notice the "H" column in that output indicates whether the task in the list is hidden or not. That column was recently added to both the &lt;code&gt;tags&lt;/code&gt; and the &lt;code&gt;project&lt;/code&gt; output. These changes are committed and pushed to the &lt;a href='http://arker.homelinux.org/~dcraven/bazaar/td/'&gt;bazaar repository&lt;/a&gt; that I spoke of in &lt;a href='http://djcraven5.blogspot.com/2006/12/now-using-bazaar-for-vcs.html'&gt;my last post&lt;/a&gt;. Don't forget to email me the bugs! 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-8930956131873163661?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/8930956131873163661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/12/searchable-tags-in-td.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/8930956131873163661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/8930956131873163661'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/12/searchable-tags-in-td.html' title='Searchable Tags in td'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-4431408416837506865</id><published>2006-12-20T13:58:00.001-05:00</published><updated>2007-10-29T21:47:15.387-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bzr'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='vcs'/><category scheme='http://www.blogger.com/atom/ns#' term='td'/><title type='text'>Now Using Bazaar for a VCS</title><content type='html'>&lt;p&gt;In order to hang with the cool crowd, I've decided to fall for the hype and jump ship (at least for now) to a &lt;em&gt;distributed&lt;/em&gt; version control system. The one I've chosen is &lt;a href='http://bazaar-vcs.org/'&gt;bazaar&lt;/a&gt;, mostly because it's written purely in Python. I like playing with new things from time to time, and bazaar commands are a pretty smooth transition from their &lt;a href='http://subversion.tigris.org/'&gt;Subversion&lt;/a&gt; equivalents. 
&lt;/p&gt;
&lt;p&gt;So, in order to get the latest and greatest unreleased code for &lt;a href='http://djcraven5.blogspot.com/2006/12/td-command-line-todo-list-manager.html'&gt;td&lt;/a&gt; or &lt;a href='http://djcraven5.blogspot.com/2006/12/vim-bloggerbeta-plugin-release.html'&gt;vim-blogger&lt;/a&gt;, you can use bazaar and grab the source from &lt;a href='http://arker.homelinux.org/~dcraven/bazaar/td/'&gt;here&lt;/a&gt; and &lt;a href='http://arker.homelinux.org/~dcraven/bazaar/vim-blogger/'&gt;here&lt;/a&gt; respectively. 
&lt;/p&gt;
&lt;p&gt;If need a quick learning reference, have a look at the &lt;a href='http://doc.bazaar-vcs.org/bzr.dev/tutorial.htm'&gt;bazaar tutorial&lt;/a&gt;. It seems the &lt;a href='http://doc.bazaar-vcs.org/bzr.dev/tutorial.htm'&gt;User Manual&lt;/a&gt; link on the website points to the tutorial as well.. Hmm. To find out more about the program, the official website can be found &lt;a href='http://bazaar-vcs.org/'&gt;here&lt;/a&gt;. 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-4431408416837506865?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/4431408416837506865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/12/now-using-bazaar-for-vcs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4431408416837506865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4431408416837506865'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/12/now-using-bazaar-for-vcs.html' title='Now Using Bazaar for a VCS'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-4520878777797082117</id><published>2006-12-19T14:18:00.001-05:00</published><updated>2006-12-19T14:18:04.741-05:00</updated><title type='text'>Vim-BloggerBeta Plugin Release</title><content type='html'>
&lt;p&gt;It turns out I'm not really doing any more modifications to this plugin code because it is working fine for me. I decided then, instead of just sitting on it maybe I should share it! So &lt;a href='http://arker.homelinux.org/files/vim-blogger/vim-blogger.tar.gz'&gt;here&lt;/a&gt; it is... Keep in mind that this no doubt a little rough around the edges as far as usability goes. I'll do my best to describe the plugin here.
&lt;/p&gt;

&lt;h2&gt;Pre-requisites&lt;/h2&gt;
&lt;p&gt;First of all, &lt;em&gt;this plugin requires Python support&lt;/em&gt; to be compiled into Vim. As in, if you do a &lt;code&gt;:version&lt;/code&gt; in Vim and do not see &lt;code&gt;+python&lt;/code&gt; in the output, this plugin will not work.
&lt;/p&gt;
&lt;p&gt;Also, you will need to provide some information for the plugin in the form of three variable settings. The plugin needs to know your blog URL, your Gmail login, and your Gmail password. The variable names for these are &lt;code&gt;g:Blog_URI&lt;/code&gt;, &lt;code&gt;g:Gmail_Account&lt;/code&gt;, and &lt;code&gt;g:Gmail_Password&lt;/code&gt; respectively. Given that some of these variables contain sensitive information, you probably want to take some steps to keep them somewhat private. I often put my &lt;code&gt;~/.vimrc&lt;/code&gt; online for others to read, so putting them in there is a bad idea. Instead, I created a &lt;code&gt;~/vim/plugin/creds.vim&lt;/code&gt; file, &lt;em&gt;made it readable by my user only&lt;/em&gt;, and stuck the info in there. Keep in mind, however, that these are global variables and as such, will be available to all scripts that you run. Also, someone could quite easily get those values by typing &lt;code&gt;:echo g:Gmail_Password&lt;/code&gt; in your vim session for example. If you have some ideas about how to keep this stuff more secure I'd be interested in hearing about them. For now, however, you've been warned :).
&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;The plugin comes in the form of a &lt;a href='http://arker.homelinux.org/files/vim-blogger/vim-blogger.tar.gz'&gt;tarball&lt;/a&gt;. Inside this tarball are five files.
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     &lt;strong&gt;plugin/blogger.vim&lt;/strong&gt;: This script provides a single command called &lt;code&gt;:Blog&lt;/code&gt; that simply opens a temporary blogger file which in turn sources the blogger.vim filetype plugin.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;ftplugin/blogger/blogger.vim&lt;/strong&gt;: This is the filetype plugin that contains the rest of the plugin's functionality.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;syntax/blogger.vim&lt;/strong&gt;: The included syntax file provides highlighting to buffers with the filetype &lt;code&gt;blogger&lt;/code&gt;. It is essentially the Markdown syntax file found &lt;a href='http://www.plasticboy.com/markdown-vim-mode/'&gt;here&lt;/a&gt; with a few vim-blogger specific additions.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;ftplugin/blogger/markdown.py&lt;/strong&gt;: This is the Python module found &lt;a href='http://www.freewisdom.org/projects/python-markdown/'&gt;here&lt;/a&gt; that the plugin uses to convert Markdown to HTML.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;ftplugin/blogger/html2text.py&lt;/strong&gt;: The Python module found &lt;a href='http://www.aaronsw.com/2002/html2text/'&gt;here&lt;/a&gt; which the plugin uses to convert HTML back to Markdown.
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To install, you just need to untar this tarball inside your &lt;code&gt;~/.vim/&lt;/code&gt; directory. All should fall into the appropriate locations. Next, you probably want to make Vim set the filetype to &lt;code&gt;blogger&lt;/code&gt; whenever it opens an appropriate file. To do this, put this line in your &lt;code&gt;~/.vim/filetype.vim&lt;/code&gt; file:
&lt;/p&gt;
&lt;pre&gt;autocmd! BufRead,BufNewFile     *.blogger   setf blogger
&lt;/pre&gt;&lt;p&gt;This will set the filetype accordingly whenever you open a file with the blogger extension, hence sourcing the ftplugin and syntax files.
&lt;/p&gt;

&lt;h2&gt;General Post Form&lt;/h2&gt;
&lt;p&gt;In a Vim buffer, a post generally looks like this screenshot:
&lt;/p&gt;
&lt;p&gt;&lt;img alt='post-screenshot' src='http://arker.homelinux.org/files/vim-blogger/general-post-form.png'&gt;&lt;/img&gt;
&lt;/p&gt;
&lt;p&gt;The first line in the buffer is the post subject. The last line contains the keyword &lt;code&gt;@@LABELS@@&lt;/code&gt; followed by a comma separated list of labels for this post. The stuff in the middle is the post body. One variation of this is if you are editing a post that was already published. In this case, the first line will be of the form &lt;code&gt;@@EDIT#@@&lt;/code&gt;. This is put there by the plugin, and used by the plugin. You probably don't want to delete it. In this case, the post subject will be the &lt;em&gt;second&lt;/em&gt; line in the buffer.
&lt;/p&gt;

&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;There are several commands included with the plugin. I'll briefly describe each of them here.
&lt;/p&gt;

&lt;h3&gt;Retrieving Your Most Recent Posts&lt;/h3&gt;
&lt;p&gt;Running the &lt;code&gt;:BlogIndex&lt;/code&gt; command will display a list of your most recent blog posts. By default, it will only display the last five to keep the list manageable, but it can take an integer argument if you would like to change that. A numbered list of posts is shown. To begin editing one of these posts, simply type the post number and press &lt;code&gt;Enter&lt;/code&gt;. This list also contains posts that you have saved as drafts. Drafts are distinguishable by the word &lt;code&gt;**DRAFT**&lt;/code&gt; beside the post subject.
&lt;/p&gt;

&lt;h3&gt;Retrieving Your Posts By Label&lt;/h3&gt;
&lt;p&gt;If you would like to see a list of blog posts by label, run the &lt;code&gt;:BlogQuery&lt;/code&gt; command with a comma separated list of labels that you would like to query for. Again, a numbered list is returned. To edit a specific post, type the appropriate number and press &lt;code&gt;Enter&lt;/code&gt;.
&lt;/p&gt;

&lt;h3&gt;Publishing or Updating a Post&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;:BlogPost&lt;/code&gt; command can be used to either publish a new post or to update an existing post. If the current post is marked as being a draft, then the draft status is removed and the post is published. Upon successfully issuing this command, it will appear in the list displayed by the &lt;code&gt;:BlogIndex&lt;/code&gt; command.
&lt;/p&gt;

&lt;h3&gt;Saving a Post as Draft&lt;/h3&gt;
&lt;p&gt;Just like the &lt;code&gt;:BlogPost&lt;/code&gt; command described above, the &lt;code&gt;:BlogDraft&lt;/code&gt; command sends your post to the Blogger server, only this time it is marked as a draft. The post will not appear in your blog, but will appear in the plugin's index (displayed with the &lt;code&gt;:BlogIndex&lt;/code&gt; command) as a &lt;code&gt;**DRAFT**&lt;/code&gt; post.
&lt;/p&gt;

&lt;h3&gt;Deleting a Post&lt;/h3&gt;
&lt;p&gt;To delete a post, run the &lt;code&gt;:BlogIndex&lt;/code&gt; command to get a list of posts, choose the post from the list as if you were going to edit it, and issue the &lt;code&gt;:BlogDelete&lt;/code&gt; command. The plugin will ask the user for confirmation, and upon responding with "yes" (nothing else will do), the post is deleted from your blog.
&lt;/p&gt;

&lt;h2&gt;Using or Not Using Markdown&lt;/h2&gt;
&lt;p&gt;One of the things I like about this plugin is that I can use &lt;a href='http://daringfireball.net/projects/markdown/'&gt;Markdown&lt;/a&gt; syntax to write my posts. This text is then converted by the plugin to HTML, and sent to the Blogger servers as a post. If I then want to edit that same post, the HTML code is retrieved from the server, converted &lt;em&gt;back&lt;/em&gt; to Markdown, and made available for me to edit. Some people, however, will inevitably prefer to just compose their posts in straight HTML. For these people, there is a global variable called &lt;code&gt;g:Blog_Use_Markdown&lt;/code&gt; which enables this portion of the plugin. To reduce confusion for the people who do not know about this feature of the plugin I've made this variable default to False. Therefore, if you want to use the Markdown stuff, put &lt;code&gt;let g:Blog_Use_Markdown = 1&lt;/code&gt; in your &lt;code&gt;~/.vimrc&lt;/code&gt; file.
&lt;/p&gt;

&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;Keep in mind that this plugin was written to scratch a particular itch of mine that was caused by slow web interfaces with a cruddy editor in a slow web browser on a slow laptop. I've been using it to make all of the posts that you see on this blog. However, it may or may not do what you expect when you expect it. Hopefully there are few actual &lt;em&gt;errors&lt;/em&gt;, but I'm sure there will be some as I've not fully tested the plugin under every scenario. If you do find a bug or need help getting it to work, email me at my Gmail account, username "dcraven". General comments are welcomed here on the blog.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-4520878777797082117?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/4520878777797082117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/12/vim-bloggerbeta-plugin-release.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4520878777797082117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4520878777797082117'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/12/vim-bloggerbeta-plugin-release.html' title='Vim-BloggerBeta Plugin Release'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-3343904095822241213</id><published>2006-12-15T16:38:00.001-05:00</published><updated>2006-12-15T16:38:47.834-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='td'/><title type='text'>Install Packages Available for td</title><content type='html'>
&lt;p&gt;&lt;a href='http://shorturl.blogspot.com'&gt;Jason&lt;/a&gt; has graciously created a &lt;a href='http://www.gentoo.org'&gt;Gentoo&lt;/a&gt; ebuild for td and made it available for download &lt;a href='http://gentooiccduo.googlecode.com/svn/trunk/overlay/app-text/td/td-0.3.ebuild'&gt;here&lt;/a&gt;. It looks like it even installs the td.vim file in the appropriate spot. Neato. Thanks for that!
&lt;/p&gt;
&lt;p&gt;This inspired me to make a deb file so that it's installable via apt on Ubuntu systems. The deb file for version 0.3 is available from &lt;a href='http://arker.homelinux.org/files/td_0.3-ubuntu1_all.deb'&gt;here&lt;/a&gt;. I've only tested this deb by installing it once on my own system. I'm not a package building expert by any means though. Let me know if there are problems with it. &lt;a href='http://lintian.debian.org/'&gt;Lintian&lt;/a&gt; doesn't seem to have any issues at all with it. There's a first.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-3343904095822241213?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/3343904095822241213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/12/install-packages-available-for-td.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3343904095822241213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3343904095822241213'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/12/install-packages-available-for-td.html' title='Install Packages Available for td'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-561219429736780726</id><published>2006-12-14T18:39:00.001-05:00</published><updated>2007-10-29T21:49:36.894-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='td'/><title type='text'>Version 0.3 of td Released</title><content type='html'>&lt;p&gt;You thought this day would never come. The highly anticipated 0.3 release of the &lt;a href='http://djcraven5.blogspot.com/2006/12/td-command-line-todo-list-manager.html'&gt;td&lt;/a&gt; command line task list manager is finally ready for public release! There have been a few fixes and additions to the feature list. I keep adding features here and there as I find things lacking during daily use. Here is a list of what's been added since I rolled the 0.2 tarball: 
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Support for 'hidden' tasks has been added. 
 &lt;/li&gt;

 &lt;li&gt;
     Tasks can be grouped by and assigned to projects. 
 &lt;/li&gt;

 &lt;li&gt;
     You can keep details or notes associated with your tasks. 
 &lt;/li&gt;

 &lt;li&gt;
     Support for dark or light console backgrounds. 
 &lt;/li&gt;

 &lt;li&gt;
     Choose between terse or more verbose "feedback" from commands. 
 &lt;/li&gt;

 &lt;li&gt;
     Man pages are added for both td(1) itself, and the new tdrc(5) configuration file. 
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think that's pretty much it. To be honest I can't really remember what was in 0.2 to begin with. The tarball can be downloaded from &lt;a href='http://arker.homelinux.org/files/td-0.3.tar.gz'&gt;here&lt;/a&gt;, and the &lt;a href='http://djcraven5.blogspot.com/2006/12/td-command-line-todo-list-manager.html'&gt;original post&lt;/a&gt; has been updated to reflect the new features. 
&lt;/p&gt;
&lt;p&gt;Hopefully my server can handle the huge amounts of downloads expected over the next few days. If not, I may need to seek hosting elsewhere ;). If you have any bug reports or feature requests, please send them to me at my gmail address with username "dcraven". General comments can either be emailed to me or left in the comments section of this blog. Either way, they are appreciated.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-561219429736780726?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/561219429736780726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/12/version-03-of-td-released.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/561219429736780726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/561219429736780726'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/12/version-03-of-td-released.html' title='Version 0.3 of td Released'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-2944933562344791473</id><published>2006-12-07T12:19:00.001-05:00</published><updated>2007-10-29T21:50:37.357-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='td'/><title type='text'>td Gets Project Stuff</title><content type='html'>&lt;p&gt;Borrowing both the idea and the syntax from &lt;a href='http://todotxt.com'&gt;here&lt;/a&gt;, I have added similar project functionality to &lt;a href='http://djcraven5.blogspot.com/2006/12/td-command-line-todo-list-manager.html'&gt;td&lt;/a&gt;. Now you can assign a task to a project by including a word in the description that is prefixed with 'p:'. For example, the following command will add a task to the "Office" project. 
&lt;/p&gt;
&lt;pre&gt;$ td add p:Office Phone that guy about the thing.
&lt;/pre&gt;&lt;p&gt;The difference between the implementation in td and the one at todotxt.com is that, in the above example, the task will appear in any displayed list as "Phone that guy about the thing.". That is, the "p:Office" part is removed. I think this keeps the descriptions a little cleaner. 
&lt;/p&gt;
&lt;p&gt;Of course, this demanded an new command be added to the arsenal. That new command is &lt;code&gt;proj&lt;/code&gt;. If the command &lt;code&gt;td proj&lt;/code&gt; is given at the command-line, then a list of projects containing tasks is displayed. If however you provide a specific project like &lt;code&gt;td proj Office&lt;/code&gt;, then a list of incomplete tasks belonging to that project is returned. The returned list is numbered as if a list of &lt;em&gt;all&lt;/em&gt; incomplete tasks were requested, however, the tasks &lt;em&gt;not&lt;/em&gt; belonging to the specified project are filtered out. To remove a task from a project, use the &lt;code&gt;rep&lt;/code&gt; command, and exclude the prefixed word from the new description. 
&lt;/p&gt;
&lt;p&gt;There is no tarball of td that includes this stuff just yet, so if you want to try it, you can check it out of the SVN repository located at &lt;a href='http://arker.homelinux.org/td/'&gt;http://arker.homelinux.org/td/&lt;/a&gt; for now. Just like a good repository should, it also includes some glaring bugs that were found in the 0.2 tarball :). 
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE (Dec 14, 2006)&lt;/strong&gt;: I've started to use &lt;a href='http://bazaar-vcs.org/'&gt;bazaar&lt;/a&gt; as a version control system for the td source code now. I've not used it before, so it sounded like fun. The bazaar branch can be found at &lt;a href='http://arker.homelinux.org/~dcraven/bazaar/td/'&gt;http://arker.homelinux.org/~dcraven/bazaar/td/&lt;/a&gt;. I hope it works.
&lt;/p&gt;
&lt;p&gt;In the case where find a bug, or even have a feature request, email a bug report to me at &lt;strong&gt;dcraven at gmail dot com&lt;/strong&gt;. 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-2944933562344791473?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/2944933562344791473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/12/td-gets-project-stuff.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/2944933562344791473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/2944933562344791473'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/12/td-gets-project-stuff.html' title='td Gets Project Stuff'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-6146651975979537602</id><published>2006-12-05T20:34:00.001-05:00</published><updated>2007-07-29T11:35:03.199-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='td'/><title type='text'>td - A Command-line Todo List Manager</title><content type='html'>
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; As of version 0.4, td depends on &lt;a href='http://labix.org/python-dateutil'&gt;python-dateutils&lt;/a&gt; for date manipulation functions. Please make sure you have this installed prior to using td.
&lt;/p&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Over a year ago, &lt;a href='http://shorturl.blogspot.com'&gt;a friend of mine&lt;/a&gt; and I began tinkering with a little todo list program as we played with Python. We just wanted something simple and fast that could be used from the bash prompt without the fuss of a GUI. The result was a little script that we called &lt;code&gt;td&lt;/code&gt;. For the past year, not much changed with it. I did a bit of work on it while learning how to use gnome-vfs, and added the ability to use remote data transparently. A couple of days ago, I began playing with it again. I added a few new and useful features, and decided to make it available to everyone in case somebody out there wanted such a tool. I'll outline the features of the program here. 
&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;The latest tarball of &lt;code&gt;td&lt;/code&gt; can be downloaded from &lt;a href='http://arker.homelinux.org/files/td-0.4.tar.gz'&gt;here&lt;/a&gt;, and is installable using the GNU autotools. In summary, navigate to the directory that has the downloaded tarball and type the following commands. 
&lt;/p&gt;
&lt;pre&gt;$ tar xvzf td-0.4.tar.gz
$ cd td-0.4/
$ ./configure
$ make
$ make install
&lt;/pre&gt;&lt;p&gt;You should now be able to run the program by typing &lt;code&gt;td&lt;/code&gt; at the command line. 
&lt;/p&gt;

&lt;h2&gt;Features&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;td&lt;/code&gt; script has the ability to add, delete, complete, prioritize, and archive tasks. This section will document each feature one at a time. 
&lt;/p&gt;

&lt;h3&gt;Displaying Tasks&lt;/h3&gt;
&lt;p&gt;Just running the command &lt;code&gt;td&lt;/code&gt; with no arguments will display a list of outstanding tasks, sorted by descending priority. The output looks like this: 
&lt;/p&gt;
&lt;p&gt;&lt;img alt='td screenshot' src='http://arker.homelinux.org/images/td/td-display.png'/&gt;
&lt;/p&gt;
&lt;p&gt;The output contains the item or task number, the priority of the task, the creation date, and the task summary itself. The task number shown in this list is useful for performing various other commands. The last line of output displays the number of shown tasks, and the number hidden (not shown). 
&lt;/p&gt;

&lt;h3&gt;Adding a New Task&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;add&lt;/code&gt; command adds a new task to the list. For example: 
&lt;/p&gt;
&lt;pre&gt;
$ td add Remind Jason to schedule his proposal.
&lt;/pre&gt;&lt;p&gt;This procedure is limited only by what is acceptable at the bash prompt. That is, things like quotes need to be escaped for example. 
&lt;/p&gt;
&lt;pre&gt;
$ td add These \"quotes\" are escaped.
&lt;/pre&gt;
&lt;h3&gt;Deleting a Task&lt;/h3&gt;
&lt;p&gt;Deleting tasks can be done by specifying the task number to delete. For example, 
&lt;/p&gt;
&lt;pre&gt;
$ td del 2
&lt;/pre&gt;&lt;p&gt;The above command will obviously delete task number 2 from the task list. Once deleted, tasks can no longer be accessed. 
&lt;/p&gt;

&lt;h3&gt;Deferring a Task&lt;/h3&gt;
&lt;p&gt;Sometimes you want to add a task to your list now, but don't want it to clutter up your task list until some date in the future. To do this, you would use the &lt;code&gt;defer&lt;/code&gt; command. This command takes several types of parameters to determine the date to defer the task to. For example, the following command will defer task number 4 one week into the future.
&lt;/p&gt;
&lt;pre&gt;$ td def 4 1w
&lt;/pre&gt;&lt;p&gt;Similar short forms exist for days (d), months (m), and years (y). The defer command also uses the &lt;a href='http://labix.org/python-dateutil'&gt;python-dateutils&lt;/a&gt; to parse dates described by natural language. For example the following command will defer task number 4 to August 5th of this year:
&lt;/p&gt;
&lt;pre&gt;$ td def 4 aug 5
&lt;/pre&gt;&lt;p&gt;If no further arguments are given to the &lt;code&gt;defer&lt;/code&gt; command, a list of deferred tasks are displayed with their creation date, and the date they have been deferred to. Deferred tasks will not appear in the regular task list until their defer date is reached.
&lt;/p&gt;

&lt;h3&gt;Undeferring a Task&lt;/h3&gt;
&lt;p&gt;If a task has been deferred to a future date, it can be made current again by using the &lt;code&gt;undefer&lt;/code&gt; command. Obtain the task number by running td with the &lt;code&gt;defer&lt;/code&gt; command without arguments. The following command will make the deferred task number 2 current again, hence making it display in the regular list of tasks.
&lt;/p&gt;
&lt;pre&gt;$ td undef 2
&lt;/pre&gt;
&lt;h3&gt;Task Details&lt;/h3&gt;
&lt;p&gt;Some tasks require further details to clarify it further, or maybe just a place to store additional braindumps that you'd like to jot down. Details or notes can be added to a task using the &lt;code&gt;details&lt;/code&gt; command. This command will cause your favourite editor to open, allowing you to type your notes. This additional data will be stored with the task data, and can be accessed by running the &lt;code&gt;details&lt;/code&gt; command again on the same task. The following command can be used to added details to task number 4 in the list. 
&lt;/p&gt;
&lt;pre&gt;$ td details 4
&lt;/pre&gt;
&lt;h3&gt;Display Hidden Tasks&lt;/h3&gt;
&lt;p&gt;To display all incomplete tasks including the tasks marked hidden, use the &lt;code&gt;hid&lt;/code&gt; command. 
&lt;/p&gt;
&lt;pre&gt;$ td hid
&lt;/pre&gt;&lt;p&gt;This will show all incomplete tasks in the list with an additional column marked "H". Each task that is marked hidden in the list will contain an asterisk in this column. 
&lt;/p&gt;

&lt;h3&gt;Prioritizing a Task&lt;/h3&gt;
&lt;p&gt;Prioritizing tasks can be done using the &lt;code&gt;pri&lt;/code&gt; command. Entering the following command will assign task number 3 to the highest priority. 
&lt;/p&gt;
&lt;pre&gt;
$ td pri 3 A
&lt;/pre&gt;&lt;p&gt;Priorities can be any single letter, and the display will be sorted by this key in descending order. Priorities of A, B, and C have distinct colours in the display output. Other priorities are just dark grey. By default, new tasks are given no priority at all. To remove the priority that was previously assigned to a task, run the same command, but exclude the priority. 
&lt;/p&gt;
&lt;pre&gt;$ td pri 3
&lt;/pre&gt;&lt;p&gt;This command will remove the priority from task 3. 
&lt;/p&gt;

&lt;h3&gt;Assigning Tasks to a Project&lt;/h3&gt;
&lt;p&gt;Tasks can be grouped into "projects" in td. To add a task to a specific project, you must include the project's name, prefixed with a "p:" somewhere in the tasks summary. The following command adds a task to the Office project. 
&lt;/p&gt;
&lt;pre&gt;$ td add p:Office Call Steve to schedule a meeting.
&lt;/pre&gt;&lt;p&gt;If you would like to see a list of projects that have outstanding tasks associated with them, you can use the &lt;code&gt;proj&lt;/code&gt; command with no parameters. This will provide a comma separated list of projects. To display a list of tasks assigned to a specific project, run the same command with the project as an argument. This command displays all tasks under the Office project. 
&lt;/p&gt;
&lt;pre&gt;$ td proj Office
&lt;/pre&gt;&lt;p&gt;Already existing tasks may be added to a project using the &lt;code&gt;rep&lt;/code&gt; (replace) command with the "p:" prefixed project in the new summary. 
&lt;/p&gt;

&lt;h3&gt;Assigning Tags to a Task&lt;/h3&gt;
&lt;p&gt;The td program supports "tagging" tasks with searchable tags. This can either be done when adding a new task, or after a task has already been created. To create a task with a set of tags, include the space separated tags in the task summary enclosed in square brackets. The following command creates a new task with the tags "work" and "python":
&lt;/p&gt;
&lt;pre&gt;$ td add [work python]Script the emulator to run tests over night.
&lt;/pre&gt;&lt;p&gt;If you want to add tags to an already created task, you can use the &lt;code&gt;tags&lt;/code&gt; command. To do this, append the tag with a '+' sign prepended to it. Removing tags from a task can be performed by appending a tag with a '-' sign. For example, the following command adds the tag "work", and removes the tag "python" from task number 5:
&lt;/p&gt;
&lt;pre&gt;$ td tags 5 +work -python
&lt;/pre&gt;&lt;p&gt;To view a list of tags that have been assigned to any task, use the &lt;code&gt;tags&lt;/code&gt; command with no arguments. This will display all tags as well as the number of tasks that have that tag assigned to them. Also, to see a list of tasks with a give tag or set of tags, use the &lt;code&gt;tags&lt;/code&gt; command with the tags of interest as an argument. For example, the following command will display a list of incomplete tasks that have been tagged with "work" and "python":
&lt;/p&gt;
&lt;pre&gt;$ td tags work python
&lt;/pre&gt;&lt;p&gt;To view a list of tasks that have no tags assigned to them, use the &lt;code&gt;notag&lt;/code&gt; command with no arguments.
&lt;/p&gt;

&lt;h3&gt;Completing a Task&lt;/h3&gt;
&lt;p&gt;Tasks can be marked as complete by issuing the &lt;code&gt;do&lt;/code&gt; command. Once marked complete, tasks will no longer appear in the normal display list, and a completion date is assigned to them. The following command will mark task number 2 as being completed. 
&lt;/p&gt;
&lt;pre&gt;
$ td do 2
&lt;/pre&gt;
&lt;h3&gt;Viewing Completed Tasks&lt;/h3&gt;
&lt;p&gt;As mentioned, once marked complete a task will no longer be listed in the normal task list display. To view all completed tasks, issue the &lt;code&gt;done&lt;/code&gt; command like this: 
&lt;/p&gt;
&lt;pre&gt;
$ td done
&lt;/pre&gt;&lt;p&gt;This will display a list containing a task number, creation date, completion date, and task summary. The displayed task number will be useful for performing various commands on completed tasks. 
&lt;/p&gt;

&lt;h3&gt;Marking Completed Tasks as Incomplete&lt;/h3&gt;
&lt;p&gt;If you have marked a task as complete by accident, or otherwise decide that a completed task should be reopened, you may issue the &lt;code&gt;undo&lt;/code&gt; command. 
&lt;/p&gt;
&lt;pre&gt;
$ td undo 2
&lt;/pre&gt;&lt;p&gt;The above command will mark the &lt;em&gt;completed&lt;/em&gt; task number 2 as incomplete. The task number is the one displayed in the list provided by the &lt;code&gt;done&lt;/code&gt; command. This task will now appear in the normal listing, and has no assigned completion date. 
&lt;/p&gt;

&lt;h3&gt;Replacing a Task&lt;/h3&gt;
&lt;p&gt;You may modify the summary of a given task by using the &lt;code&gt;rep&lt;/code&gt; command. When given a task number, this simply replaces the summary of that task with the new one provided. 
&lt;/p&gt;
&lt;pre&gt;
$ td rep 3 Fix a spelling mistake in this task.
&lt;/pre&gt;
&lt;h3&gt;Searching for Tasks&lt;/h3&gt;
&lt;p&gt;Tasks can be filtered by providing search patterns to the &lt;code&gt;filt&lt;/code&gt; command. By giving a series of patterns, only those tasks who's summary match &lt;em&gt;all&lt;/em&gt; patterns will be displayed. The resulting list will be numbered as if the full list was being displayed, but the tasks which do not match the patterns will be "filtered". This operation uses a &lt;em&gt;smartcase&lt;/em&gt; search, which means if any of the given patterns contain at least one upper case letter, then the search will be case sensitive. If none of the letters in the pattern are upper case, then the search will be case insensitive. See the following examples. 
&lt;/p&gt;
&lt;pre&gt;$ td filt case insensitive
$ td filt cAse sEnsItiVe
&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;filt&lt;/code&gt; command can take as many patterns as you wish, in any order. Only the tasks matching &lt;em&gt;all&lt;/em&gt; patterns will be displayed. 
&lt;/p&gt;

&lt;h3&gt;Archiving Tasks&lt;/h3&gt;
&lt;p&gt;Once completed, tasks may be archived in a text file in case you would like to keep them for future reference. The text file is stored in &lt;code&gt;~/.td/td_archive.txt&lt;/code&gt;. The file contains the summary, associated project, the creation date, and the completion date of all archived tasks. This operation permanently removes tasks from the todo list. You may archive a single task by providing its number, or all completed tasks by specifying &lt;code&gt;all&lt;/code&gt; as an argument to the &lt;code&gt;archive&lt;/code&gt; command. If no argument is given, &lt;code&gt;td&lt;/code&gt; will ask you if you would like to archive all completed tasks. Answering "yes" will perform the archiving, anything else will abort. So basically, both of the following commands will work as expected. 
&lt;/p&gt;
&lt;pre&gt;
$ td archive all
$ td archive 3
&lt;/pre&gt;
&lt;h3&gt;Purging Tasks&lt;/h3&gt;
&lt;p&gt;To just delete all completed tasks (unarchived) without saving them in the archive, issue the &lt;code&gt;purge&lt;/code&gt; command. If given a task number, that task alone will be purged. If no task number is given, the user is asked for confirmation, and &lt;em&gt;all&lt;/em&gt; complete tasks are purged. 
&lt;/p&gt;
&lt;pre&gt;$ td purge 3
&lt;/pre&gt;&lt;p&gt;This command will only purge task 3, without confirmation. 
&lt;/p&gt;
&lt;pre&gt;$ td purge
&lt;/pre&gt;&lt;p&gt;This command will prompt the user for confirmation, then purge all completed tasks. Purged tasks are lost, and cannot be recovered. 
&lt;/p&gt;

&lt;h3&gt;Getting Help&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;td help&lt;/code&gt; command simply prints a message with a terse description of all the available commands, and their usage. 
&lt;/p&gt;

&lt;h3&gt;Specifying Your Data Source&lt;/h3&gt;
&lt;p&gt;This really only applies if you do not have gnome-vfs and its Python bindings installed. To set the data source after first run (see below), you can issue the &lt;code&gt;source&lt;/code&gt; command. Doing this without the presence of gnome-vfs has no effect. However, you can change your data source to a remote file if you do have gnome-vfs installed. For example, the following command will make &lt;code&gt;td&lt;/code&gt; use a remote file to store data over ssh. 
&lt;/p&gt;
&lt;pre&gt;
$ td source sftp://your.host.com:/home/username/.td/todos.xml
&lt;/pre&gt;&lt;p&gt;From this point on you can use td as usual, and it will transparently use the data file stored at the given URI. The &lt;code&gt;source&lt;/code&gt; command also takes the "local" argument (see below). 
&lt;/p&gt;

&lt;h4&gt;Without GNOME-VFS&lt;/h4&gt;
&lt;p&gt;If you do not have gnome-vfs and its Python bindings installed, the program will automatically store your todo list in the file &lt;code&gt;~/.td/todos.xml&lt;/code&gt;. There are no remote data capabilities without using gnome-vfs. 
&lt;/p&gt;

&lt;h4&gt;With GNOME-VFS&lt;/h4&gt;
&lt;p&gt;The presence of gnome-vfs and its Python bindings will be detected when the program is run. On first run, td will ask you to enter a data source. This basically just means that it needs to know where to store your data. If you enter "local" then your data will be stored locally in the file &lt;code&gt;~/.td/todos.xml&lt;/code&gt;. If you want to use remote data, enter any valid gnome-vfs URI to use that location. For example, the to use a data file stored in your home directory on a remote server, you could use &lt;code&gt;sftp://your.host.com:/home/username/.td/todos.xml&lt;/code&gt; to make &lt;code&gt;td&lt;/code&gt; use that data over ssh. 
&lt;/p&gt;

&lt;h2&gt;Types of Tasks&lt;/h2&gt;
&lt;p&gt;td maintains three types of tasks in its lists. This section will briefly describe each. 
&lt;/p&gt;

&lt;h3&gt;Incomplete Tasks&lt;/h3&gt;
&lt;p&gt;Incomplete tasks are basically any type of task that is not marked as complete. This is the default type when a task is created. These obviously represent tasks that are not yet completed, and which the user wants to appear in the default task list. 
&lt;/p&gt;

&lt;h3&gt;Hidden Tasks&lt;/h3&gt;
&lt;p&gt;These are a subset of incomplete tasks. They are treated the same, except the user doesn't want to see them in the default task list. Reasons for this may be to reduce clutter if for example the task is long term. Other reasons for marking a task as hidden are up to the user. Tasks are marked as hidden when, upon creation, the task summary provided begins with a period ("."), just like hidden files on the Unix file system. To mark a hidden task as no longer being hidden, use the replace command and enter a summary without the leading period. Similarly, to mark an already existing task as hidden, simply replace the current summary with one beginning with a period. 
&lt;/p&gt;

&lt;h3&gt;Completed Tasks&lt;/h3&gt;
&lt;p&gt;Tasks that have been marked as complete with the &lt;code&gt;do&lt;/code&gt; command are no longer displayed in the default task list. To view these tasks, use the &lt;code&gt;done&lt;/code&gt; command. To mark a completed task as incomplete, use the &lt;code&gt;undo&lt;/code&gt; command. Only tasks marked as completed are available to the &lt;code&gt;purge&lt;/code&gt; and &lt;code&gt;archive&lt;/code&gt; commands. 
&lt;/p&gt;

&lt;h2&gt;The ~/.tdrc Configuration File&lt;/h2&gt;
&lt;p&gt;td now looks in &lt;code&gt;$HOME/.tdrc&lt;/code&gt; if it exists for a few optionally configurable settings. This section will describe these settings. 
&lt;/p&gt;
&lt;p&gt;The syntax used by the tdrc file is pretty typical for any configuration file. Entries are generally of the form &lt;code&gt;{KEY} = {VALUE}&lt;/code&gt;. Pretty straightforward stuff. If the file doesn't exist, or only a subset of the options are specified in it, then sane defaults are chosen. 
&lt;/p&gt;

&lt;h3&gt;Background Colour&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;background&lt;/code&gt; option informs td of the type of background on the user's xterm. If the xterm background is dark, then typically darker coloured text doesn't show up well. Setting this option to &lt;code&gt;dark&lt;/code&gt; instructs td to use brighter colours for its output. Setting it to &lt;code&gt;light&lt;/code&gt; instructs td to use more subtle colouring suitable for light backgrounds. The default value for this option is &lt;code&gt;light&lt;/code&gt;. 
&lt;/p&gt;

&lt;h3&gt;Feedback Level&lt;/h3&gt;
&lt;p&gt;Sets the level of feedback that td should provide to the user. If the value of the &lt;code&gt;feedback&lt;/code&gt; key is set to &lt;code&gt;verbose&lt;/code&gt;, then positive feedback will be provided upon successful completion of commands. If set to &lt;code&gt;terse&lt;/code&gt; then only errors will be displayed. The default value for this option is &lt;code&gt;verbose&lt;/code&gt;. 
&lt;/p&gt;

&lt;h3&gt;Preferred Editor&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;editor&lt;/code&gt; sets the preferred editor to be used when modifying the notes or details portion of a task. When deciding what editor to use, td will first check the &lt;code&gt;$HOME/.tdrc&lt;/code&gt; file for a value. If none is set, then the value of &lt;code&gt;$EDITOR&lt;/code&gt; is used. If still no value is found then &lt;a href='http://www.vim.org'&gt;Vim&lt;/a&gt; is used. This value can contain either a full path to the executable or just the executable file name provided it can be found in your &lt;code&gt;$PATH&lt;/code&gt;. The default for this option is &lt;code&gt;vim&lt;/code&gt;. 
&lt;/p&gt;

&lt;h2&gt;Extra Stuff&lt;/h2&gt;
&lt;p&gt;I like syntax colouring, and I use &lt;a href='http://www.vim.org'&gt;Vim&lt;/a&gt; for all of my editing. I made a &lt;em&gt;very&lt;/em&gt; simple syntax file for editing td task details. It provides colours for the first line of the details file which indicates the project and the task summary. I also like to enter most of my notes in point form, so this syntax file also highlights lines beginning with an asterisk :). I know, I'm lame. 
&lt;/p&gt;
&lt;p&gt;Anyways, this syntax file is available in the td tarball and will be installed into the &lt;code&gt;$PREFIX/share/td/extras/&lt;/code&gt; directory on your file system. To use it, copy it to &lt;code&gt;$HOME/.vim/syntax/&lt;/code&gt; and add the following line to your &lt;code&gt;$HOME/.vim/filetype.vim&lt;/code&gt; file. 
&lt;/p&gt;
&lt;pre&gt;autocmd! BufRead,BufNewFile     *.td    setf td
&lt;/pre&gt;&lt;p&gt;After doing this, you should see the syntax highlighting the next time you run the &lt;code&gt;details&lt;/code&gt; command in td. 
&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you decide to use &lt;code&gt;td&lt;/code&gt; or at least try it out, you can probably expect a bug or two. If that is the case, or you need some clarification, feel free to email me so I can help. Although I don't expect there to be much demand for a tool like this one, if somebody besides me would find it useful, I'd like to make it work for them too. 
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-6146651975979537602?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/6146651975979537602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/12/td-command-line-todo-list-manager.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6146651975979537602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6146651975979537602'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/12/td-command-line-todo-list-manager.html' title='td - A Command-line Todo List Manager'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-3053017707551499914</id><published>2006-11-27T15:05:00.001-05:00</published><updated>2006-11-27T15:05:25.119-05:00</updated><title type='text'>Overreact Much?</title><content type='html'>
&lt;p&gt;The recent &lt;a href='http://www.linux.com/article.pl?sid=06/11/25/028237'&gt;kerfluffle&lt;/a&gt; over the &lt;a href='http://lists.opensuse.org/opensuse/2006-11/msg03765.html'&gt;post&lt;/a&gt; that Shuttleworth made on the openSUSE mailing list has me torn. First of all, and this is in no particular order, I think it's clear that Shuttleworth is just extending a friendly invitation to those developers that feel abandoned by the &lt;a href='http://www.novell.com/linux/microsoft/'&gt;deal&lt;/a&gt;. That being said, however, it does serve his purpose to some extent as an email like this may poke said developer into action (ie. jumping ship) when otherwise he/she would have given into his passive ways and stayed where they were comfortable. Also, I think it is fairly well known that volunteer developers are typically welcomed, if not encouraged, to join any project they so desire. The fact that Ubuntu accepts new developers really isn't news. Whether the email was &lt;em&gt;really&lt;/em&gt; composed as an innocent invitation, or as some kind of weird stunt, I guess we'll never know. And frankly, who cares?
&lt;/p&gt;
&lt;p&gt;On the other hand, I also think the openSUSE developers are &lt;a href='http://lists.opensuse.org/opensuse/2006-11/msg03766.html'&gt;overreacting&lt;/a&gt; a little in their responses. The most effective way to answer an unwelcome post like this is to not answer it at all. Being childish and bad mouthing competing distros is uncalled for, and that's exactly what some of those responses do. Swinging again in the other direction, however, what did Shuttleworth really expect? It's not difficult to predict that an email like this will be met with hostile resentment. It's not as though Gore invented the Internet just last week or anything. We've all see this stuff before, many times over. Someone (Shuttleworth) does something unacceptable, the victims (openSUSE devs) cry and toss insults back in response, then thousands of uninvolved peons (me) blog about it for weeks. Prodding people to leave the distro that they are clearly passionate about rarely ends nicely.
&lt;/p&gt;
&lt;p&gt;In my opinion Shuttleworth was silly to even think about making such a post to the mailing list. The guy is in no position to sing about unity and software freedom after making the decision to ship and install non-free binary drivers by default with the next Ubuntu release. I mean, let's face it. If I were an openSUSE developer who was looking to move elsewhere as a direct result of this deal, I'd make an attempt to decide which distro/company would &lt;em&gt;least&lt;/em&gt; likely wind up doing the same thing to me in the future. If we lined up all of the major distros (Fedora, Debian, Mandriva, etc.) and looked at them in this light, I think many of us would agree which one we would add to the avoid list. The future of Ubuntu "freedom" spooks me a bit for some reason. I can't quite put my finger on the reason though.
&lt;/p&gt;
&lt;p&gt;I got a kick out of how &lt;a href='http://trends.newsforge.com/comments.pl?sid=60475&amp;amp;op=&amp;amp;threshold=0&amp;amp;commentsort=0&amp;amp;mode=thread&amp;amp;tid=138&amp;amp;tid=150&amp;amp;pid=131632#131633'&gt;this guy&lt;/a&gt; compares the Microvell deal and Ubuntu's commitment to freedom in a comment on the Newsforge article:
&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Microsoft+Novell deal involves:
   *Not sueing people.
&lt;/p&gt;
&lt;p&gt;Ubuntu involves:
   *Singing the praises of Free Software and all about how all software should be Free, yay, la la la, let's get around the bonfire and sing Koombayah and dress up the desktop in brown colors because it's all about humans and people and being human and proprietary software is bug #1 and...
&lt;/p&gt;
&lt;p&gt;*Except it actually isn't totally free software. Oops! We'll stick that in under bug #123581352.
&lt;/p&gt;
&lt;p&gt;*...But hey you SuSE goes can come develop for us cause we're more about Freedom and Unity with a capital F and U! 
&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Not sure why, but I found that funny.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-3053017707551499914?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/3053017707551499914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/11/overreact-much.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3053017707551499914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3053017707551499914'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/11/overreact-much.html' title='Overreact Much?'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-8482422276542756561</id><published>2006-11-19T16:04:00.001-05:00</published><updated>2006-11-19T18:07:20.243-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tracker'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='FOSS'/><title type='text'>Replacing Mono Applications</title><content type='html'>
&lt;p&gt;Since Novell &lt;a href='http://www.novell.com/linux/microsoft/'&gt;admits to violating software patents&lt;/a&gt; in their code, and points at you and I for using offending software, I'm making an attempt to partially rid my machines of it. First to go, of course, is anything related to Mono. This means &lt;a href='http://banshee-project.org/'&gt;Banshee&lt;/a&gt;, &lt;a href='http://f-spot.org/'&gt;F-Spot&lt;/a&gt; and &lt;a href='http://beagle-project.org/Main_Page'&gt;Beagle&lt;/a&gt; need replacements. Replacing Banshee won't be a big deal in my case, since I don't really listen to music on my computer very often anyways. Also there must be a ton of music players out there. I think &lt;a href='http://www.sacredchao.net/quodlibet/'&gt;QuodLibet&lt;/a&gt; wins in this category for now just because it's written in Python. 
&lt;/p&gt;
&lt;p&gt;F-Spot will be a little more difficult for me to get rid of since I've become quite accustomed to using it. For the time being, however, I'll switch back to using the quite capable &lt;a href='http://gthumb.sourceforge.net/'&gt;gThumb&lt;/a&gt;. Also since F-Spot uses a weird format for storing data (meaningless directory structures etc), there will be some effort required in converting it to something that makes sense to use with gThumb. 
&lt;/p&gt;
&lt;p&gt;Beagle has already been replaced by the much faster, leaner, and command line friendly &lt;a href='http://www.gnome.org/~jamiemcc/tracker/'&gt;Tracker&lt;/a&gt;. This was a switch that would have happened regardless of Novell's actions, so I've got no problems there. I'll not go into great detail about Tracker now since this would probably warrant its own post, but this is a project that I hope has a bright future. 
&lt;/p&gt;
&lt;p&gt;Removing Mono and all (I think) related packages from your Ubuntu install is as easy as:
&lt;/p&gt;
&lt;pre&gt;sudo aptitude remove libmono0
&lt;/pre&gt;&lt;p&gt;That will remove all kinds of stuff, including the &lt;code&gt;ubuntu-desktop&lt;/code&gt; package. Read the list of packages before pressing &lt;code&gt;Y&lt;/code&gt; so that you have no suprises. As of Edgy, Ubuntu ships with Mono since Tomboy and F-Spot are in the default desktop configuration. I am curious to see where Canonical takes this, if anywhere at all. It's probably about time I &lt;a href='http://fedoraproject.org/wiki/'&gt;moved on&lt;/a&gt; anyways.
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;PS: To all of you who are pointing at me, laughing, and shrieking "I told you so!", yeah yeah I know... I guess I should have seen this coming.&lt;/em&gt;
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-8482422276542756561?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/8482422276542756561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/11/replacing-mono-applications.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/8482422276542756561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/8482422276542756561'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/11/replacing-mono-applications.html' title='Replacing Mono Applications'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-6084245953849207138</id><published>2006-11-15T19:06:00.001-05:00</published><updated>2006-11-15T19:21:44.457-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><category scheme='http://www.blogger.com/atom/ns#' term='irssi'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Beep, SSH, and Perl 101</title><content type='html'>
&lt;p&gt;I typically have my IRC &lt;a href='http://www.irssi.org'&gt;client&lt;/a&gt; running on a remote machine in a &lt;a href='http://csci.csusb.edu/turner/archive/notes/screen.html'&gt;screen&lt;/a&gt; session so that I can SSH from my laptop and attach to that session from anywhere. This is a great system, but the one thing it lacked was audible notification of highlighted messages. For the last few months I've used the &lt;a href='http://www.irssi.org/scripts/scripts/hilightwin.pl'&gt;hilightwin.pl&lt;/a&gt; script so that any conversation that contains keywords of my choice gets displayed in a little window at the top of my screen. The script is sufficiently small enough that even though I don't know &lt;a href='http://www.perl.org'&gt;Perl&lt;/a&gt;, I was able to modify it so that &lt;em&gt;any&lt;/em&gt; special message shows up there. After being away from my keyboard it's nice to know I haven't missed anyone just by glancing at this little window.
&lt;/p&gt;
&lt;p&gt;The only thing that this system lacked was an audible beep to alert me when these messages arrive. Too often I'm just on another workspace when someone is trying to talk to me, and if I could hear the alert, I could chat back at them. Anyways, irssi does have beep functionality, but it doesn't seem to work very well through an ssh/screen session. Already long story short, inserting one line of Perl into the &lt;code&gt;hilightwin&lt;/code&gt; script solved the problem in a rather hackish, but effective manner. 
&lt;/p&gt;
&lt;pre&gt;system("ssh hostname beep -f 100 -l 50 -r 2 &amp;amp;&amp;gt; /dev/null");
&lt;/pre&gt;&lt;p&gt;This command simply opens an ssh session with my laptop (exchange &lt;code&gt;hostname&lt;/code&gt; with the actual hostname, of course), and runs the &lt;code&gt;beep&lt;/code&gt; command producing two relatively low, short beeps. They are easily distinguishable from the normal system beep. If &lt;a href='http://kimmo.suominen.com/docs/ssh/'&gt;passwordless logins&lt;/a&gt; are enabled, then you're golden. Not many people talk to me so this really doesn't add much traffic to my network :) 
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-6084245953849207138?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/6084245953849207138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/11/beep-ssh-and-perl-101.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6084245953849207138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6084245953849207138'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/11/beep-ssh-and-perl-101.html' title='Beep, SSH, and Perl 101'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-2256531511386354107</id><published>2006-11-12T16:59:00.001-05:00</published><updated>2006-11-12T16:59:43.146-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Gmail and Top Posting</title><content type='html'>
&lt;p&gt;I know many have bitched about this in the past, so I won't go off on a rant now. I am curious though if Google has addressed this anywhere that I haven't seen. As in, have they so much as acknowledged the complaints at all? Even if there were some FAQ entry somewhere that said something lame like "We at Google have decided that top posting is best practise and have no plans to support bottom posters." that would provide a feeling of closure. Instead, each time the &lt;em&gt;New Features&lt;/em&gt; indicator appears I jump all over it hoping that today is the day. It never is.
&lt;/p&gt;
&lt;p&gt;Admittedly, I do feel like a bit of a knob even complaining or mentioning this at all. It's not &lt;em&gt;that&lt;/em&gt; big of a deal to delete the space at the top, trim the replied text, and add my reply to the bottom. Also, I understand that Windows users are the majority and that Google probably doesn't wish to confuse them. But at least acknowledge good form and provide a non-default setting so that the geeks of the world who do give a shit feel loved too.
&lt;/p&gt;
&lt;p&gt;Am I alone here?
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-2256531511386354107?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/2256531511386354107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/11/gmail-and-top-posting.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/2256531511386354107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/2256531511386354107'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/11/gmail-and-top-posting.html' title='Gmail and Top Posting'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-1361491737790357909</id><published>2006-11-11T18:09:00.001-05:00</published><updated>2006-12-19T10:52:04.642-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gnucash'/><category scheme='http://www.blogger.com/atom/ns#' term='ledger'/><title type='text'>The GnuCash and Ledger Combo</title><content type='html'>&lt;p&gt;For the past month I've been using the excellent &lt;a href='http://www.gnucash.org'&gt;GnuCash 2.0&lt;/a&gt; accounting package to keep track of our (my wife's and mine) finances. It's a quality accounting package with a quick double-entry accounting style, but I found it lacking a quick and flexible querying and reporting feature. Actually this is not true. I understand the built-in reporting features are quite extensible if you are familiar with &lt;a href='http://www.gnu.org/software/guile/guile.html'&gt;Guile&lt;/a&gt;, and I mean, who isn't? 
&lt;/p&gt;
&lt;p&gt;Anyways, just yesterday, an &lt;a href='http://www.linux.com/article.pl?sid=06/11/06/2136209'&gt;article&lt;/a&gt; at &lt;a href='http://www.linux.com'&gt;Linux.com&lt;/a&gt; pointed me to a package called &lt;a href='http://www.newartisans.com/ledger.html'&gt;Ledger&lt;/a&gt;. I'll not go into great detail about the package since the linked article does a pretty good job, but suffice it to say, that it is everything we've all grown to love in a powerful command line tool. It's very fast, and very powerful (with the use of regular expressions). Of course, it doesn't produce the prettiest of reports, but it does get the information you are looking for very quickly. It even has the option to output the matching entries to your query in XML format if you wish. I think I can see some Python report generating scripts in my future :). 
&lt;/p&gt;
&lt;p&gt;As the article mentions, the package can read the data files that are produced by GnuCash. Instead of manually editing the Ledger data file as a method of entering transactions, I think I'll stick to using GnuCash as it has a very fast and efficient flow with autocompletions and all that goodness. The Ledger tool, however, is perfect for quick queries and reporting from one of my always open terminals. I think these tools will have a long and harmonious life on my desktop.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-1361491737790357909?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/1361491737790357909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/11/gnucash-and-ledger-combo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1361491737790357909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1361491737790357909'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/11/gnucash-and-ledger-combo.html' title='The GnuCash and Ledger Combo'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-4311770876491934666</id><published>2006-11-01T10:43:00.001-05:00</published><updated>2006-11-01T10:45:08.495-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='laptop'/><title type='text'>Disable Touchpad While Typing</title><content type='html'>
&lt;p&gt;I ran across &lt;a href='http://ubuntu.wordpress.com/2006/09/20/disable-touchpad-temporarily-when-typing/'&gt;this blog entry&lt;/a&gt; while browsing around aimlessly yesterday
   that I think will play a large part in keeping my sanity. It drives me crazy
   when I accidentally touch the touchpad on my laptop while typing, and the
   cursor ends up being moved to some random spot on my desktop where my typing
   resumes.
&lt;/p&gt;
&lt;p&gt;I'm not sure why this little tip is not more widely known, but I think it
   should be. Especially since it's so easy to do. Ensure the line &lt;code&gt;Option
"SHMConfig" "on"&lt;/code&gt; appears in the appropriate &lt;code&gt;Input Device&lt;/code&gt; section in your
   &lt;code&gt;/etc/X11/xorg.conf&lt;/code&gt;. Then stick the command &lt;code&gt;sysdaemon -t -d&lt;/code&gt; in your list of
   session startup commands. Here's the appropriate section of my &lt;code&gt;xorg.conf&lt;/code&gt;
   file for reference:
&lt;/p&gt;
&lt;pre&gt;Section "InputDevice"
        Identifier         "Synaptics Touchpad"
        Driver             "synaptics"
        Option             "SendCoreEvents"         "true"
        Option             "Device"                 "/dev/psaux"
        Option             "Protocol"               "auto-dev"
        Option             "HorizScrollDelta"       "0"
        Option             "SHMConfig"              "on"
EndSection
&lt;/pre&gt;&lt;p&gt;Done.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-4311770876491934666?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/4311770876491934666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/11/disable-touchpad-while-typing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4311770876491934666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4311770876491934666'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/11/disable-touchpad-while-typing.html' title='Disable Touchpad While Typing'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-6318487435879236467</id><published>2006-10-30T10:59:00.001-05:00</published><updated>2006-10-30T11:02:27.466-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Retrieving Your BloggerBeta Blog ID</title><content type='html'>
&lt;p&gt;Some people are wondering how to programatically get the &lt;code&gt;blogID&lt;/code&gt; that the
   &lt;a href='http://code.google.com/apis/gdata/blogger.html'&gt;Google Data API&lt;/a&gt; page keeps referring to. I'm not sure if this is the 
   best way or not, but I've had success using the following method in Python:
&lt;/p&gt;
&lt;pre&gt;
&lt;font color='#0000ff'&gt;def&lt;/font&gt; &lt;font color='#0000ff'&gt;getBlogID&lt;/font&gt;(uri):
    &lt;font color='#0000ff'&gt;import&lt;/font&gt; httplib2, re
    con = httplib2.Http()
    response, content = con.request(uri, &lt;font color='#a31515'&gt;'GET'&lt;/font&gt;)
    match = re.search(&lt;font color='#a31515'&gt;'blogID=(\d*)'&lt;/font&gt;, content)
    &lt;font color='#0000ff'&gt;if&lt;/font&gt; match:
        &lt;font color='#0000ff'&gt;return&lt;/font&gt; match.group(&lt;font color='#0000ff'&gt;1&lt;/font&gt;)
    &lt;font color='#0000ff'&gt;else&lt;/font&gt;:
        &lt;font color='#0000ff'&gt;print&lt;/font&gt; &lt;font color='#a31515'&gt;"BlogID retrieval failed."&lt;/font&gt;
&lt;/pre&gt;

&lt;p&gt;It's quite simple actually, it takes your blog's URL as a parameter (as in http://whatever.blogspot.com),
   and sends an empty &lt;code&gt;GET&lt;/code&gt; request to it. The response returned contains a string
   that matches the regular expression &lt;code&gt;blogID=(\d*)&lt;/code&gt;. That is, the string "blogID=" followed
   by a bunch of numbers. That bunch of numbers is the blogID. The function shown above
   extracts that number with a regular expression, and returns it.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-6318487435879236467?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/6318487435879236467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/retrieving-your-bloggerbeta-blog-id.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6318487435879236467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/6318487435879236467'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/retrieving-your-bloggerbeta-blog-id.html' title='Retrieving Your BloggerBeta Blog ID'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-5123012540478285656</id><published>2006-10-27T18:00:00.001-05:00</published><updated>2006-10-28T13:48:01.605-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>GNOME-Terminal Vim with 256 Colors</title><content type='html'>
&lt;p&gt;All this time I've been using Vim in 8 color mode assuming that my terminal (gnome-terminal) didn't support anything better. Well when using libvte version 0.13.0 or newer, it can support up to 256 colors! To pull this off in Vim is actually quite simple. You just need to tell Vim that your terminal can handle it, then use an appropriate colorscheme that takes advantage of the extra terminal colors. Telling Vim is as easy as &lt;code&gt;set t_Co=256&lt;/code&gt;. After that download a colorscheme like &lt;a href='http://www.vim.org/scripts/script.php?script_id=1243'&gt;desert256&lt;/a&gt; to make it look all pretty-like. 
&lt;/p&gt;
&lt;p&gt;&lt;img alt='Modified desert256' src='http://arker.homelinux.org/images/vim-desert256.png'&gt;&lt;/img&gt;
&lt;/p&gt;
&lt;p&gt;There's a screenshot of my Vim, running in the terminal, using a modified version of &lt;a href='http://www.vim.org/scripts/script.php?script_id=1243'&gt;desert256&lt;/a&gt;. The only modifications I made were to tone down the comments a bit (from cyan), and to alter the omni-completion menu from face-melting hot pink. If I didn't know better, I'd think that was GVim :) 
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-5123012540478285656?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/5123012540478285656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/gnome-terminal-vim-with-256-colors.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/5123012540478285656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/5123012540478285656'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/gnome-terminal-vim-with-256-colors.html' title='GNOME-Terminal Vim with 256 Colors'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-3767962737522292891</id><published>2006-10-24T18:10:00.001-05:00</published><updated>2006-10-25T05:57:24.221-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Mastering the Vim Help System</title><content type='html'>
&lt;p&gt;From hanging out in &lt;code&gt;#vim&lt;/code&gt; on the &lt;a href='http://freenode.net'&gt;Freenode&lt;/a&gt; IRC channel one thing I've noticed is that although the majority of people asking for support are more than willing to read the appropriate help topic, they are not familiar enough with the available tools to do so effectively. The Vim help system is surprisingly powerful, very well written, and very complete. This post is written to expose the Vim user to some of the less known tips about finding help within Vim. 
&lt;/p&gt;

&lt;h2&gt;The Basics&lt;/h2&gt;
&lt;p&gt;Given a command, or option, or any given topic that you'd like to find more information on, the best place to start looking for help is with the &lt;code&gt;:help&lt;/code&gt; command. For example if you want to look up details on the &lt;em&gt;expandtab&lt;/em&gt; option you would type &lt;code&gt;:help expandtab&lt;/code&gt; to get to the appropriate section as shown below. 
&lt;/p&gt;
&lt;p&gt;&lt;img alt='{@align=center}Expandtab Help Screenshot' src='http://arker.homelinux.org/images/vimhelp/expandtab-help.png'&gt;&lt;/img&gt;
&lt;/p&gt;

&lt;h2&gt;Navigation With Bookmarks&lt;/h2&gt;
&lt;p&gt;Throughout the help documentation, you will find many terms surrounded by &lt;code&gt;|&lt;/code&gt; symbols like &lt;code&gt;|these-ones|&lt;/code&gt;. These terms are references to bookmarks. If you put the cursor on one of these references and press &lt;code&gt;&amp;lt;C-]&amp;gt;&lt;/code&gt;, you will jump to that reference's corresponding bookmark. Bookmarks in the documentation are surrounded by &lt;code&gt;*&lt;/code&gt; characters like &lt;code&gt;*these-ones*&lt;/code&gt;. You can jump from topic to topic as much as you like, and pressing &lt;code&gt;&amp;lt;C-T&amp;gt;&lt;/code&gt; at any time will take you backwards one step. 
&lt;/p&gt;
&lt;p&gt;In fact, you can try the &lt;code&gt;&amp;lt;C-]&amp;gt;&lt;/code&gt; trick on &lt;em&gt;any&lt;/em&gt; word in the help system to attempt a jump to a help section on that word. The explicit references are there to take you to a specific destination though. 
&lt;/p&gt;

&lt;h2&gt;Help Completion&lt;/h2&gt;
&lt;p&gt;Ensure that that &lt;code&gt;wildmenu&lt;/code&gt; option is turned on (typing &lt;code&gt;:set wildmenu&lt;/code&gt; will enable it) and you can have some nice help topic &lt;code&gt;&amp;lt;Tab&amp;gt;&lt;/code&gt; completion. By typing &lt;code&gt;:h&lt;/code&gt; (Note: &lt;code&gt;:h&lt;/code&gt; is short for &lt;code&gt;:help&lt;/code&gt;) followed by a partial word and a &lt;code&gt;&amp;lt;Tab&amp;gt;&lt;/code&gt; you will be shown a list of help topics that &lt;em&gt;begin&lt;/em&gt; with the given pattern. Pressing &lt;code&gt;&amp;lt;Tab&amp;gt;&lt;/code&gt; repeatedly here will cycle through the option. Press &lt;code&gt;&amp;lt;Enter&amp;gt;&lt;/code&gt; to select the topic you want. The following screenshot is the result of typing &lt;code&gt;:h expa&amp;lt;Tab&amp;gt;&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;&lt;img alt='{@align=center}Tab-Completed Help' src='http://arker.homelinux.org/images/vimhelp/tab-complete-help.png'&gt;&lt;/img&gt;
&lt;/p&gt;
&lt;p&gt;Another useful tip when you only know a partial name is &lt;code&gt;&amp;lt;C-D&amp;gt;&lt;/code&gt; (Ctrl-D) completion. By typing a partial name and pressing &lt;code&gt;&amp;lt;C-D&amp;gt;&lt;/code&gt;, you will get a list of available topics &lt;em&gt;containing&lt;/em&gt; that partial word. For example, the following picture is a result of typing &lt;code&gt;:h cursor&amp;lt;C-D&amp;gt;&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;&lt;img alt='{@align=center}Ctl-D Help Completion' src='http://arker.homelinux.org/images/vimhelp/ctrl-d-complete.png'&gt;&lt;/img&gt;
&lt;/p&gt;

&lt;h2&gt;Search Help Using Regular Expressions&lt;/h2&gt;
&lt;p&gt;For more complex searches, we can use the &lt;code&gt;:helpgrep&lt;/code&gt; command. This command takes a &lt;a href='http://en.wikipedia.org/wiki/Regular_expression'&gt;regular expression&lt;/a&gt; as an argument and will return a list of all occurrences of a match found in the help documentation. For example, if you wanted to find all occurrences of the term &lt;em&gt;double-click&lt;/em&gt; you would type &lt;code&gt;:helpgrep double-click&lt;/code&gt;. The result of this command is shown below. 
&lt;/p&gt;
&lt;p&gt;&lt;img alt='{@align=center}HelpGrep Help Result' src='http://arker.homelinux.org/images/vimhelp/helpgrep-help.png'&gt;&lt;/img&gt;
&lt;/p&gt;
&lt;p&gt;As you can see in the bottom of that screenshot, there were a total of 14 occurrences of this search term in the documentation. Each of these occurrences are displayed to you one at a time. To cycle to the next occurrence, use the &lt;code&gt;:cn&lt;/code&gt; command. To cycle backwards, use the &lt;code&gt;:cp&lt;/code&gt; command. 
&lt;/p&gt;

&lt;h2&gt;Keep Your Own Tips Section&lt;/h2&gt;
&lt;p&gt;This section doesn't cover more tools for searching the help documentation, but instead it suggests a way to take advantage of the help system itself to keep track of your own tips. This is a method I've been using for about a month now, and I've found it extremely helpful. 
&lt;/p&gt;
&lt;p&gt;Start by creating a new text file in your &lt;code&gt;~/.vim/doc/&lt;/code&gt; directory. Let's call it &lt;code&gt;mytips.txt&lt;/code&gt;. Put the following line as the very first line of the new file. 
&lt;/p&gt;
&lt;pre&gt;*mytips.txt*  My own set of tips...
&lt;/pre&gt;&lt;p&gt;This is really the only line that matters as far as format goes. The rest of the file can be pretty much free form, but you will benefit by keeping it relatively organized. I keep mine divided up in sections, each section beginning with a bookmark like &lt;code&gt;*mytips-movement*&lt;/code&gt;. With these bookmarks, I can jump to these sections immediately using the &lt;code&gt;:h mytips-movement&lt;/code&gt; command just as I can jump anywhere else in the help system. In order to make your new file work as a help document, you need to run a command to generate a tags file for it like this: &lt;code&gt;:helptags ~/.vim/d/oc&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;I have several autocommands in my &lt;code&gt;~/.vimrc&lt;/code&gt; to make this process a little more automated. If you'd like to use them, stick the following lines in your &lt;code&gt;~/.vimrc&lt;/code&gt;. 
&lt;/p&gt;
&lt;pre&gt;autocmd BufWrite mytips.txt             :helptags ~/.vim/doc/
autocmd BufRead  mytips.txt             set filetype=help
autocmd BufRead  mytips.txt             set noreadonly
autocmd BufRead  mytips.txt             set modifiable

nmap &amp;lt;leader&amp;gt;h :tabnew ~/.vim/doc/mytips.txt&amp;lt;CR&amp;gt;
&lt;/pre&gt;&lt;p&gt;The first one generates a new helptags file each time you write your tips file to disk. This keeps you from having to do it manually, and ensures your tips will always be current. The second sets the filetype to 'help' so that you get the appropriate syntax highlighting when you edit your file, and the following two undo a couple of unwanted options that setting the filetype enables automatically. Finally, &lt;code&gt;&amp;lt;Leader&amp;gt;h&lt;/code&gt; is mapped to opening the new tips file in a new tab for editing (tabs are only in Vim7 or newer). 
&lt;/p&gt;
&lt;p&gt;Now, when you discover a new tip, type &lt;code&gt;&amp;lt;Leader&amp;gt;h&lt;/code&gt; (&lt;code&gt;\h&lt;/code&gt; by default, see &lt;code&gt;:he leader&lt;/code&gt;), add it to the file, and save it. Done! 
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-3767962737522292891?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/3767962737522292891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/mastering-vim-help-system.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3767962737522292891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3767962737522292891'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/mastering-vim-help-system.html' title='Mastering the Vim Help System'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-5277705470487679969</id><published>2006-10-22T18:15:00.001-05:00</published><updated>2007-10-29T22:02:18.159-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Vim-Blogger Featuring Markdown</title><content type='html'>&lt;p&gt;Yes I'm &lt;em&gt;still&lt;/em&gt; playing with this &lt;a href='http://djcraven5.blogspot.com/2006/10/see-vim-bloggerbeta-plugin-in-action.html'&gt;vim-blogger&lt;/a&gt; plugin. Now it has the
   ability to allow you to compose your post using John Gruber's &lt;a href='http://daringfireball.net/projects/markdown/'&gt;Markdown&lt;/a&gt; syntax instead
   of plain ol' ugly html :). To accomplish this task, I am using a Python
   &lt;a href='http://www.freewisdom.org/projects/python-markdown/'&gt;module&lt;/a&gt; for the conversion to HTML when posted. 
&lt;/p&gt;
&lt;p&gt;Also cool is the fact that when a post is retrieved from your blog using this
   plugin, it is converted &lt;em&gt;back&lt;/em&gt; to Markdown syntax using &lt;a href='http://www.aaronsw.com/2002/html2text/'&gt;html2text&lt;/a&gt;.
   I think this is pretty cool. Here is a screenshot of me composing this post:
&lt;/p&gt;
&lt;p&gt;&lt;img alt='Vim-BloggerBeta with Markdown' src='http://arker.homelinux.org/files/vim-blogger/vim-blogger-markdown.png'&gt;&lt;/img&gt;
&lt;/p&gt;
&lt;p&gt;As you can see, I have a Vim &lt;a href='http://www.plasticboy.com/markdown-vim-mode/'&gt;syntax file&lt;/a&gt; for Markdown files too. I've
   modified it a bit to include vim-blogger specific things like the &lt;code&gt;@@LABELS@@&lt;/code&gt;
   line at the bottom etc. I do plan on making a release of this plugin at some
   point soon. It's too buggy just yet though. When I do, it will be composed of
   multiple files including the markdown and html2text Python modules, the syntax
   files, an ftplugin directory, and a regular (small) blogger.vim plugin file.
&lt;/p&gt;
&lt;p&gt;Using Markdown syntax has both advantages and disadvantages. The biggest
   advantage is the fact that it is easier to read and write when compared to
   HTML code. Also, it is rapidly becoming a popular method of writing structured
   text. A disadvantage is that the syntax still has some weaknesses. For example
   as of now there is no way to specify the size of an embedded image and there's no
   way to make it float right or left in your text. This can be done with
   embedded HTML, but then it would get messed up during the conversion back to
   Markdown in the context of this Vim plugin. For now though, it's fun to play
   with :).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-5277705470487679969?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/5277705470487679969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/vim-bloggerbeta-now-featuring-markdown.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/5277705470487679969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/5277705470487679969'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/vim-bloggerbeta-now-featuring-markdown.html' title='Vim-Blogger Featuring Markdown'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-1921088325771346187</id><published>2006-10-21T12:56:00.001-05:00</published><updated>2006-10-21T12:58:40.389-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><title type='text'>Faster Buffer Switches in Vim</title><content type='html'>&lt;p&gt;
  I've tried several times in the past to use various buffer management
  plugins like the very popular
  &lt;a href='http://vim.sourceforge.net/scripts/script.php?script_id=159'&gt;minibufexplorer&lt;/a&gt;
  and
  &lt;a href='http://vim.sourceforge.net/scripts/script.php?script_id=42'&gt;bufexplorer&lt;/a&gt;
  only to find myself &lt;em&gt;not&lt;/em&gt; using them or forgetting to use them after a few
  days. It seems that the normal "switch by name or number" method is faster
  and more convenient for me for some unknown reason. I can see how these
  plugins could be useful if your current number of open buffers gets huge,
  but until then I think they just take up valuable screen real estate (I'm
  pretty stingy about my screen space).
  &lt;/p&gt;
  &lt;p&gt;
    Buffers inherit their names from their file names. You can switch buffers
    by entering &lt;code&gt;:b {name}&lt;/code&gt; or by &lt;code&gt;:b {N}&lt;/code&gt; where &lt;code&gt;{name}&lt;/code&gt; is either the
    full &lt;strong&gt;or partial&lt;/strong&gt; buffer name that you desire (filename), and &lt;code&gt;{N}&lt;/code&gt; is
    the buffer number. This by default has a number of issues.

&lt;ul&gt;
&lt;li&gt;  Buffer numbers are difficult to remember unless you are a robot. Especially if the number of buffers is large. &lt;/li&gt;
&lt;li&gt;  If you have two buffers named &lt;code&gt;file1&lt;/code&gt; and &lt;code&gt;file2&lt;/code&gt; and you attempt to switch buffers with a command like &lt;code&gt;:b file&lt;/code&gt; you will get an error message stating that there is more than one buffer matching that pattern. &lt;/li&gt;
&lt;li&gt;  If you have a buffer named &lt;code&gt;Foo&lt;/code&gt; and you attempt to switch to it with a command like &lt;code&gt;:b foo&lt;/code&gt; it will not work. Switching buffers by name is case sensitive. &lt;/li&gt;
&lt;/ul&gt;

  In order to overcome these problems, I decided to modify this behaviour a
  bit to make my preferred method of buffer switching a little more user
  friendly. Of course before I began writing a function for it, I did a quick
  search through the tips at the &lt;a href='http://www.vim.org'&gt;Vim website&lt;/a&gt; and found
  &lt;a href='http://vim.sourceforge.net/tips/tip.php?tip_id=183'&gt;this tip&lt;/a&gt; by Cory T.
  Echols. As suggested in a comment in this tip, this function prompts the user
  for a choice even if there is only one match to the given pattern. Also, it
  doesn't solve the case sensitivity problem mentioned above. I decided to
  work from this function and modify it to better suit my own tastes. First,
  instead of having a boolean switch for whether a pattern match was found or
  not, I used a List (Cory's function was written well before Lists were
  available in Vim. They are a Vim 7 feature.) and appended the number of
  matching buffers to this list. Once I've cycled through all of the listed
  buffers, if the length of this list is 1, I immediately make that buffer the
  active one. Only if there are more than one matching buffers do I prompt the
  user for a choice. I also chose to exclude unlisted buffers from my search.
  Unlisted buffers are ones that do not show up in the &lt;code&gt;:ls&lt;/code&gt; list because
  they have been closed with the &lt;code&gt;:bdelete&lt;/code&gt; command. I figure if I delete
  the buffer then I don't want to use it anymore. I only want to select a
  buffer from the listed ones.
  &lt;/p&gt;
  &lt;p&gt;
    Finally, I added a global variable called &lt;code&gt;g:BufSel_Case_Sensitive&lt;/code&gt; that
    controls whether the match is case sensitive or not. It defaults to false,
    but can be changed anywhere (like your &lt;code&gt;~/.vimrc&lt;/code&gt; for example). This
    makes it much easier to swap if your edited file names contain a mix of
    upper and lower case characters.
    &lt;/p&gt;
    &lt;p&gt;
    The final product looks like this:
&lt;pre&gt;
&lt;font color='#0000ff'&gt;function&lt;/font&gt;! BufSel&lt;font color='#0000ff'&gt;(&lt;/font&gt;pattern&lt;font color='#0000ff'&gt;)&lt;/font&gt;
    &lt;font color='#0000ff'&gt;let&lt;/font&gt; buflist &lt;font color='#0000ff'&gt;=&lt;/font&gt; []
    &lt;font color='#0000ff'&gt;let&lt;/font&gt; bufcount &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;bufnr&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"$"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
    &lt;font color='#0000ff'&gt;let&lt;/font&gt; currbufnr &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;

    &lt;font color='#0000ff'&gt;while&lt;/font&gt; currbufnr &lt;font color='#0000ff'&gt;&amp;lt;=&lt;/font&gt; bufcount
        &lt;font color='#0000ff'&gt;if&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;buflisted&lt;font color='#0000ff'&gt;(&lt;/font&gt;currbufnr&lt;font color='#0000ff'&gt;))&lt;/font&gt;
            &lt;font color='#0000ff'&gt;let&lt;/font&gt; currbufname &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;bufname&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;currbufnr&lt;font color='#0000ff'&gt;)&lt;/font&gt;
            &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;exists&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"g:BufSel_Case_Sensitive"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#0000ff'&gt;0&lt;/font&gt; &lt;font color='#0000ff'&gt;||&lt;/font&gt; g:BufSel_Case_Sensitive &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#0000ff'&gt;0&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
                &lt;font color='#0000ff'&gt;let&lt;/font&gt; curmatch &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;tolower&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;currbufname&lt;font color='#0000ff'&gt;)&lt;/font&gt;
                &lt;font color='#0000ff'&gt;let&lt;/font&gt; patmatch &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;tolower&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;a:pattern&lt;font color='#0000ff'&gt;)&lt;/font&gt;
            &lt;font color='#0000ff'&gt;else&lt;/font&gt;
                &lt;font color='#0000ff'&gt;let&lt;/font&gt; curmatch &lt;font color='#0000ff'&gt;=&lt;/font&gt; currbufname
                &lt;font color='#0000ff'&gt;let&lt;/font&gt; patmatch &lt;font color='#0000ff'&gt;=&lt;/font&gt; a:pattern
            &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
            &lt;font color='#0000ff'&gt;if&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;match&lt;font color='#0000ff'&gt;(&lt;/font&gt;curmatch, patmatch&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;&amp;gt;&lt;/font&gt; &lt;font color='#0000ff'&gt;-&lt;/font&gt;&lt;font color='#0000ff'&gt;1&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
                &lt;font color='#0000ff'&gt;call&lt;/font&gt; &lt;font color='#0000ff'&gt;add&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;buflist, currbufnr&lt;font color='#0000ff'&gt;)&lt;/font&gt;
            &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
        &lt;font color='#0000ff'&gt;let&lt;/font&gt; currbufnr &lt;font color='#0000ff'&gt;=&lt;/font&gt; currbufnr &lt;font color='#0000ff'&gt;+&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;
    &lt;font color='#0000ff'&gt;endwhile&lt;/font&gt;
    &lt;font color='#0000ff'&gt;if&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;len&lt;font color='#0000ff'&gt;(&lt;/font&gt;buflist&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;&amp;gt;&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
        &lt;font color='#0000ff'&gt;for&lt;/font&gt; bufnum &lt;font color='#0000ff'&gt;in&lt;/font&gt; buflist
            &lt;font color='#0000ff'&gt;echo&lt;/font&gt; bufnum . &lt;font color='#a31515'&gt;":      "&lt;/font&gt;. &lt;font color='#0000ff'&gt;bufname&lt;/font&gt;(bufnum)
        &lt;font color='#0000ff'&gt;endfor&lt;/font&gt;
        &lt;font color='#0000ff'&gt;let&lt;/font&gt; desiredbufnr &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;input&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"Enter buffer number: "&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
        &lt;font color='#0000ff'&gt;if&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;strlen&lt;font color='#0000ff'&gt;(&lt;/font&gt;desiredbufnr&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;!=&lt;/font&gt; &lt;font color='#0000ff'&gt;0&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
            &lt;font color='#0000ff'&gt;exe&lt;/font&gt; &lt;font color='#a31515'&gt;":bu "&lt;/font&gt;&lt;font color='#0000ff'&gt;.&lt;/font&gt; desiredbufnr
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
    &lt;font color='#0000ff'&gt;elseif&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;len&lt;font color='#0000ff'&gt;(&lt;/font&gt;buflist&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
        &lt;font color='#0000ff'&gt;exe&lt;/font&gt; &lt;font color='#a31515'&gt;":bu "&lt;/font&gt; &lt;font color='#0000ff'&gt;.&lt;/font&gt; get&lt;font color='#0000ff'&gt;(&lt;/font&gt;buflist,&lt;font color='#0000ff'&gt;0&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
    &lt;font color='#0000ff'&gt;else&lt;/font&gt;
        &lt;font color='#0000ff'&gt;echo&lt;/font&gt; &lt;font color='#a31515'&gt;"No matching buffers"&lt;/font&gt;
    &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
&lt;font color='#0000ff'&gt;endfunction&lt;/font&gt;
&lt;font color='#0000ff'&gt;command&lt;/font&gt;! &lt;font color='#0000ff'&gt;-&lt;/font&gt;&lt;font color='#a31515'&gt;nargs&lt;/font&gt;&lt;font color='#0000ff'&gt;=&lt;/font&gt;&lt;font color='#0000ff'&gt;1&lt;/font&gt; &lt;font color='#0000ff'&gt;-&lt;/font&gt;&lt;font color='#a31515'&gt;complete&lt;/font&gt;&lt;font color='#0000ff'&gt;=&lt;/font&gt;&lt;font color='#0000ff'&gt;buffer&lt;/font&gt; Bs :&lt;font color='#0000ff'&gt;call&lt;/font&gt; BufSel(&lt;font color='#a31515'&gt;"&amp;lt;args&amp;gt;"&lt;/font&gt;)
&lt;/pre&gt;
    It's not a real complicated function, but it does add a lot of flexibility
    when switching buffers via the command line. I added the following line in
    my &lt;code&gt;~/.vimrc&lt;/code&gt; to replace the already existing command when typed:
&lt;pre&gt;
    cabbr b Bs
&lt;/pre&gt;
    So now when I type &lt;code&gt;:b &lt;/code&gt; (notice the space) it is replaced by &lt;code&gt;:Bs &lt;/code&gt;
    automatically and the function is run instead of the built-in &lt;code&gt;buffer&lt;/code&gt;
    command. This suggestion was also taken from the comments in the tip page
    above, and it works quite well.
    &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-1921088325771346187?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/1921088325771346187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/faster-buffer-switches-in-vim_21.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1921088325771346187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1921088325771346187'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/faster-buffer-switches-in-vim_21.html' title='Faster Buffer Switches in Vim'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-9213647112125806765</id><published>2006-10-20T10:24:00.002-05:00</published><updated>2008-04-04T22:42:44.486-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><title type='text'>Making ZZ Behave in Vim</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Update Apr 4, 2008: &lt;/span&gt; I was recently reminded of this post and thought I should mention that this particular solutions sucks. Although it won't break anything, it doesn't work well. Don't waste your time :) Cheers.

&lt;p&gt;
I've gotten quite used to the idea of hitting &lt;code&gt;ZZ&lt;/code&gt; in Vim to kill the
window I'm currently working in. The problem is that I'm &lt;i&gt;so&lt;/i&gt; used to the
idea, that I hit it almost automatically when I'm done with a particular
buffer and there is only one window left. The result is that the Vim session
is closed completely whether there is only one listed buffer or not.
&lt;/p&gt;
&lt;p&gt;
    My solution to this was not to find the probably existing command or
    setting built into Vim that corrects this problem, but rather to write a
    function that customizes the behavior of the &lt;code&gt;ZZ&lt;/code&gt; command. This would be the
    first time I'd ever written a non-trivial function in pure Vim script, so
    I thought I'd give it a shot. The following function is the result. I've put
    lots of comments in there so that you can follow if you are new to Vim
    scripting like I am.
    &lt;/p&gt;
&lt;pre&gt;
&lt;font color='#0000ff'&gt;function&lt;/font&gt;! BehaveZZ&lt;font color='#0000ff'&gt;()&lt;/font&gt;
&lt;font color='#008000'&gt;    " Get the number of *listed* buffers.&lt;/font&gt;
    &lt;font color='#0000ff'&gt;let&lt;/font&gt; highbuf &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;bufnr&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"$"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
    &lt;font color='#0000ff'&gt;let&lt;/font&gt; buflist &lt;font color='#0000ff'&gt;=&lt;/font&gt; []
    &lt;font color='#0000ff'&gt;let&lt;/font&gt; i &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;
    &lt;font color='#0000ff'&gt;while&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;i &lt;font color='#0000ff'&gt;&amp;lt;=&lt;/font&gt; highbuf&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;        "Skip unlisted buffers.&lt;/font&gt;
        &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;bufexists&lt;font color='#0000ff'&gt;(&lt;/font&gt;i&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;!=&lt;/font&gt; &lt;font color='#0000ff'&gt;0&lt;/font&gt; &lt;font color='#0000ff'&gt;&amp;amp;&amp;amp;&lt;/font&gt; buflisted&lt;font color='#0000ff'&gt;(&lt;/font&gt;i&lt;font color='#0000ff'&gt;))&lt;/font&gt;
            &lt;font color='#0000ff'&gt;call&lt;/font&gt; &lt;font color='#0000ff'&gt;add&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;buflist, i&lt;font color='#0000ff'&gt;)&lt;/font&gt;
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
        &lt;font color='#0000ff'&gt;let&lt;/font&gt; i &lt;font color='#0000ff'&gt;=&lt;/font&gt; i &lt;font color='#0000ff'&gt;+&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;
    &lt;font color='#0000ff'&gt;endwhile&lt;/font&gt;
    &lt;font color='#0000ff'&gt;let&lt;/font&gt; bufcount &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;len&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;buflist&lt;font color='#0000ff'&gt;)&lt;/font&gt;
    &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;bufcount &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
        &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;bufname&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"%"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#a31515'&gt;""&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;            " This buffer is unnamed (has no associated file).&lt;/font&gt;
            &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;&amp;amp;modified&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;                " Give option to save modifications.&lt;/font&gt;
                &lt;font color='#0000ff'&gt;let&lt;/font&gt; choice &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;input&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"Lose modifications? [Enter=yes]: "&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
                &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;choice &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#a31515'&gt;""&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
                    &lt;font color='#0000ff'&gt;set&lt;/font&gt; &lt;font color='#a31515'&gt;nomodified&lt;/font&gt;
                &lt;font color='#0000ff'&gt;else&lt;/font&gt;
                    &lt;font color='#0000ff'&gt;echo&lt;/font&gt; &lt;font color='#a31515'&gt;"ZZ action aborted..."&lt;/font&gt;
                    &lt;font color='#0000ff'&gt;return&lt;/font&gt;
                &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
            &lt;font color='#0000ff'&gt;else&lt;/font&gt;
&lt;font color='#008000'&gt;                " The buffer has no modifications. Just do default ZZ.&lt;/font&gt;
                &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"x"&lt;/font&gt;
            &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
        &lt;font color='#0000ff'&gt;else&lt;/font&gt;
&lt;font color='#008000'&gt;            " There is only one listed buffer and it is named. In this case, &lt;/font&gt;
&lt;font color='#008000'&gt;            " the standard ZZ works just fine, so do that.&lt;/font&gt;
            &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"x"&lt;/font&gt;
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
    &lt;font color='#0000ff'&gt;elseif&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;getbufvar&lt;font color='#0000ff'&gt;(&lt;/font&gt;bufnr&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"%"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;, &lt;font color='#a31515'&gt;"&amp;amp;buftype"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;!=&lt;/font&gt; &lt;font color='#a31515'&gt;""&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;        " This buffer is a &lt;/font&gt;&lt;font color='#a31515'&gt;"special"&lt;/font&gt;&lt;font color='#008000'&gt; buffer.&lt;/font&gt;
        &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"bdelete"&lt;/font&gt;
    &lt;font color='#0000ff'&gt;elseif&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;bufname&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"%"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#a31515'&gt;""&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;        " This buffer is unnamed (has no associated file).&lt;/font&gt;
        &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;&amp;amp;modified&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;            " Give option to save modifications.&lt;/font&gt;
            &lt;font color='#0000ff'&gt;let&lt;/font&gt; choice &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;input&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"Lose modifications? [Enter=yes]: "&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
            &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;choice &lt;font color='#0000ff'&gt;==&lt;/font&gt; &lt;font color='#a31515'&gt;""&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
                &lt;font color='#0000ff'&gt;set&lt;/font&gt; &lt;font color='#a31515'&gt;nomodified&lt;/font&gt;
            &lt;font color='#0000ff'&gt;else&lt;/font&gt;
                &lt;font color='#0000ff'&gt;echo&lt;/font&gt; &lt;font color='#a31515'&gt;"ZZ action aborted..."&lt;/font&gt;
                &lt;font color='#0000ff'&gt;return&lt;/font&gt;
            &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
        &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;winnr&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"$"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;&amp;gt;&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;            " There are multiple windows open. Just do a normal ZZ.&lt;/font&gt;
            &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"x"&lt;/font&gt;
        &lt;font color='#0000ff'&gt;else&lt;/font&gt;
            &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"buffer! "&lt;/font&gt; &lt;font color='#0000ff'&gt;.&lt;/font&gt; bufnr&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"#"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
    &lt;font color='#0000ff'&gt;else&lt;/font&gt;
&lt;font color='#008000'&gt;        " This is a named buffer. &lt;/font&gt;
        &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;&amp;amp;modified&lt;font color='#0000ff'&gt;)&lt;/font&gt;
            &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"write"&lt;/font&gt;
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
        &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;winnr&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"$"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;&amp;gt;&lt;/font&gt; &lt;font color='#0000ff'&gt;1&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;            " There are multiple windows. Just do normal ZZ.&lt;/font&gt;
            &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"x"&lt;/font&gt;
        &lt;font color='#0000ff'&gt;else&lt;/font&gt;
&lt;font color='#008000'&gt;            " There is only one window, but multiple listed buffers.&lt;/font&gt;
            &lt;font color='#0000ff'&gt;let&lt;/font&gt; curbuf &lt;font color='#0000ff'&gt;=&lt;/font&gt; &lt;font color='#0000ff'&gt;bufnr&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"%"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;            " If we have a 'last visited' buffer, go there. Else bnext.&lt;/font&gt;
            &lt;font color='#0000ff'&gt;if&lt;/font&gt; &lt;font color='#0000ff'&gt;(&lt;/font&gt;bufnr&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"#"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt; &lt;font color='#0000ff'&gt;!=&lt;/font&gt; &lt;font color='#0000ff'&gt;-&lt;/font&gt;&lt;font color='#0000ff'&gt;1&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
                &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"buffer! "&lt;/font&gt; &lt;font color='#0000ff'&gt;.&lt;/font&gt; bufnr&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"#"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
            &lt;font color='#0000ff'&gt;else&lt;/font&gt;
                &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"bnext"&lt;/font&gt;
            &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
            &lt;font color='#0000ff'&gt;execute&lt;/font&gt; &lt;font color='#a31515'&gt;"bdelete"&lt;/font&gt; &lt;font color='#0000ff'&gt;.&lt;/font&gt; curbuf
        &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
    &lt;font color='#0000ff'&gt;endif&lt;/font&gt;
&lt;font color='#0000ff'&gt;endfunction&lt;/font&gt;
&lt;font color='#0000ff'&gt;command&lt;/font&gt;! ZZ &lt;font color='#0000ff'&gt;call&lt;/font&gt; BehaveZZ()
&lt;/pre&gt;
    &lt;p&gt;
        Now at the time of this writing, the above function has had very
        limited testing, so if you want to use it, beware. This is what the
        function does.
        &lt;ul&gt;
            &lt;li&gt;If there are multiple windows open, just close the current
            one. (Same as default &lt;code&gt;ZZ&lt;/code&gt;)&lt;/li&gt;
            &lt;li&gt;If there is only one window open, but multiple buffers, delete
            the current buffer and switch to another one.&lt;/li&gt;
            &lt;li&gt;If there is only one window, and only one listed buffer, exit
            the session. (Same sd default &lt;code&gt;ZZ&lt;/code&gt;)&lt;/li&gt;
            &lt;li&gt;If the current buffer is unnamed (ie. has no filename
            associated with it), confirm loss of modifications. If user presses
            just &lt;code&gt;Enter&lt;/code&gt;, then discard modifications and delete the
            buffer. Else abort.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;/p&gt;
        &lt;p&gt;
           One behaviour of the default Vim that I found odd is a result of
           opening multiple files from the command line at once like &lt;code&gt;vim
               file1 file2&lt;/code&gt;. When you do this, and try to close one you
           get a &lt;code&gt;E173: 1 more file to edit&lt;/code&gt; message, and nothing
           happens at all.  It however gives no such warnings if you open only
           one file, then open a second with the &lt;code&gt;:e file2&lt;/code&gt; command
           from inside the editor. This time it just closes the whole session if
           there is only one window open. In both of these cases, my function
           will close the currently active buffer and switch to one of the other
           buffers in the buffer list.
        &lt;/p&gt;
        &lt;p&gt;I think I've handled most special cases where a buffer is
        &lt;i&gt;special&lt;/i&gt; like a help buffer, or a scratch buffer too. Initially I
        made it so that if the current buffer was unnamed and modified then the
        modifications would just be discarded, but that made me nervous so I
        added a one key confirmation just to be safe. The whole function turned
        out to be a lot more complex than I thought it would (not to mention
        longer). Things like special buffers gave me a lot of grief. Being new
        to this, the whole snippet probably ended up being more complicated than
        it needed to be. If you see any bugs or optimizations, I'd be interested
        in hearing about them. Leave a comment after this post.&lt;/p&gt;
        &lt;p&gt;
        To use this function, drop it into your &lt;code&gt;~/.vimrc&lt;/code&gt; and either
        &lt;code&gt;:call&lt;/code&gt; it manually or map a key to it like 
        &lt;pre&gt;:map ZZ :call BehaveZZ()&amp;lt;CR&amp;gt;&lt;/pre&gt;.
        That's the mapping I use and it simply replaces &lt;code&gt;ZZ&lt;/code&gt;'s normal
        behavior with the new one.
        &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-9213647112125806765?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/9213647112125806765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/making-zz-behave-in-vim.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9213647112125806765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9213647112125806765'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/making-zz-behave-in-vim.html' title='Making ZZ Behave in Vim'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-1781543016751406864</id><published>2006-10-14T13:23:00.001-05:00</published><updated>2006-10-14T13:29:46.975-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>See the Vim-BloggerBeta Plugin in Action</title><content type='html'>&lt;p&gt;
&lt;a href='http://arker.homelinux.org/files/vim-blogger/vim-blogger.png'&gt;&lt;img style='float:right; padding-left:10px; padding-bottom:10px;' src='http://arker.homelinux.org/files/vim-blogger/vim-blogger_thumb.png'&gt;&lt;/img&gt;&lt;/a&gt;
I made a funky &lt;a href='http://arker.homelinux.org/files/vim-blogger/vim-blogger.html'&gt;flash
      screencast&lt;/a&gt; of my vim-blogger plugin in action for all to
see :). The screencast demonstrates saving a draft post, retrieving a list of
all posts on the blog, editing a saved post, publishing a post, adding labels
to a post, and finally deleting a post. The swf file ended up being quite
large, but hopefully managable, and since Blogger doesn't allow hosting such
files (yet?), I have to host it on my slow home server for now. Let me know if
it is unbearably slow.
&lt;/p&gt;
&lt;p&gt;
  I do plan on releasing the plugin some day soon so all Vim/Blogger-beta
  users can make use of it, but first it needs some serious testing. The last
  thing I want to happen is for me to make it available too early, then have
  somebody pooch their data because of it. That and the thing is a bloody
  mess. I wrote it while discovering how to use the &lt;a href='http://code.google.com/apis/gdata/blogger.html'&gt;Blogger GData
    API&lt;/a&gt;, and the code shows it. Once it's in a safe state that I don't
  mind putting my name on, I'll make it public ;p.
  &lt;/p&gt;
  &lt;p&gt;Until then, enjoy the &lt;a href='http://arker.homelinux.org/files/vim-blogger/vim-blogger.html'&gt;screencast&lt;/a&gt;, and leave comments or suggestions if
  you have any!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-1781543016751406864?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/1781543016751406864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/see-vim-bloggerbeta-plugin-in-action.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1781543016751406864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1781543016751406864'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/see-vim-bloggerbeta-plugin-in-action.html' title='See the Vim-BloggerBeta Plugin in Action'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-97402622213912688</id><published>2006-10-13T15:37:00.001-05:00</published><updated>2006-10-13T16:06:47.284-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Success! Posting to Blogger-beta Using Vim</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
        &lt;p&gt;
If you see this, then I've &lt;i&gt;finally&lt;/i&gt; (at least partially) figured out how
to use the Blogger-beta GData API from Python. And to make posting a little
bit quicker/easier for me, I've stuck that Python code into a Vim plugin.
&lt;/p&gt;
&lt;p&gt;
  To be honest, I'm not entirely sure what I was doing wrong in my previous
  attempts. I've changed several things, then changed some back. The resulting
  code really doesn't look much different to me than it did before, but there
  are a few very subtle changes. I suspect my ignorance when it comes to HTTP
  and XML protocols played a large part in my frustrations.
  &lt;/p&gt;
  &lt;p&gt;
    Anyways, here is a working version of the Python code that works for
    posting a blog entry. You will obviously need to fill in your
    &lt;tt&gt;BLOGID&lt;/tt&gt;, &lt;tt&gt;GMAIL_ADDRESS&lt;/tt&gt;, and &lt;tt&gt;GMAIL_PASSWORD&lt;/tt&gt;
    appropriately for it to work for you:

&lt;pre&gt;
&lt;font color='#0000ff'&gt;#!/usr/bin/env python&lt;/font&gt;

&lt;font color='#0000ff'&gt;import&lt;/font&gt; httplib2, re

account = &lt;font color='#a31515'&gt;"GMAIL_ADDRESS"&lt;/font&gt;
password = &lt;font color='#a31515'&gt;"GMAIL_PASSWORD"&lt;/font&gt;
blogid = &lt;font color='#a31515'&gt;"BLOGID"&lt;/font&gt;

&lt;font color='#0000ff'&gt;def&lt;/font&gt; &lt;font color='#0000ff'&gt;authenticate&lt;/font&gt;(h):
    auth_uri = &lt;font color='#a31515'&gt;'https://www.google.com/accounts/ClientLogin'&lt;/font&gt;
    headers = {&lt;font color='#a31515'&gt;'Content-Type'&lt;/font&gt;: &lt;font color='#a31515'&gt;'application/x-www-form-urlencoded'&lt;/font&gt;}
    myrequest = &lt;font color='#a31515'&gt;"Email=%s&amp;amp;Passwd=%s&amp;amp;service=blogger&amp;amp;service=TestCompany-TestApp-0.0"&lt;/font&gt; % (account, password)
    response, content = h.request(auth_uri, &lt;font color='#a31515'&gt;'POST'&lt;/font&gt;, body=myrequest, headers=headers)
    &lt;font color='#0000ff'&gt;if&lt;/font&gt; response[&lt;font color='#a31515'&gt;'status'&lt;/font&gt;] == &lt;font color='#a31515'&gt;'200'&lt;/font&gt;:
        &lt;font color='#0000ff'&gt;return&lt;/font&gt; re.search(&lt;font color='#a31515'&gt;'Auth=(\S*)'&lt;/font&gt;, content).group(&lt;font color='#0000ff'&gt;1&lt;/font&gt;)
    &lt;font color='#0000ff'&gt;else&lt;/font&gt;:
        &lt;font color='#0000ff'&gt;return&lt;/font&gt; None

entry = &lt;font color='#a31515'&gt;"""&amp;lt;?xml version="1.0" ?&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;    &amp;lt;entry xmlns='http://www.w3.org/2005/Atom'&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;      &amp;lt;title type='text'&amp;gt;Test Post&amp;lt;/title&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;      &amp;lt;content type='xhtml'&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;        &amp;lt;div xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;        If you are reading this, then it worked!&lt;/font&gt;
&lt;font color='#a31515'&gt;        &amp;lt;/div&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;      &amp;lt;/content&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;      &amp;lt;author&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;        &amp;lt;name&amp;gt;TestUser&amp;lt;/name&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;      &amp;lt;/author&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;    &amp;lt;/entry&amp;gt;&lt;/font&gt;
&lt;font color='#a31515'&gt;    """&lt;/font&gt;

h = httplib2.Http()
uri = &lt;font color='#a31515'&gt;'http://www.blogger.com/feeds/%s/posts/full'&lt;/font&gt; % blogid

&lt;font color='#008000'&gt;# Get the Auth token from ClientLogin&lt;/font&gt;
auth = authenticate(h)
&lt;font color='#0000ff'&gt;if&lt;/font&gt; auth:
    headers = {&lt;font color='#a31515'&gt;'Content-Type'&lt;/font&gt;: &lt;font color='#a31515'&gt;'application/atom+xml'&lt;/font&gt;, &lt;font color='#a31515'&gt;'Authorization'&lt;/font&gt;: &lt;font color='#a31515'&gt;'GoogleLogin auth=%s'&lt;/font&gt; % auth.strip()}
    response, content = h.request(uri, &lt;font color='#a31515'&gt;'POST'&lt;/font&gt;, body=entry, headers=headers)

    &lt;font color='#008000'&gt;# blindly follow redirects&lt;/font&gt;
    &lt;font color='#0000ff'&gt;while&lt;/font&gt; response[&lt;font color='#a31515'&gt;'status'&lt;/font&gt;] == &lt;font color='#a31515'&gt;'302'&lt;/font&gt;:
        response, content = h.request(response[&lt;font color='#a31515'&gt;'location'&lt;/font&gt;], &lt;font color='#a31515'&gt;'POST'&lt;/font&gt;, body=entry, headers=headers)

    &lt;font color='#0000ff'&gt;if&lt;/font&gt; response[&lt;font color='#a31515'&gt;'status'&lt;/font&gt;] == &lt;font color='#a31515'&gt;'201'&lt;/font&gt;:
        &lt;font color='#0000ff'&gt;print&lt;/font&gt; &lt;font color='#a31515'&gt;"Entry successfully posted."&lt;/font&gt;
    &lt;font color='#0000ff'&gt;else&lt;/font&gt;:
        &lt;font color='#0000ff'&gt;print&lt;/font&gt; &lt;font color='#a31515'&gt;"Post failed: %s"&lt;/font&gt; % response[&lt;font color='#a31515'&gt;'status'&lt;/font&gt;]
&lt;font color='#0000ff'&gt;else&lt;/font&gt;:
    &lt;font color='#0000ff'&gt;print&lt;/font&gt; &lt;font color='#a31515'&gt;"Authorization failed."&lt;/font&gt;
&lt;/pre&gt;
    &lt;/p&gt;
    &lt;p&gt;
     It's pretty rough, I realize, but I think it's good enough to get anyone
     started if you are interested. I hope someone will find this useful.
     &lt;/p&gt;
     &lt;p&gt;Now to see what other functionality I can perform :).&lt;/p&gt;
&lt;p&gt;Oh, I almost forgot. If you want the Vim plugin I'm using you can get it &lt;a href="http://arker.homelinux.org/files/blogger.vim"&gt;here&lt;/a&gt;. To install it, drop it in &lt;tt&gt;~/.vimrc/plugins/&lt;/tt&gt;. To use it, open vim, type your post's subject on the first line, the post body below that, and type &lt;tt&gt;:BlogPost&lt;/tt&gt; when you are done.&lt;/p&gt;
        &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-97402622213912688?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/97402622213912688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/success-posting-to-blogger-beta-using.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/97402622213912688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/97402622213912688'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/success-posting-to-blogger-beta-using.html' title='Success! Posting to Blogger-beta Using Vim'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-7918170132742719600</id><published>2006-10-11T16:34:00.000-05:00</published><updated>2006-10-21T11:28:30.478-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Blogger Template Customization</title><content type='html'>&lt;p&gt;Today I decided to customize my Blogger template a little bit to make it differ from the typical cookie cutter blogs on here. I'm not an expert on CSS and HTML by any means, but I think I'm pleased with the results so far. Aside from the shot of my ugly mug I stuck up there at the top of the page, I think it's fairly easy on the eyes. Of course, I've only viewed it with Firefox, so if you see any errors or problems with the page layout at all, please let me know.&lt;/p&gt;

&lt;p&gt;By the looks of it, one pretty much has complete control over the look and
feel of their &lt;a href='http://beta.blogger.com'&gt;Blogger-beta&lt;/a&gt; website. I could touch and edit pretty much every aspect of the page from what I could see. Like I said, however, I'm no expert so I didn't want to delve too deeply into things for fear of messing them up beyond repair.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-7918170132742719600?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/7918170132742719600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/blogger-template-customization.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/7918170132742719600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/7918170132742719600'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/blogger-template-customization.html' title='Blogger Template Customization'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-3358180982275778807</id><published>2006-10-11T11:00:00.000-05:00</published><updated>2007-10-29T22:19:47.181-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>A Step Closer to Google Authentication?</title><content type='html'>&lt;p&gt;
  Thanks to a &lt;a href="https://beta.blogger.com/comment.g?blogID=7044907287770355906&amp;postID=9050229134500237604"&gt;comment&lt;/a&gt;
  left by Frank Mantek regarding the &lt;a href="http://djcraven5.blogspot.com/2006/10/using-google-gdata-api-with-python.html"&gt;issue&lt;/a&gt; I was having with my Blogger-beta
  authentication, I've been able to get a step closer (I think?) to success.
  Frank was correct in his assumption that I was getting a 302 redirect
  response from the ClientLogin URL, and that my custom headers weren't being
  resent to the new URL. The response I got was a dictionary which contained
  of course the status code of &lt;tt&gt;302&lt;/tt&gt;, and also a &lt;tt&gt;location&lt;/tt&gt; key
  with a value of &lt;tt&gt;http://beta.blogger.com/feeds/BLOGID/posts/full&lt;/tt&gt;.
  Being quite new to all of this HTTP stuff, I can only assume that location
  is where the redirect was pointing to. I then implemented a test on the
  return status code, if it is &lt;tt&gt;302&lt;/tt&gt;, I manually resent the post and
  custom headers to the new location, and got a new error!
&lt;/p&gt;
&lt;p&gt;
The new error is a &lt;tt&gt;400 Bad Request&lt;/tt&gt; error, and the content says
&lt;tt&gt;GoogleLogin auth token is malformed&lt;/tt&gt;. A search online for that error
string revealed &lt;a
  href="http://groups-beta.google.com/group/Google-Accounts-API/browse_frm/thread/05f5f4b5e395829a"&gt;a
guy with the same problem&lt;/a&gt;, but no responses. Since that thread was too old
to reply to and revive, I had to start a &lt;a
  href="http://groups-beta.google.com/group/Google-Accounts-API/browse_frm/thread/02f0b20eb55dce52"&gt;new
and similar thread&lt;/a&gt;. Hopefully it'll get some action.
&lt;/p&gt;
&lt;p&gt;
  I won't post all of the new code as most of it remains unchanged. I simply
  modified the &lt;tt&gt;getPost()&lt;/tt&gt; function to take the URL to make the request
  to. The new stuff looks like this, with the test for redirect included:

&lt;pre&gt;
h = httplib2.Http()
uri = &lt;font color="#a31515"&gt;'http://www.blogger.com/feeds/BLOGID/posts/full'&lt;/font&gt;

cert = authenticate()
&lt;font color="#0000ff"&gt;if&lt;/font&gt; cert:
    response, content = postEntry(cert, uri)
    &lt;font color="#0000ff"&gt;while&lt;/font&gt; response[&lt;font color="#a31515"&gt;'status'&lt;/font&gt;] == &lt;font color="#a31515"&gt;'302'&lt;/font&gt;:
        cert = authenticate()
        response, content = postEntry(cert, response[&lt;font color="#a31515"&gt;'location'&lt;/font&gt;])
    &lt;font color="#0000ff"&gt;print&lt;/font&gt; response, content
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
  Hopefully this is in fact a step closer. I'd love to get this working.
  Thanks for the comment and the help, Frank! :)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-3358180982275778807?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/3358180982275778807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/step-closer-to-google-authentication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3358180982275778807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/3358180982275778807'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/step-closer-to-google-authentication.html' title='A Step Closer to Google Authentication?'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-4260018674547958196</id><published>2006-10-10T05:42:00.000-05:00</published><updated>2006-10-13T22:29:38.215-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Send a Gmail Message from Vim</title><content type='html'>&lt;p&gt;
  Using Gmail on my laptop through the web interface can be quite time
  consuming. I use the Linux version of Firefox, and it's not exactly known
  around the world for its great speed. Anyways, sometimes I just want to
  shoot off a quick email, and it would take just as long to load the Gmail
  compose form as it would to type the email content. For these times I wrote
  a little vim-python script as follows:
&lt;pre&gt;
&lt;font color='#008000'&gt;" Make sure the Vim was compiled with +python before loading the script...&lt;/font&gt;
&lt;font color='#0000ff'&gt;if&lt;/font&gt; !&lt;font color='#0000ff'&gt;has&lt;/font&gt;&lt;font color='#0000ff'&gt;(&lt;/font&gt;&lt;font color='#a31515'&gt;"python"&lt;/font&gt;&lt;font color='#0000ff'&gt;)&lt;/font&gt;
        &lt;font color='#0000ff'&gt;finish&lt;/font&gt;
&lt;font color='#0000ff'&gt;endif&lt;/font&gt;

:&lt;font color='#0000ff'&gt;command&lt;/font&gt;! &lt;font color='#0000ff'&gt;-&lt;/font&gt;&lt;font color='#a31515'&gt;nargs&lt;/font&gt;&lt;font color='#0000ff'&gt;=?&lt;/font&gt; GMSend :&lt;font color='#0000ff'&gt;call&lt;/font&gt; GMailSend(&lt;font color='#a31515'&gt;"&amp;lt;args&amp;gt;"&lt;/font&gt;)

&lt;font color='#0000ff'&gt;function&lt;/font&gt;! GMailSend&lt;font color='#0000ff'&gt;(&lt;/font&gt;args&lt;font color='#0000ff'&gt;)&lt;/font&gt;
&lt;font color='#008000'&gt;python &amp;lt;&amp;lt; EOF&lt;/font&gt;
&lt;font color='#0000ff'&gt;import&lt;/font&gt; vim
to = vim.eval('&lt;font color='#a31515'&gt;a:args&lt;/font&gt;')
GSend(to)
&lt;font color='#008000'&gt;EOF&lt;/font&gt;
&lt;font color='#0000ff'&gt;endfunction&lt;/font&gt;

&lt;font color='#008000'&gt;python &amp;lt;&amp;lt; EOF&lt;/font&gt;
&lt;font color='#008000'&gt;########### BEGIN USER CONFIG ##########&lt;/font&gt;
account = '&lt;font color='#a31515'&gt;MY_GMAIL_ACCOUNT&lt;/font&gt;'
password = '&lt;font color='#a31515'&gt;MY_GMAIL_PASSWORD&lt;/font&gt;'
&lt;font color='#008000'&gt;########### END USER CONFIG ###########&lt;/font&gt;


&lt;font color='#0000ff'&gt;def&lt;/font&gt; &lt;font color='#0000ff'&gt;GSend&lt;/font&gt;(to):
    """
&lt;font color='#a31515'&gt;    Send the current buffer as a Gmail message to a given user.&lt;/font&gt;
&lt;font color='#a31515'&gt;    &lt;/font&gt;"""
    &lt;font color='#0000ff'&gt;import&lt;/font&gt; libgmail

    subject = vim.current.buffer[0]
    body = '&lt;font color='#0000ff'&gt;\n&lt;/font&gt;'.join(vim.current.buffer[2:])

    ga = libgmail.GmailAccount(account, password)
    &lt;font color='#0000ff'&gt;try&lt;/font&gt;:
        ga.login()
    &lt;font color='#0000ff'&gt;except&lt;/font&gt; libgmail.GmailLoginFailure:
        &lt;font color='#0000ff'&gt;print&lt;/font&gt; "&lt;font color='#a31515'&gt;Login failed. (Wrong username/password?)&lt;/font&gt;"

    gmsg = libgmail.GmailComposedMessage(to, subject, body)

    &lt;font color='#0000ff'&gt;if&lt;/font&gt; ga.sendMessage(gmsg):
        &lt;font color='#0000ff'&gt;print&lt;/font&gt; "&lt;font color='#a31515'&gt;Message sent `%s` successfully.&lt;/font&gt;" % subject
    &lt;font color='#0000ff'&gt;else&lt;/font&gt;:
        &lt;font color='#0000ff'&gt;print&lt;/font&gt; "&lt;font color='#a31515'&gt;Could not send message.&lt;/font&gt;"

&lt;font color='#008000'&gt;EOF&lt;/font&gt;
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
 It's a really simple script, and it uses Python so it will only work if your
 Vim was compiled with the &lt;tt&gt;+python&lt;/tt&gt; option. Of course, you'll also
 need to edit the script to put in your own Gmail user name and password
 (lines 18 and 19).
&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;
Drop the above script (or download it from &lt;a href='http://arker.homelinux.org/files/gmail.vim'&gt;here&lt;/a&gt;) into your &lt;tt&gt;~/.vim/plugin/&lt;/tt&gt; directory. Reload Vim or source the file with &lt;tt&gt;:so ~/.vim/gmail.vim&lt;/tt&gt;.
&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;
  It's even easier to use. The first line in the buffer is the email's
  subject, and the rest is the body. Once the email is composed in this
  fashion, type &lt;tt&gt;:GMSend &amp;lt;dest&amp;gt;&lt;/tt&gt; where &amp;lt;dest&amp;gt; is the email
  address that you want to send this message to. If all is well, you'll see a
  message at the bottom of your Vim window indicating that all is well, and
  that the message was sent successfully.
&lt;/p&gt;
&lt;p&gt;
  Hopefully somebody out there will find this useful. The version I am
  actually using is a little more complex. I've extended the script to
  download messages by folder or label and stick the id, subject, and author
  in an active buffer. From there I can select one of the shown messages and
  the script will display the body in the same buffer. I've kept the rest to
  myself as I'm not real thrilled with the UI part, and I'm not sure it will
  work as expected for everyone. If you are interested, leave a comment. I'm
  pretty confident that the script posted above (the one that just sends mail)
  will work as expected. Enjoy!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-4260018674547958196?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/4260018674547958196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/send-gmail-message-from-vim.html#comment-form' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4260018674547958196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/4260018674547958196'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/send-gmail-message-from-vim.html' title='Send a Gmail Message from Vim'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-9050229134500237604</id><published>2006-10-08T15:41:00.000-05:00</published><updated>2006-11-13T22:42:03.410-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Using the Google GData API with Python</title><content type='html'>&lt;p&gt;
  I did a very quick search online for examples that I could use to see how to
  interact with &lt;a
    href="http://code.google.com/apis/gdata/blogger.html"&gt;Google's GData API&lt;/a&gt;
  for creating and posting Blogger-beta blog entries. The best I could find
  was &lt;a href="http://weblog.infoworld.com/udell/2006/06/13.html"&gt;this
    post&lt;/a&gt; to Jon Udell's &lt;a href="http://www.infoworld.com/"&gt;Infoworld&lt;/a&gt;
  weblog which illustrates making an entry to &lt;a
    href="http://www.google.com/calendar"&gt;Google Calendar&lt;/a&gt;. Now even though
  it is a different web application, most of this example code is still
  relevent as apparently they use the same API.
&lt;/p&gt;
&lt;p&gt;
From this, I tried the following code:

&lt;pre&gt;
&lt;font color="#0000ff"&gt;#!/usr/bin/env python&lt;/font&gt;

&lt;font color="#0000ff"&gt;import&lt;/font&gt; httplib2

h = httplib2.Http()
h.add_credentials(&lt;font color="#a31515"&gt;'MY_GMAIL_ACCOUNT'&lt;/font&gt;, &lt;font
color="#a31515"&gt;'MY_GMAIL_PASSWORD'&lt;/font&gt;)
h.follow_all_redirects = True
uri = &lt;font color="#a31515"&gt;'http://www.blogger.com/feeds/BLOGID/posts/full'&lt;/font&gt;

post_xml = &lt;font color="#a31515"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/font&gt;
&lt;font color="#a31515"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;&amp;lt;entry xmlns='http://www.w3.org/2005/Atom'&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;  &amp;lt;title type='text'&amp;gt;Test Post from Python&amp;lt;/title&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;  &amp;lt;content type='xhtml'&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;    &amp;lt;div xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;      &amp;lt;p&amp;gt;If you can see this, then it worked!&amp;lt;/p&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;    &amp;lt;/div&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;  &amp;lt;/content&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;  &amp;lt;author&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;    &amp;lt;name&amp;gt;Dennis&amp;lt;/name&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;  &amp;lt;/author&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;&amp;lt;/entry&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/font&gt;

headers = {&lt;font color="#a31515"&gt;'Content-Type'&lt;/font&gt;: &lt;font color="#a31515"&gt;'application/atom+xml'&lt;/font&gt;}
response, content = h.request(uri, &lt;font color="#a31515"&gt;'POST'&lt;/font&gt;, body=post_xml, headers=headers)
&lt;font color="#0000ff"&gt;print&lt;/font&gt; response, content
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
With this code, the last print line revealed a &lt;tt&gt;Error 401&lt;/tt&gt; of
&lt;tt&gt;Missing auth parameter in GoogleLogin&lt;/tt&gt;. I assumed that there was a
problem with the method of authentication in the httplib2 library. Possibly it
was out of date as apparently this API is a bit of a moving target still these
days. As a result, I had a look at the &lt;a
  href="http://code.google.com/apis/accounts/AuthForInstalledApps.html"&gt;Google
Account Authentication&lt;/a&gt; docs to see if I would have better luck doing the
authentication manually. After a bit of fiddling, I ended up with this:
&lt;pre&gt;
&lt;font color="#0000ff"&gt;#!/usr/bin/env python&lt;/font&gt;

&lt;font color="#0000ff"&gt;import&lt;/font&gt; httplib2
&lt;font color="#0000ff"&gt;import&lt;/font&gt; re

&lt;font color="#0000ff"&gt;def&lt;/font&gt; &lt;font color="#0000ff"&gt;postEntry&lt;/font&gt;(auth):

    entry = &lt;font color="#a31515"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/font&gt;
&lt;font color="#a31515"&gt;    &amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;    &amp;lt;entry xmlns='http://www.w3.org/2005/Atom'&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;      &amp;lt;title type='text'&amp;gt;Test Post from Python&amp;lt;/title&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;      &amp;lt;content type='xhtml'&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;        &amp;lt;div xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;          &amp;lt;p&amp;gt;If you can see this, then it worked!&amp;lt;/p&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;        &amp;lt;/div&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;      &amp;lt;/content&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;      &amp;lt;author&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;        &amp;lt;name&amp;gt;Dennis&amp;lt;/name&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;      &amp;lt;/author&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;    &amp;lt;/entry&amp;gt;&lt;/font&gt;
&lt;font color="#a31515"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/font&gt;

    headers = {&lt;font color="#a31515"&gt;'Content-Type'&lt;/font&gt;: &lt;font color="#a31515"&gt;'application/atom+xml'&lt;/font&gt;, &lt;font color="#a31515"&gt;'Authorization'&lt;/font&gt;: &lt;font color="#a31515"&gt;'GoogleLogin Auth=%s'&lt;/font&gt; % auth.strip()}
    response, content = h.request(uri, &lt;font color="#a31515"&gt;'POST'&lt;/font&gt;, body=entry, headers=headers)
    &lt;font color="#0000ff"&gt;print&lt;/font&gt; response, content

&lt;font color="#0000ff"&gt;def&lt;/font&gt; &lt;font color="#0000ff"&gt;authenticate&lt;/font&gt;():
    auth_uri = &lt;font color="#a31515"&gt;'https://www.google.com/accounts/ClientLogin'&lt;/font&gt;
    headers = {&lt;font color="#a31515"&gt;'Content-Type'&lt;/font&gt;: &lt;font color="#a31515"&gt;'application/x-www-form-urlencoded'&lt;/font&gt;}
    myrequest = &lt;font color="#a31515"&gt;&amp;quot;Email=MY_GMAIL_ACCOUNT&amp;amp;Passwd=MY_GMAIL_PASSWORD&amp;amp;service=blogger&amp;amp;service=Dcraven-TestApp-0.0&amp;quot;&lt;/font&gt;
    response, content = h.request(auth_uri, &lt;font color="#a31515"&gt;'POST'&lt;/font&gt;, body=myrequest, headers=headers)
    &lt;font color="#0000ff"&gt;if&lt;/font&gt; response[&lt;font color="#a31515"&gt;'status'&lt;/font&gt;] == &lt;font color="#a31515"&gt;'200'&lt;/font&gt;:
        &lt;font color="#0000ff"&gt;return&lt;/font&gt; re.search(&lt;font color="#a31515"&gt;'Auth=(\S*)'&lt;/font&gt;, content).group(&lt;font color="#0000ff"&gt;1&lt;/font&gt;)
    &lt;font color="#0000ff"&gt;else&lt;/font&gt;:
        &lt;font color="#0000ff"&gt;return&lt;/font&gt; None

h = httplib2.Http()
h.follow_all_redirects = True
uri = &lt;font color="#a31515"&gt;'http://www.blogger.com/feeds/BLOGID/posts/full'&lt;/font&gt;

cert = authenticate()
&lt;font color="#0000ff"&gt;if&lt;/font&gt; cert:
    postEntry(cert)

&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
The result of this was &lt;strong&gt;exactly&lt;/strong&gt; the same thing, although the
actual &lt;tt&gt;authenticate()&lt;/tt&gt; function worked fine, so the problem doesn't
lie there. The response from the &lt;tt&gt;POST&lt;/tt&gt; call in this method was in fact
&lt;tt&gt;200&lt;/tt&gt;, and I did get an &lt;tt&gt;Auth&lt;/tt&gt; code from the server. Even after
manually packing this code into the header as specified by the Google
documentation, I still got an &lt;tt&gt;Error 401: Missing auth parameter in
  GoogleLogin&lt;/tt&gt; returned by the &lt;tt&gt;postEntry()&lt;/tt&gt; function.
&lt;/p&gt;
&lt;p&gt;
  I think this code should work, but alas, it does not. If anyone has any
  ideas why, or can spot an error in the code I'd really appreciate you
  pointing it out in a comment below. In the meantime I think I'll make posts
  the old fashioned way until I get the ambition to try again.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;NOTE: &lt;/span&gt;&lt;/span&gt;I suppose I should note that in the above code, the words BLOGID, MY_GMAIL_PASSWORD, and MY_GMAIL_ACCOUNT actually contained the appropriate values when I tried to run the program :)
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;UPDATE:&lt;/b&gt; I just wanted to post this update for anyone landing here from a Google search or something. I ended up having success with this as posted &lt;a href="http://djcraven.blogspot.com/2006/10/success-posting-to-blogger-beta-using.html"&gt;here&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-9050229134500237604?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/9050229134500237604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/using-google-gdata-api-with-python.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9050229134500237604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9050229134500237604'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/using-google-gdata-api-with-python.html' title='Using the Google GData API with Python'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-9162144190065120499</id><published>2006-10-08T05:47:00.000-05:00</published><updated>2006-10-08T06:10:03.701-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gajim'/><category scheme='http://www.blogger.com/atom/ns#' term='pastebin'/><title type='text'>VimPastebin - Post to Pastebin from within Vim</title><content type='html'>The VimPastebin script is a &lt;a class="ext-link" href="http://www.vim.org/"&gt;&lt;span class="icon"&gt;Vim&lt;/span&gt;&lt;/a&gt; plugin script that posts selected text to the &lt;a class="ext-link" href="http://pastebin.com/"&gt;&lt;span class="icon"&gt;Pastebin&lt;/span&gt;&lt;/a&gt; of your choice and optionally sends the URL to your pasted text as &lt;a href="http://gajim.org"&gt;Gajim&lt;/a&gt; message to someone in your roster. The syntax is chosen from the current &lt;strong&gt;filetype&lt;/strong&gt; in the Vim editor. For example, if you are editing a Python file, the text sent to &lt;a class="ext-link" href="http://pastebin.com/"&gt;&lt;span class="icon"&gt;Pastebin&lt;/span&gt;&lt;/a&gt; will automatically be highlighted with Python syntax.
&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;&lt;h2&gt;Requirements&lt;/h2&gt; &lt;p&gt; This script is mostly written in &lt;a class="ext-link" href="http://www.python.org/"&gt;&lt;span class="icon"&gt;Python&lt;/span&gt;&lt;/a&gt;, so it will only work if your Vim was compiled with the &lt;tt&gt;--enable-pythoninterp=yes&lt;/tt&gt; configure option. To see if your installed Vim is compiled with this option, simply type the &lt;tt&gt;:version&lt;/tt&gt; command inside Vim and look for &lt;tt&gt;+python&lt;/tt&gt;. If you see &lt;tt&gt;-python&lt;/tt&gt; in the list, this script will not work, otherwise you're golden!  &lt;/p&gt;&lt;h2&gt;Installation&lt;/h2&gt; &lt;p&gt; Drop &lt;a class="ext-link" href="http://arker.homelinux.org/files/pastebin.vim"&gt;&lt;span class="icon"&gt;this&lt;/span&gt;&lt;/a&gt; script into your &lt;tt&gt;~/.vim/plugin&lt;/tt&gt; directory or somewhere else in your &lt;tt&gt;$VIMRUNTIME&lt;/tt&gt; path. It will be sourced automatically next time you start Vim. You can source it manually by typing &lt;tt&gt;:source /path/to/script&lt;/tt&gt; if you like. &lt;/p&gt; &lt;p&gt; There are a couple of configuration options in the script that should be modified for your particular settings. You can set your preferred &lt;a class="ext-link" href="http://pastebin.com/"&gt;&lt;span class="icon"&gt;Pastebin&lt;/span&gt;&lt;/a&gt; on line 38, and your preferred username on line 40. By default, the script included on this wiki page will post to &lt;a class="ext-link" href="http://pastebin.com/"&gt;&lt;span class="icon"&gt;http://pastebin.com&lt;/span&gt;&lt;/a&gt; as the user "vimuser". &lt;/p&gt; &lt;h2&gt;Usage&lt;/h2&gt; &lt;p&gt; To use the script is very simple. Just visually block (Shift-v) the lines of code you want to send to the &lt;a class="ext-link" href="http://pastebin.com/"&gt;&lt;span class="icon"&gt;Pastebin&lt;/span&gt;&lt;/a&gt; and enter the command &lt;tt&gt;:PasteCode&lt;/tt&gt;. The blocked text will be sent to the &lt;a class="ext-link" href="http://pastebin.com/"&gt;&lt;span class="icon"&gt;Pastebin&lt;/span&gt;&lt;/a&gt; and the new URL will be shown on the Vim statusline. Optionally, you could enter the command &lt;tt&gt;:PasteGajim somename@somejid.org&lt;/tt&gt; to send the new URL to the JID somename@somejid.org providing that JID appears in your roster. To make it even easier, you can send it to someone in your roster by only specifying their name, like &lt;tt&gt;:PasteGajim dcraven&lt;/tt&gt; will send it to user name dcraven. This is handy if you cannot remember the person's full JID. &lt;/p&gt; &lt;h2&gt;That's It!&lt;/h2&gt; &lt;p&gt; That's pretty much all there is to it. If you missed the link to the actual script above, you can &lt;a class="ext-link" href="http://arker.homelinux.org/files/pastebin.vim"&gt;&lt;span class="icon"&gt;download it here&lt;/span&gt;&lt;/a&gt;. Enjoy! &lt;/p&gt;
&lt;p&gt;Here's the code if you just want to have a quick look:
&lt;pre&gt;
&lt;font color="#008000"&gt;&amp;quot; Make sure the Vim was compiled with +python before loading the script...&lt;/font&gt;
&lt;font color="#0000ff"&gt;if&lt;/font&gt; !&lt;font color="#0000ff"&gt;has&lt;/font&gt;&lt;font color="#0000ff"&gt;(&lt;/font&gt;&lt;font color="#a31515"&gt;&amp;quot;python&amp;quot;&lt;/font&gt;&lt;font color="#0000ff"&gt;)&lt;/font&gt;
        &lt;font color="#0000ff"&gt;finish&lt;/font&gt;
&lt;font color="#0000ff"&gt;endif&lt;/font&gt;

&lt;font color="#008000"&gt;&amp;quot; Map a keystroke for Visual Mode only (default:F2)&lt;/font&gt;
:&lt;font color="#0000ff"&gt;vmap&lt;/font&gt; &lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;f2&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt; :PasteCode&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;cr&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;

&lt;font color="#008000"&gt;&amp;quot; Define two commands.. One for just pastebinning alone, and another for&lt;/font&gt;
&lt;font color="#008000"&gt;&amp;quot; Gajiming the results&lt;/font&gt;
:&lt;font color="#0000ff"&gt;command&lt;/font&gt; &lt;font color="#0000ff"&gt;-&lt;/font&gt;&lt;font color="#a31515"&gt;range&lt;/font&gt; &lt;font color="#0000ff"&gt;-&lt;/font&gt;&lt;font color="#a31515"&gt;nargs&lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#0000ff"&gt;*&lt;/font&gt; PasteCode :&lt;font color="#0000ff"&gt;call&lt;/font&gt; PasteMe(&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;line1&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;,&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;line2&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;,&lt;font color="#a31515"&gt;&amp;quot;None&amp;quot;&lt;/font&gt;)
:&lt;font color="#0000ff"&gt;command&lt;/font&gt; &lt;font color="#0000ff"&gt;-&lt;/font&gt;&lt;font color="#a31515"&gt;range&lt;/font&gt; &lt;font color="#0000ff"&gt;-&lt;/font&gt;&lt;font color="#a31515"&gt;nargs&lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#0000ff"&gt;*&lt;/font&gt; PasteGajim :&lt;font color="#0000ff"&gt;call&lt;/font&gt; PasteMe(&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;line1&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;,&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;line2&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;,&lt;font color="#a31515"&gt;&amp;quot;&amp;lt;args&amp;gt;&amp;quot;&lt;/font&gt;)

&lt;font color="#0000ff"&gt;function&lt;/font&gt;! PasteMe&lt;font color="#0000ff"&gt;(&lt;/font&gt;line1,line2,args&lt;font color="#0000ff"&gt;)&lt;/font&gt;
&lt;font color="#008000"&gt;python &amp;lt;&amp;lt; EOF&lt;/font&gt;
&lt;font color="#0000ff"&gt;import&lt;/font&gt; vim

line1 = vim.eval('&lt;font color="#a31515"&gt;a:line1&lt;/font&gt;')
line2 = vim.eval('&lt;font color="#a31515"&gt;a:line2&lt;/font&gt;')
jid = vim.eval('&lt;font color="#a31515"&gt;a:args&lt;/font&gt;')
format = vim.eval('&lt;font color="#a31515"&gt;&amp;amp;ft&lt;/font&gt;')

url = PBSend(line1, line2, format)
&lt;font color="#0000ff"&gt;if&lt;/font&gt; &lt;font color="#0000ff"&gt;not&lt;/font&gt; jid == &amp;quot;&lt;font color="#a31515"&gt;None&lt;/font&gt;&amp;quot;:
    gajim_send_url(jid, url)
&lt;font color="#0000ff"&gt;print&lt;/font&gt; &amp;quot;&lt;font color="#a31515"&gt;Pasted at %s&lt;/font&gt;&amp;quot; % url
&lt;font color="#008000"&gt;EOF&lt;/font&gt;
&lt;font color="#0000ff"&gt;endfunction&lt;/font&gt;

&lt;font color="#008000"&gt;python &amp;lt;&amp;lt; EOF&lt;/font&gt;
&lt;font color="#0000ff"&gt;import&lt;/font&gt; vim
&lt;font color="#0000ff"&gt;from&lt;/font&gt; urllib2 &lt;font color="#0000ff"&gt;import&lt;/font&gt; urlopen
&lt;font color="#0000ff"&gt;from&lt;/font&gt; re &lt;font color="#0000ff"&gt;import&lt;/font&gt; compile

&lt;font color="#0000ff"&gt;def&lt;/font&gt; &lt;font color="#0000ff"&gt;PBSend&lt;/font&gt;(line1, line2, format='&lt;font color="#a31515"&gt;text&lt;/font&gt;'):
&lt;font color="#008000"&gt;################### BEGIN USER CONFIG ###################&lt;/font&gt;
    &lt;font color="#008000"&gt;# Set this to your preferred pastebin&lt;/font&gt;
    pastebin = '&lt;font color="#a31515"&gt;&lt;a href="http://pastebin.com"&gt;http://pastebin.com&lt;/a&gt;&lt;/font&gt;'
    &lt;font color="#008000"&gt;# Set this to your preferred username&lt;/font&gt;
    user = '&lt;font color="#a31515"&gt;vimuser&lt;/font&gt;'
&lt;font color="#008000"&gt;#################### END USER CONFIG ####################&lt;/font&gt;

    supported_formats = {
        '&lt;font color="#a31515"&gt;text&lt;/font&gt;' : '&lt;font color="#a31515"&gt;text&lt;/font&gt;', '&lt;font color="#a31515"&gt;bash&lt;/font&gt;' : '&lt;font color="#a31515"&gt;bash&lt;/font&gt;', '&lt;font color="#a31515"&gt;python&lt;/font&gt;' : '&lt;font color="#a31515"&gt;python&lt;/font&gt;', '&lt;font color="#a31515"&gt;c&lt;/font&gt;' : '&lt;font color="#a31515"&gt;c&lt;/font&gt;',
        '&lt;font color="#a31515"&gt;cpp&lt;/font&gt;' : '&lt;font color="#a31515"&gt;cpp&lt;/font&gt;', '&lt;font color="#a31515"&gt;html&lt;/font&gt;' : '&lt;font color="#a31515"&gt;html4strict&lt;/font&gt;', '&lt;font color="#a31515"&gt;java&lt;/font&gt;' : '&lt;font color="#a31515"&gt;java&lt;/font&gt;',
        '&lt;font color="#a31515"&gt;javascript&lt;/font&gt;' : '&lt;font color="#a31515"&gt;javascript&lt;/font&gt;', '&lt;font color="#a31515"&gt;perl&lt;/font&gt;' : '&lt;font color="#a31515"&gt;perl&lt;/font&gt;', '&lt;font color="#a31515"&gt;php&lt;/font&gt;' : '&lt;font color="#a31515"&gt;php&lt;/font&gt;',
        '&lt;font color="#a31515"&gt;sql&lt;/font&gt;' : '&lt;font color="#a31515"&gt;sql&lt;/font&gt;', '&lt;font color="#a31515"&gt;ada&lt;/font&gt;' : '&lt;font color="#a31515"&gt;ada&lt;/font&gt;', '&lt;font color="#a31515"&gt;apache&lt;/font&gt;' : '&lt;font color="#a31515"&gt;apache&lt;/font&gt;', '&lt;font color="#a31515"&gt;asm&lt;/font&gt;' : '&lt;font color="#a31515"&gt;asm&lt;/font&gt;',
        '&lt;font color="#a31515"&gt;aspvbs&lt;/font&gt;' : '&lt;font color="#a31515"&gt;asp&lt;/font&gt;', '&lt;font color="#a31515"&gt;dcl&lt;/font&gt;' : '&lt;font color="#a31515"&gt;caddcl&lt;/font&gt;', '&lt;font color="#a31515"&gt;lisp&lt;/font&gt;' : '&lt;font color="#a31515"&gt;lisp&lt;/font&gt;', '&lt;font color="#a31515"&gt;cs&lt;/font&gt;' : '&lt;font color="#a31515"&gt;csharp&lt;/font&gt;',
        '&lt;font color="#a31515"&gt;css&lt;/font&gt;' : '&lt;font color="#a31515"&gt;css&lt;/font&gt;', '&lt;font color="#a31515"&gt;lua&lt;/font&gt;' : '&lt;font color="#a31515"&gt;lua&lt;/font&gt;', '&lt;font color="#a31515"&gt;masm&lt;/font&gt;' : '&lt;font color="#a31515"&gt;mpasm&lt;/font&gt;', '&lt;font color="#a31515"&gt;nsis&lt;/font&gt;' : '&lt;font color="#a31515"&gt;nsis&lt;/font&gt;',
        '&lt;font color="#a31515"&gt;objc&lt;/font&gt;' : '&lt;font color="#a31515"&gt;objc&lt;/font&gt;', '&lt;font color="#a31515"&gt;ora&lt;/font&gt;' : '&lt;font color="#a31515"&gt;oracle8&lt;/font&gt;', '&lt;font color="#a31515"&gt;pascal&lt;/font&gt;' : '&lt;font color="#a31515"&gt;pascal&lt;/font&gt;',
        '&lt;font color="#a31515"&gt;basic&lt;/font&gt;' : '&lt;font color="#a31515"&gt;qbasic&lt;/font&gt;', '&lt;font color="#a31515"&gt;smarty&lt;/font&gt;' : '&lt;font color="#a31515"&gt;smarty&lt;/font&gt;', '&lt;font color="#a31515"&gt;vb&lt;/font&gt;' : '&lt;font color="#a31515"&gt;vb&lt;/font&gt;', '&lt;font color="#a31515"&gt;xml&lt;/font&gt;' : '&lt;font color="#a31515"&gt;xml&lt;/font&gt;'
    }

    &lt;font color="#0000ff"&gt;if&lt;/font&gt; &lt;font color="#0000ff"&gt;not&lt;/font&gt; (pastebin[:7] == '&lt;font color="#a31515"&gt;&lt;a href="http://"&gt;http://&lt;/a&gt;&lt;/font&gt;'):
        pastebin = '&lt;font color="#a31515"&gt;&lt;a href="http://"&gt;http://&lt;/a&gt;&lt;/font&gt;' + pastebin

    code = '&lt;font color="#0000ff"&gt;\n&lt;/font&gt;'.join(vim.current.buffer[int(line1)-1:int(line2)])
    &lt;font color="#0000ff"&gt;if&lt;/font&gt; format &lt;font color="#0000ff"&gt;in&lt;/font&gt; supported_formats.keys():
        data = &amp;quot;&lt;font color="#a31515"&gt;format=%s&amp;amp;paste=Submit&amp;amp;code2=%s&amp;amp;poster=%s&lt;/font&gt;&amp;quot; % &lt;font color="#0000ff"&gt;\&lt;/font&gt;
                (supported_formats[format], urlencode(code),
                urlencode(user))
    &lt;font color="#0000ff"&gt;else&lt;/font&gt;:
        data = &amp;quot;&lt;font color="#a31515"&gt;format=text&amp;amp;paste=Submit&amp;amp;code2=%s&amp;amp;poster=%s&lt;/font&gt;&amp;quot; % &lt;font color="#0000ff"&gt;\&lt;/font&gt;
                (urlencode(code), urlencode(user))

    u = urlopen(pastebin, data)
    f = &amp;quot;&amp;quot;.join(u.readlines())
    rx = compile(&amp;quot;&lt;font color="#a31515"&gt;&amp;lt;a.*?/(\d+)&lt;/font&gt;&lt;font color="#0000ff"&gt;\&amp;quot;&lt;/font&gt;&lt;font color="#a31515"&gt;&amp;gt;&lt;/font&gt;&amp;quot;)
    ar = rx.findall(f)
    &lt;font color="#0000ff"&gt;if&lt;/font&gt; len(ar) &amp;gt; 0:
        url = pastebin + '&lt;font color="#a31515"&gt;/&lt;/font&gt;' + ar[0]
        &lt;font color="#0000ff"&gt;return&lt;/font&gt; url
    &lt;font color="#0000ff"&gt;else&lt;/font&gt;:
        &lt;font color="#0000ff"&gt;print&lt;/font&gt; '&lt;font color="#a31515"&gt;An error occured.&lt;/font&gt;'

&lt;font color="#0000ff"&gt;def&lt;/font&gt; &lt;font color="#0000ff"&gt;gajim_send_url&lt;/font&gt;(jid, url):
    &lt;font color="#0000ff"&gt;try&lt;/font&gt;:
        &lt;font color="#0000ff"&gt;import&lt;/font&gt; dbus
        sbus = dbus.SessionBus()
        obj = sbus.get_object('&lt;font color="#a31515"&gt;org.gajim.dbus&lt;/font&gt;', '&lt;font color="#a31515"&gt;/org/gajim/dbus/RemoteObject&lt;/font&gt;')
        interface = dbus.Interface(obj, '&lt;font color="#a31515"&gt;org.gajim.dbus.RemoteInterface&lt;/font&gt;')

        &lt;font color="#008000"&gt;# Try to get the actual JID from your contact list&lt;/font&gt;
        list = interface.__getattr__('&lt;font color="#a31515"&gt;list_contacts&lt;/font&gt;')
        roster = list()
        &lt;font color="#0000ff"&gt;for&lt;/font&gt; contact &lt;font color="#0000ff"&gt;in&lt;/font&gt; roster:
            &lt;font color="#0000ff"&gt;if&lt;/font&gt; jid.lower() == contact['&lt;font color="#a31515"&gt;name&lt;/font&gt;'].lower():
                jid = contact['&lt;font color="#a31515"&gt;jid&lt;/font&gt;']

        send = interface.__getattr__('&lt;font color="#a31515"&gt;send_message&lt;/font&gt;')
        &lt;font color="#0000ff"&gt;if&lt;/font&gt; &lt;font color="#0000ff"&gt;not&lt;/font&gt; send(jid, url):
            &lt;font color="#0000ff"&gt;print&lt;/font&gt; &amp;quot;&lt;font color="#a31515"&gt;%s not found in Gajim roster.&lt;/font&gt;&amp;quot; % jid
    &lt;font color="#0000ff"&gt;except&lt;/font&gt;:
        &lt;font color="#0000ff"&gt;print&lt;/font&gt; &amp;quot;&lt;font color="#a31515"&gt;Error sending message to %s.&lt;/font&gt;&amp;quot; % jid

&lt;font color="#0000ff"&gt;def&lt;/font&gt; &lt;font color="#0000ff"&gt;urlencode&lt;/font&gt;(data):
    out = &amp;quot;&amp;quot;
    &lt;font color="#0000ff"&gt;for&lt;/font&gt; char &lt;font color="#0000ff"&gt;in&lt;/font&gt; data:
        &lt;font color="#0000ff"&gt;if&lt;/font&gt; char.isalnum() &lt;font color="#0000ff"&gt;or&lt;/font&gt; char &lt;font color="#0000ff"&gt;in&lt;/font&gt; ['&lt;font color="#a31515"&gt;-&lt;/font&gt;','&lt;font color="#a31515"&gt;_&lt;/font&gt;']:
            out += char
        &lt;font color="#0000ff"&gt;else&lt;/font&gt;:
            char = hex(ord(char))[2:]
            &lt;font color="#0000ff"&gt;if&lt;/font&gt; len(char) == 1:
                char = &amp;quot;&lt;font color="#a31515"&gt;0&lt;/font&gt;&amp;quot; + char
            out += &amp;quot;&lt;font color="#a31515"&gt;%&lt;/font&gt;&amp;quot; + char
    &lt;font color="#0000ff"&gt;return&lt;/font&gt; out
&lt;font color="#008000"&gt;EOF&lt;/font&gt;
&lt;/pre&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-9162144190065120499?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/9162144190065120499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/vimpastebin-post-to-pastebin-from.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9162144190065120499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/9162144190065120499'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/vimpastebin-post-to-pastebin-from.html' title='VimPastebin - Post to Pastebin from within Vim'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7044907287770355906.post-1811366069056062093</id><published>2006-10-07T16:53:00.000-05:00</published><updated>2006-10-07T16:56:31.179-05:00</updated><title type='text'>Screw it... Let someone else host my crud :)</title><content type='html'>I've decided to migrate my own blog from my home server to here to see how it works out. I hardly ever make posts, and my hardware is unreliable. If I put it here, then maybe I can forget about it altogether.

The hard/painful part is migrating  all (3?) of my posts from my old home to here. heh&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7044907287770355906-1811366069056062093?l=djcraven5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://djcraven5.blogspot.com/feeds/1811366069056062093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://djcraven5.blogspot.com/2006/10/screw-it-let-someone-else-host-my-crud.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1811366069056062093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7044907287770355906/posts/default/1811366069056062093'/><link rel='alternate' type='text/html' href='http://djcraven5.blogspot.com/2006/10/screw-it-let-someone-else-host-my-crud.html' title='Screw it... Let someone else host my crud :)'/><author><name>Dennis</name><uri>http://www.blogger.com/profile/16653637086961997662</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
