<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>R James Taylor<title>&#187; How-to</title>
</title>
	<atom:link href="http://www.rjamestaylor.com/category/howto/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rjamestaylor.com</link>
	<description>Unboxed: technology, customer service, satire, opinion</description>
	<lastBuildDate>Wed, 08 Sep 2010 18:17:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<script type="text/javascript">
if (typeof Meebo == "undefined") {
Meebo=function(){(Meebo._=Meebo._||[]).push(arguments)};
(function(q){

	var args = arguments;
	if (!document.body) { return setTimeout(function(){ args.callee.apply(this, args) }, 100); }
	var d=document, b=d.body, m=b.insertBefore(d.createElement('div'), b.firstChild); s=d.createElement('script');
	m.id='meebo'; m.style.display='none'; m.innerHTML='<iframe id="meebo-iframe"></iframe>';
	s.src='http'+(q.https?'s':'')+'://'+(q.stage?'stage-':'')+'cim.meebo.com/cim/cim.php?network='+q.network;
	b.insertBefore(s, b.firstChild);

})({network:'rjamestaylor_fu01he'});	}</script>	<item>
		<title>Anti-social media: Turning communication into unication</title>
		<link>http://www.rjamestaylor.com/anti-social-media-turning-communication-into-unication/</link>
		<comments>http://www.rjamestaylor.com/anti-social-media-turning-communication-into-unication/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 19:35:48 +0000</pubDate>
		<dc:creator>rjamestaylor</dc:creator>
				<category><![CDATA[How-to]]></category>
		<category><![CDATA[emerging media]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=638</guid>
		<description><![CDATA[Recently I received an unsolicited request for help from someone I&#8217;ve never met and whom I do not want to expose. The sender confused me for a Twitter employee, I guess. Here&#8217;s the request (paraphrased): Greetings, How can I use Twitter for business messaging but block people from sending us tweets back? I&#8217;d like to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fanti-social-media-turning-communication-into-unication%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fanti-social-media-turning-communication-into-unication%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Recently I received an unsolicited request for help from someone I&#8217;ve never met and whom I do not want to expose. The sender confused me for a Twitter employee, I guess. Here&#8217;s the request (paraphrased):</p>
<blockquote style="text-align: left;"><p>Greetings,</p>
<p>How can I use Twitter for business messaging but block people from sending us tweets back? I&#8217;d like to guarantee the public can see our tweets but we don&#8217;t see theirs.</p></blockquote>
<p>I pointed the sender to twitter.com for assistance but could not let this go without sharing the hilarity of the request.</p>
<p>First, I use Twitter but have no relationship with Twitter. I have no idea why someone would think I do.</p>
<p>Second, the request is so totally against social media principles as to be a poster child of &#8220;Does Not Get the Concept.&#8221;</p>
<p>Twitter and other social networking venues are about sharing, co-communicating (emphasizing the two-way nature because too many one sided message givers call themselves and their function &#8220;communicating&#8221;) and community. The idea that someone could disable others&#8217; ability to write tweets to one&#8217;s own account is, well, preposterous.</p>
<p>However, I firmly believe that many businesses and other communicators would actually prefer a one-way messaging system that would guarantee public consumption but prevent public response. Just so happens this misguided inquirer is more blunt and honest about his or her intent. Others actually use Twitter and Facebook, etc., in this same manner: output only, no input acknowledged.</p>
<p>Most other media are exactly this kind of one-sided &#8220;unication&#8221; (my term for these &#8220;communicators&#8221;) that push out messages but have no mechanism or intent for dialogue. Radio, TV, infomercials, print media, banner ads, etc., all favor the message sender and diminish or prevent the reciprocal exchange of information and feedback. Even email has become a vehicle for unication; consider &#8220;noreply@example.com&#8221;.</p>
<p>I believe one reason for the uptake and success of social networking is the inherent ability to engage in two-way conversations.</p>
<p>It will be interesting to see how Twitter changes with the introduction of Promoted Tweets &#8212; that is, in stream paid advertisements. Will this push Twitter to become yet another unication platform? Will Twitter be able to retain the &#8220;social&#8221; aspect of its service post Promoted Tweets? I hope so.</p>
<img style='display:none' id="post-638-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/anti-social-media-turning-communication-into-unication/',title:'Anti-social media: Turning communication into unication',tweet:' 			 				 			 		 Recently I received an unsolicited request for help from someone I&#8217;ve never m',description:' 			 				 			 		 Recently I received an unsolicited request for help from someone I&#8217;ve never m'})"><script type='text/javascript'>document.getElementById("post-638-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/anti-social-media-turning-communication-into-unication/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Purging frozen messages from Exim</title>
		<link>http://www.rjamestaylor.com/purging-frozen-messages-from-exim/</link>
		<comments>http://www.rjamestaylor.com/purging-frozen-messages-from-exim/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 20:23:28 +0000</pubDate>
		<dc:creator>rjamestaylor</dc:creator>
				<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[BASH]]></category>
		<category><![CDATA[exim]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=626</guid>
		<description><![CDATA[There&#8217;s probably a better way to do this. (If so, leave a comment!) However, I run a debian server for a small task and use the default MTA Exim for mail delivery of status updates to my main mail accounts. Usually I run Postfix or Sendmail. I even have to support Qmail on occasion. However [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fpurging-frozen-messages-from-exim%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fpurging-frozen-messages-from-exim%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>There&#8217;s probably a better way to do this. (If so, leave a comment!) However, I run a debian server for a small task and use the default MTA Exim for mail delivery of status updates to my main mail accounts. Usually I run Postfix or Sendmail. I even have to support Qmail on occasion. However Exim is unfamiliar territory for me &#8212; I&#8217;m an Exim n00b. </p>
<p>Recently I decided I wanted to remove the &#8220;frozen&#8221; messages seen by running the <code>mailq</code> command. For example:</p>
<blockquote><p><code><br />
# mailq<br />
48h  1.6K 1NUQLB-0007BC-QL <> *** frozen ***<br />
          user@domain.tld</p>
<p>48h  1.6K 1NUQO9-0007CW-1u <> *** frozen ***<br />
          user@domain.tld</p>
<p>48h  1.6K 1NUQOG-0007CY-1f <> *** frozen ***<br />
          user@domain.tld</p>
<p>48h  1.6K 1NUQOG-0007CZ-1v <> *** frozen ***<br />
          user@domain.tld</p>
<p>48h  1.6K 1NUQP4-0007DH-Af <> *** frozen ***<br />
          user@domain.tld<br />
</code></p></blockquote>
<p>I know they&#8217;ll be purged eventually, I just wanted to clear the queue for some quick testing I was performing. The documentation I found on-line mentioned running &#8220;<code>exim -Mrm &lt;id&gt;</code>&#8221; for each message id in the <code>mailq</code> output. Being lazy, I don&#8217;t want to run that each time &#8212; I want a simple one-line command to purge frozen messages. So, I wrote the following BASH script that parses the <code>mailq</code> output and executes the command for each message id:</p>
<blockquote><p>
<code>for i in `mailq | awk '$6 ~ /^frozen$/ {print $3}'`; do exim -Mrm $i; done</code>
</p></blockquote>
<p>Worked like a charm! Message queue emptied of frozen messages.</p>
<img style='display:none' id="post-626-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/purging-frozen-messages-from-exim/',title:'Purging frozen messages from Exim',tweet:' 			 				 			 		 There&#8217;s probably a better way to do this. (If so, leave a comment!) However, ',description:' 			 				 			 		 There&#8217;s probably a better way to do this. (If so, leave a comment!) However, '})"><script type='text/javascript'>document.getElementById("post-626-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/purging-frozen-messages-from-exim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter-pwn&#8217;ed: the confessions of a lazy developer</title>
		<link>http://www.rjamestaylor.com/mea-culpa-the-confessions-of-a-lazy-developer/</link>
		<comments>http://www.rjamestaylor.com/mea-culpa-the-confessions-of-a-lazy-developer/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 18:59:53 +0000</pubDate>
		<dc:creator>rjamestaylor</dc:creator>
				<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/mea-culpa-the-confessions-of-a-lazy-developer/</guid>
		<description><![CDATA[This is a hard post to write since it is absolutely embarrassing to me and may cause me to lose serious geek-cred. However, I hope this is a useful mea culpa for others&#8217; benefit. This morning I spent a while revising a script that accepted external input which I borrowed (and modified) from someone else. The [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fmea-culpa-the-confessions-of-a-lazy-developer%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fmea-culpa-the-confessions-of-a-lazy-developer%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>This is a hard post to write since it is absolutely embarrassing to me and may cause me to lose serious geek-cred. However, I hope this is a useful <em>mea culpa</em> for others&#8217; benefit. This morning I spent a while revising a script that accepted external input which I borrowed (and modified) from someone else. The original script used the external input safely &#8211; my modifications made it a true security nightmare. Basically, the script took content from the Twitter API and rerouted it through Jabber (XMPP) protocol. My change also sent the content through email.</p>
<p>If I had used the built-in <a title="ruby stdlib net::smtp" href="http://ruby-doc.org/stdlib/libdoc/net/smtp/rdoc/index.html" target="_blank">SMTP features of ruby</a> this post would have been unnecessary. However, as I was in a hurry (the excuse of a scoundrel) I simply piped the output through BASH to the <code>mail</code> command via ruby&#8217;s <code>system()</code> function. Also, I took no precautions to escape the external input from being executed by BASH itself. System admins and top-notch developers are now crying with laughter.</p>
<p>Why did I do this? Besides being an idiot, I did this because this script was a &#8220;one-off&#8221; and not something I was paid to develop. I needed a feature and, in the spirit of a developer (not a system administrator or security professional), I looked for the path of least resistance. With the <code>system()</code> call I could use my knowledge of the Linux command-line to accomplish my task. Since the original script was written in ruby, a language I have not used much at all, previously, I was able to add my needed feature in minutes. A couple more minutes would be all that was necessary to find out how to use ruby itself to accomplish this result. Laziness won over thoroughness and correctness. Result: a *huge* security hole.</p>
<p>Here&#8217;s what prompted me to invest in learning to add this feature in the Right Way™: a friend of mine who is an überGeek realized that, based on a clue I gave out about my script&#8217;s performance, he could have his way with my server via Twitter. I was Twitter-pwn&#8217;ed. Here&#8217;s what he sent me (knowing I watch my tweets via this script):</p>
<blockquote><p>@<a href="/rjamestaylor">rjamestaylor</a> $(touch /tmp/test)</p></blockquote>
<blockquote><p>@<a href="/rjamestaylor">rjamestaylor</a> $(ls -la /tmp/test)</p></blockquote>
<p>After he sent these two tweets my script sent me an email with this:</p>
<blockquote><p><code>-rw-r--r-- 1 root root 0 Dec 27 03:39 /tmp/test</code></p></blockquote>
<p>Yes. BASH executed his tweet (!) and as ROOT! So, if someone had tweeted &#8220;<code>@rjamestaylor $(rm -rf /)</code>&#8221; my server would be a barren husk of hardware. Worse, someone could have used my script &#8212; via Twitter! &#8212; to setup privileged user accounts, send spam (though small), attack other systems, etc. Why root (or as my geek friends would ask, WHY IN GOD&#8217;S NAME &#8220;root&#8221;?)? Simple: I was in a hurry. Stupid.</p>
<p>Lesson: spending the little bit of extra time necessary to add features without violating security protocols is always worth it. Sure, I could have just bought some <a title="My CodeOffsets critique" href="http://www.rjamestaylor.com/codeoffsets-com-a-bad-idea-for-solving-a-real-problem/" target="_blank">CodeOffsets</a> to assuage my guilt, but it was actually better to (1) shut down my script until (2) I fixed the security issues.</p>
<p>Turns out adding net::smtp to a script in ruby is painless. Now I have my feature and no exciting side-effects from rushed, careless development. In fact, most security holes I encounter in others&#8217; code is due to the same thing: rush to add features without a review of implications. Anytime one takes external input from a user or the Internet (or Twitter) one must sanitize the input from unintended effects. This goes for SQL injection (parameters, people!) as well as simple command expansion attacks, among many other possible vectors.</p>
<p>So, go ahead and tweet BASH-expandable tweets to me, my code is not <a title="Seriously. Read my critique of CodeOffsets.com" href="http://www.rjamestaylor.com/codeoffsets-com-a-bad-idea-for-solving-a-real-problem/" target="_blank">just offset</a>, it&#8217;s fixed.</p>
<img style='display:none' id="post-612-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/mea-culpa-the-confessions-of-a-lazy-developer/',title:'Twitter-pwn&#8217;ed: the confessions of a lazy developer',tweet:' 			 				 			 		 This is a hard post to write since it is absolutely embarrassing to me and may caus',description:' 			 				 			 		 This is a hard post to write since it is absolutely embarrassing to me and may caus'})"><script type='text/javascript'>document.getElementById("post-612-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/mea-culpa-the-confessions-of-a-lazy-developer/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Twitter Lists: Changing Everything about Twitter</title>
		<link>http://www.rjamestaylor.com/twitter-lists-changing-everything-about-twitter/</link>
		<comments>http://www.rjamestaylor.com/twitter-lists-changing-everything-about-twitter/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 02:27:16 +0000</pubDate>
		<dc:creator>rjamestaylor</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[emerging media]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=582</guid>
		<description><![CDATA[Twitter List support has been out for a while now but the impact of this new feature may not be readily apparent to most Twitter users. Yet, Lists have already changed Twitter in dramatic ways that you really need to know about. Twitter Lists are user-created groupings of other Twitter accounts. This is somewhat like [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Ftwitter-lists-changing-everything-about-twitter%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Ftwitter-lists-changing-everything-about-twitter%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Twitter List support has been out for a while now but the impact of this new feature may not be readily apparent to most Twitter users. Yet, Lists have already changed Twitter in dramatic ways that you really need to know about.</p>
<p>Twitter Lists are user-created groupings of other Twitter accounts. This is somewhat like the client-side groups provided by TweetDeck, Seesmic Desktop, FriendFeed and others but since it is built into Twitter itself the impact is far-reaching. The biggest difference between client-side groups and Twitter Lists is that lists are public. User can &#8220;follow&#8221; lists others set up, for example.</p>
<p>Here&#8217;s a quick rundown of how Twitter Lists work. A logged in user can create up to 20 Lists containing 500 users each. The name of the List is up to the user and usually suggests the common trait tying the users together in the mind of the List creator. The list creator is also able to provide a description of the list created. The list can be public (default) or private (seen only by the list creator). <del datetime="2009-12-14T23:32:42+00:00">However, users added to a list can see which list they are on regardless of the public/private setting of the list itself. That means users on a private list know who has listed them and knows the name of the list that they are on.</del> [ed: Thanks to several people who have corrected me - I agree, private lists are private to the list curator and are not seen by those listed. My apologies!]</p>
<div class="wp-caption alignnone" style="width: 490px"><a href="http://twitter.com/rjamestaylor"><img class=" " title="@rjamestaylor home page with count of Lists" src="http://img.skitch.com/20091204-tuw3p7xjbk4ancqqbm4j7mbg9n.png" alt="@rjamestaylor home page with count of Lists" width="480" height="338" /></a><p class="wp-caption-text">@rjamestaylor home page with count of Lists</p></div>
<p>When I log into Twitter I can see that I&#8217;m currently listed on 89 Lists (see above). I can also see the Lists to which I&#8217;m subscribed on the right most column of my Twitter home page.</p>
<div class="wp-caption alignnone" style="width: 288px"><a href="http://twitter.com/rjamestaylor"><img title="Lists @rjamestaylor created or follows" src="http://img.skitch.com/20091204-kmeabiiwna6qd9mgnuccqcnyfj.png" alt="Lists @rjamestaylor created or follows" width="278" height="523" /></a><p class="wp-caption-text">Lists @rjamestaylor created or follows</p></div>
<p>Let&#8217;s create a list! The screencast below demonstrates creating a new list, adding users to the list, viewing the list and deleting the list. (Tip &#8211; watch in full screen mode)</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" height="340" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/Rbs5FT0NWyY&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed wmode="transparent" type="application/x-shockwave-flash" width="560" height="340" src="http://www.youtube.com/v/Rbs5FT0NWyY&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The most obvious benefit of using Twitter Lists is to reduce the clutter in your reviewing of users&#8217; tweets. By segmenting users into lists the &#8220;noise&#8221; of all the twitter users you follow is drastically reduced. But the game changing value of Twitter Lists is more subtle: following lists others make of interesting users.</p>
<h3>Making lists and checking them twice</h3>
<p>Since anyone can make lists of any (non-blocking) Twitter users and share these lists with the Twitter public a new way of discovering interesting users has come to Twitter. The impact is this: those users with special knowledge of other Twitter users can group otherwise unidentifiable users into easy to find categories. For example, if you&#8217;re interested in venture capitalists, you may have tried to find those VCs on Twitter you know of or can find through searching Twitter profiles for their own self-description as a VC. Yet, you may miss some key VCs without special knowledge. Twitter @Scobleizer probably knows more VCs on Twitter than most and he has faithfully created a list of VCs on Twitter: <a href="http://twitter.com/Scobleizer/venture-capitalists" target="_blank">@Scobleizer/venture-capitalists</a>. Now you can easily follow the thoughts, activities and actions (including locations) of the top venture capitalists on Twitter. Needless to say, finding trends among VCs is significantly easier for all of us due to Twitter Lists.</p>
<p>Let&#8217;s take this a step further. Say you are interested in a particular company for reasons such as news reporting, competitive intelligence, investment research, employment research, or even to follow the tweets of your own employees. Previously, finding Twitter users from particular companies relied on the self-reporting of each user. Now those with special knowledge of a company&#8217;s staff can make their own lists. So an employee of a company may not realize they have been listed by others as part of their employer&#8217;s Twitter users. Impact? Your personal intention to separate business from personal life on Twitter is compromised. More over, those companies that make their own list of employees who tweet make it very easy for the public to learn about the culture, sayings and doings of their employees. By having a public list of employees whether self-made or made by others with special insight, researching a company has been simplified. PR departments may think they control the public perception of the internal nature of their companies but Twitter Lists has busted this wide open.</p>
<p>Previously a Twitter user may have been followed by a handful of others. Such a user may have been careful not to related themselves to their employer but by being listed as an employee of their company they have become a de facto spokesperson on their company&#8217;s behalf. This is why I believe Twitter Lists have changed everything about Twitter.</p>
<p>For example, say a company is going into a quiet period required by the SEC. Because of Twitter Lists employees that believe they are speaking independently and privately now may give critical information to investors through tweets like, &#8220;Wow &#8211; just met our new owners &#8211; great company! Can&#8217;t wait until I can talk about this!&#8221; As part of a List of employees this may be an improper disclosure. This is an extreme example, sure, but a real one that could have employment and legal consequences for the employee.</p>
<p>Example two: an airline is facing inquiries from the FAA over possible maintenance violations. An employee not knowingly aggregated with his employer due to being listed on &#8220;Airline-X-engineers&#8221; list tweets, &#8220;finally the chickens are coming home to roost. Shortcuts we&#8217;ve been forced to make are getting exposed.&#8221; Oops.</p>
<p>Example three: a utility company suffers a public-affecting outage. Many people are impacted. Phone lines are jammed, customers are hurting. An unwittingly listed employee tweets, &#8220;Nothing to do at work so we&#8217;re catching up on World of Warcraft.&#8221; How do you think customers would react when the PR department releases a statement that everyone is working hard to recover power to each customer? Perhaps the employee works in accounting for the utility and their department really is at a point when the workers are able to catch a break. Think customers will understand that an accountant isn&#8217;t going to be manning the cherry pickers? Ouch!</p>
<h3>Rethinking Twitter in light of Lists</h3>
<p>Twitter has changed, dramatically, with the introduction of Lists. As a long time Twitter user I see that the former semi-anonymity associated with tweeting was seriously compromised by Twitter Search and practically eliminated due to Twitter Lists. I believe we all need to rethink some previously held assumptions about Twitter.</p>
<ul>
<li>Should I tweet at all?</li>
</ul>
<p>Previously I encouraged everyone to use Twitter. However now more than ever we must realize that tweeting can affect our personal and professional lives. Those with any concern that their tweets could jeopardize their livelihood should seriously consider not tweeting at all.</p>
<p>Those who continue to tweet need to remember that much is on the line with each tweet. Deleting a tweet is not guaranteed to remove it from the Internet (see: <a href="http://www.rjamestaylor.com/once-tweeted-never-deleted-your-reputation-online/" target="_blank">Once Tweeted, Never Deleted</a>). Remembering to ask, &#8220;is this hurtful? Is this helpful?&#8221; before tweeting is necessary now more than ever.</p>
<ul>
<li>I&#8217;m listed as an employee of my employer, what should I do differently?</li>
</ul>
<p>First, make sure to carefully follow SEC and company policies with each tweet. Not sure what those rules are? Better read step one above and find out before continuing to tweet.</p>
<p>Second, before tweeting make sure that your company&#8217;s customers are not suffering on Twitter. How? Search for your company&#8217;s name or brands on Twitter using Twitter search. If your customers are suffering try to reach out to help them or consider not tweeting until the issues are resolved.</p>
<p>Third, remember that your company will be judged in aggregate through the tweets of listed company employees. Proud that your company provides expertise to customers related to technology? How about including relevant links every once in a while, or offering up a simple tip related to some area of your own expertise? That will positively impact not only the public perception of your company but help show you personally are a contributing member of the company to others. Conversely, if your company sells vegan products as its main product offering, tweeting about hunting trips and company outings that include baby backed ribs may have a negative impact on the company and your employment.</p>
<ul>
<li>If I&#8217;m listed without wanting to be, what can I do?</li>
</ul>
<p>Above I show how to tell whether or not you appear on any lists &#8212; check that frequently if you are concerned about which lists you appear. Currently Twitter users can add anyone that is not blocking them to a public or private list of their own choosing. So if you do not want to be on a particular list I recommend first trying to contact the list curator to have you removed. If that does not work, the more extreme step of blocking the list maker will remove you from any list you on which you do not wish to appear. Blocking is considered extreme and even rude, so use this as a last resort.</p>
<ul>
<li>I want to use this new, powerful research tool &#8211; how do I get started?</li>
</ul>
<p>Due to my concern over the average Twitter user I&#8217;ve focused on the worrisome aspects of Lists in this blog post. I care that people not be surprised about the changes to Twitter due to Lists and that&#8217;s my main focus here. However, Lists are powerful for reading as well. The best place I&#8217;ve found to begin exploring Lists is a third-party website specializing in Lists: <a href="http://listorious.com" target="_blank">listorious.com</a>. On Listorious the top lists and list makers are curated and made searchable. Spend some time there to find lists that interest you. Once you find interesting lists and follow them think of the lists you would like to create and start making your own. Do be polite and sensitive to others that you list. Blocking may be considered rude but adding people to a list they do not want to be on can be hazardous to them, personally.</p>
<img style='display:none' id="post-582-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/twitter-lists-changing-everything-about-twitter/',title:'Twitter Lists: Changing Everything about Twitter',tweet:' 			 				 			 		 Twitter List support has been out for a while now but the impact of this new featur',description:' 			 				 			 		 Twitter List support has been out for a while now but the impact of this new featur'})"><script type='text/javascript'>document.getElementById("post-582-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/twitter-lists-changing-everything-about-twitter/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>noVIMber: VIM support for scripting languages</title>
		<link>http://www.rjamestaylor.com/novimber-vim-support-for-scripting-languages/</link>
		<comments>http://www.rjamestaylor.com/novimber-vim-support-for-scripting-languages/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 21:59:29 +0000</pubDate>
		<dc:creator>druzziel</dc:creator>
				<category><![CDATA[Guest Articles]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[guest]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=578</guid>
		<description><![CDATA[Thanks everyone for reading along. I hope you&#8217;ve enjoyed reading these tips as much as I&#8217;ve enjoyed writing them. For the last installment, I wanted to share a very cool feature in VIM that I am just beginning to learn how to use. VIM provides support for Perl, Python and Ruby so that you can [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-vim-support-for-scripting-languages%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-vim-support-for-scripting-languages%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Thanks everyone for reading along.  I hope you&#8217;ve enjoyed reading these<br />
tips as much as I&#8217;ve enjoyed writing them.</p>
<p>For the last installment, I wanted to share a very cool feature in VIM<br />
that I am just beginning to learn how to use.  VIM provides support for<br />
Perl, Python and Ruby so that you can use these languages to create<br />
functions in VIM.</p>
<p>I&#8217;m most familiar with Python myself, so here are a couple of examples.<br />
In VIM, try the following:</p>
<p><code>:python print "Hello world"</code></p>
<p>You&#8217;ll see &#8216;Hello world&#8217; show up in the status line at the bottom of the<br />
screen.  Cool, but not all that handy (though you can use this as a<br />
quick calculator, e.g. :<code>py print 256 * 8</code> ).</p>
<p>To actually get Python to do something interesting with the contents of<br />
your editor, you can define a VIM function that uses Python to do the<br />
heavy lifting.</p>
<p>Here&#8217;s how:<br />
<code>:function! PySort()<br />
python &lt;&lt; EOF<br />
import vim<br />
b = vim.buffers[0]<br />
x = b[:]<br />
x.sort()<br />
b[:] = x<br />
EOF<br />
endfunction</code></p>
<p>The<code> :function!</code> line begins a function definition.  VIM has its own<br />
internal scripting language, which is swell and all, but if you already<br />
have familiarity with one of the other supported languages, you can use<br />
that language to get a jump start on seriously tricking out VIM.</p>
<p>The line:</p>
<p><code>python &lt;&lt; EOF</code></p>
<p>tells VIM that we&#8217;re defining a block of Python code.  The block will<br />
end with the line &#8220;EOF&#8221;.  The enclosed lines are pure Python.</p>
<p>First, we import the vim module:</p>
<p><code>import vim</code></p>
<p>Now we have access to that module&#8217;s components, like the buffers[]<br />
list.  Just like in normal Python, buffers[] is zero-indexed, so<br />
buffers[0] is the first buffer.</p>
<p>Next, we copy the contents of b as a list into the variable x:</p>
<p><code>x = b[:]</code></p>
<p>Then we sort that list alphabetically:</p>
<p><code>x.sort()</code></p>
<p>Then we replace the current buffer with the sorted context of x:</p>
<p><code>b[:] = x</code></p>
<p>And voila &#8211; you can now sort the current buffer alphabetically by<br />
calling the PySort() function:</p>
<p><code>:call PySort()</code></p>
<p>This is just a trivial example, but hopefully it gives you some ideas of<br />
what can be done with Python (or Perl, or Ruby) inside of VIM.</p>
<p>To get more information about using scripts in VIM, try the following<br />
help commands in VIM:</p>
<p><code>:help python-vim</code><br />
<code>:help perl</code><br />
<code>:help perl-using</code><br />
<code>:help ruby-vim</code></p>
<p>Thank you all for reading.  Anyone interested in exploring any of the<br />
topics discussed in this or previous tips should feel free to <a href=http://twitter.com/druzziel>contact me</a>.</p>
<p>Happy VIMming!</p>
<p>- <a href=http://twitter.com/druzziel>David Roth</a></p>
<img style='display:none' id="post-578-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/novimber-vim-support-for-scripting-languages/',title:'noVIMber: VIM support for scripting languages',tweet:' 			 				 			 		 Thanks everyone for reading along.  I hope you&#8217;ve enjoyed reading these tips ',description:' 			 				 			 		 Thanks everyone for reading along.  I hope you&#8217;ve enjoyed reading these tips '})"><script type='text/javascript'>document.getElementById("post-578-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/novimber-vim-support-for-scripting-languages/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>noVIMber: g wiz!</title>
		<link>http://www.rjamestaylor.com/novimber-g-wiz/</link>
		<comments>http://www.rjamestaylor.com/novimber-g-wiz/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 16:40:45 +0000</pubDate>
		<dc:creator>druzziel</dc:creator>
				<category><![CDATA[Guest Articles]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[guest]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=576</guid>
		<description><![CDATA[VIM&#8217;s got a lot of helpful commands that start with g. Not sure why g, of all letters, but there you are. One that I find really helpful when running through Apache configurations is gf. If you put your cursor over the path to a file and type: gf VIM will open up the file [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-g-wiz%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-g-wiz%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>VIM&#8217;s got a lot of helpful commands that start with <code>g</code>.  Not sure why <code>g</code>,<br />
of all letters, but there you are.</p>
<p>One that I find really helpful when running through Apache<br />
configurations is <code>gf</code>.  If you put your cursor over the path to a file<br />
and type:</p>
<p><code>gf</code></p>
<p>VIM will open up the file that&#8217;s under your cursor.  So, given a vhost<br />
like the following:</p>
<p><code>&lt;VirtualHost *:80&gt;<br />
DocumentRoot /var/www/html<br />
ServerName example.com<br />
&lt;/VirtualHost&gt;</code></p>
<p>If you put your cursor over /var/www/html and type <code>gf</code>, VIM will open up<br />
a directory listing of that directory.  Or, if you&#8217;ve piped the output<br />
of <code>httpd -S</code> to a file and you put your cursor over the path to a<br />
particular virtual host&#8217;s configuration file, you can open it up in the<br />
same way.  Note that if you&#8217;ve updated the current file and it hasn&#8217;t<br />
been written to disk yet, VIM will complain that the current file hasn&#8217;t<br />
been saved yet and <code>gf</code> will fail.</p>
<p>Another handy use of <code>g</code> is when you&#8217;re editing a file with wrapped<br />
lines.  Ever find yourself on a line that is wrapped, and you want to<br />
make a change that&#8217;s right below the cursor, so you type <code>j</code> or hit the<br />
down arrow, but the cursor skips right past what you want and goes to<br />
the next line?  Don&#8217;t you just HATE that?  Well, if you type <code>gj</code> or<br />
<code>g&lt;down arrow&gt;</code> instead, the cursor will move according to displayed<br />
lines, not logical lines.  Much better.</p>
<p>Finally, my favorite stupid VIM trick.  <code>g?</code> will ROT-13 text.  Use the<br />
<code>ggVG</code> sequence to highlight your entire file.  Then type:</p>
<p><code>g?</code></p>
<p>And presto &#8211; every alphabetic character is shifted 13 places to the<br />
right in the alphabet.  Quick and easy obfuscation.</p>
<p>Happy VIMming!</p>
<p>- David Roth</p>
<img style='display:none' id="post-576-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/novimber-g-wiz/',title:'noVIMber: g wiz!',tweet:' 			 				 			 		 VIM&#8217;s got a lot of helpful commands that start with g.  Not sure why g, of al',description:' 			 				 			 		 VIM&#8217;s got a lot of helpful commands that start with g.  Not sure why g, of al'})"><script type='text/javascript'>document.getElementById("post-576-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/novimber-g-wiz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>noVIMber: VIM Scripts</title>
		<link>http://www.rjamestaylor.com/novimber-vim-scripts/</link>
		<comments>http://www.rjamestaylor.com/novimber-vim-scripts/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 16:38:20 +0000</pubDate>
		<dc:creator>druzziel</dc:creator>
				<category><![CDATA[Guest Articles]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[guest]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=574</guid>
		<description><![CDATA[We went over creating VIM macros in a previous tip. If you save your macros to a file, you can have VIM run the macro against a file, effectively creating a batch mode for executing VIM macros. Let&#8217;s say that, for whatever reason, you want to convert a file to all lower case. Create a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-vim-scripts%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-vim-scripts%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>We went over creating VIM macros in a previous tip.  If you save your<br />
macros to a file, you can have VIM run the macro against a file,<br />
effectively creating a batch mode for executing VIM macros.</p>
<p>Let&#8217;s say that, for whatever reason, you want to convert a file to all<br />
lower case.  Create a file called lower.vim and put in the following lines:</p>
<p><code>ggVGu</code><br />
<code>:wq!</code></p>
<p>Make sure there are carriage returns at the end of each line.  Those<br />
commands will jump to the first line (<code>gg</code>), turn on visual highlighting<br />
mode (<code>V</code>), then jump to the last line (<code>G</code>).  The &#8216;<code>u</code>&#8216; command at the end of<br />
the first line will translate all highlighted characters to lower case.<br />
Then the next line writes and quits the file.</p>
<p>Now you can apply this script to any file with:</p>
<p><code>vim -s lower.vim /path/to/file</code></p>
<p>Maybe you want to translate all your XML files under the current<br />
directory to lower case.  In that case, you can combine VIM with &#8216;find&#8217;<br />
to do some quick batch processing:</p>
<p><code>find . -type f -name \*.xml -exec vim -s lower.vim {} \;</code></p>
<p>Note that when you use VIM in this way, VIM does not operate in the<br />
background.  An instance of VIM is started for each file being<br />
processed, and the commands in the script file are run like a macro.  If<br />
your script file makes a lot of complicated changes, this can be really<br />
amusing to watch.  I run this on my computer at home instead of having a<br />
fireplace.</p>
<p>Happy VIMming!</p>
<p>- David Roth</p>
<img style='display:none' id="post-574-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/novimber-vim-scripts/',title:'noVIMber: VIM Scripts',tweet:' 			 				 			 		 We went over creating VIM macros in a previous tip.  If you save your macros to a f',description:' 			 				 			 		 We went over creating VIM macros in a previous tip.  If you save your macros to a f'})"><script type='text/javascript'>document.getElementById("post-574-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/novimber-vim-scripts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>noVIMber: Plugin Madness</title>
		<link>http://www.rjamestaylor.com/novimber-plugin-madness/</link>
		<comments>http://www.rjamestaylor.com/novimber-plugin-madness/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 16:35:54 +0000</pubDate>
		<dc:creator>druzziel</dc:creator>
				<category><![CDATA[Guest Articles]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[guest]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=572</guid>
		<description><![CDATA[VIM ships with a number of plugins, which are scripts that enhance VIM&#8217;s basic functionality. You&#8217;ll find the plugins that shipped with your copy of VIM in $VIMRUNTIME/plugin. (Sub-tip: don&#8217;t know where VIM is installed? In vim, type &#8220;:echo $VIMRUNTIME&#8220;.) We talked about syntax highlighting in an earlier tip. Syntax highlighting is great and it [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-plugin-madness%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-plugin-madness%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>VIM ships with a number of plugins, which are scripts that enhance VIM&#8217;s<br />
basic functionality.  You&#8217;ll find the plugins that shipped with your<br />
copy of VIM in $VIMRUNTIME/plugin.</p>
<p>(Sub-tip: don&#8217;t know where VIM is installed?  In vim, type &#8220;<code>:echo<br />
$VIMRUNTIME</code>&#8220;.)</p>
<p>We talked about syntax highlighting in an earlier tip.  Syntax<br />
highlighting is great and it makes code more readable, but if you take<br />
your text file that&#8217;s all fancy in VIM and publish it on a web page<br />
somewhere, it goes back to dreary black text.</p>
<p>But it doesn&#8217;t have to.  With a syntax-highlighted file open, type:</p>
<p><code>ggVG</code></p>
<p>(that highlights the entire file)</p>
<p><code>:TOhtml</code></p>
<p>(that creates an HTML document of your highlighted file)</p>
<p>Cool, huh?</p>
<p>Another fun pair of plugins are gzip.vim and tarPlugin.vim.  These are<br />
great because you don&#8217;t have to do anything to activate them &#8211; just use<br />
VIM to open a .gz or .tar file (or, for that matter, a .tar.gz file).<br />
VIM will uncompress your gzipped file on the fly and re-compress it when<br />
you&#8217;re done editing it.  If you&#8217;re opening up a .tar file, VIM will give<br />
you a list of the files in the tarball.</p>
<p>Happy VIMming!</p>
<p>- David Roth</p>
<img style='display:none' id="post-572-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/novimber-plugin-madness/',title:'noVIMber: Plugin Madness',tweet:' 			 				 			 		 VIM ships with a number of plugins, which are scripts that enhance VIM&#8217;s basi',description:' 			 				 			 		 VIM ships with a number of plugins, which are scripts that enhance VIM&#8217;s basi'})"><script type='text/javascript'>document.getElementById("post-572-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/novimber-plugin-madness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>noVIMber: Automating tasks with VIM</title>
		<link>http://www.rjamestaylor.com/novimber-automating-tasks-with-vim/</link>
		<comments>http://www.rjamestaylor.com/novimber-automating-tasks-with-vim/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 16:34:50 +0000</pubDate>
		<dc:creator>druzziel</dc:creator>
				<category><![CDATA[Guest Articles]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[guest]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=570</guid>
		<description><![CDATA[VIM has a bunch of built-in event handlers which can be used to automate certain tasks. These are known as autocommands. You can define actions that get executed whenever one of these autocommands is fired to do things like read in a template file or write a note to a log file. In today&#8217;s tip, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-automating-tasks-with-vim%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-automating-tasks-with-vim%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>VIM has a bunch of built-in event handlers which can be used to automate<br />
certain tasks.  These are known as autocommands.  You can define actions<br />
that get executed whenever one of these autocommands is fired to do<br />
things like read in a template file or write a note to a log file.  In<br />
today&#8217;s tip, I&#8217;m going to show you how to use template files for certain<br />
file types.</p>
<p>Let&#8217;s say you write a lot of HTML code, and you always find yourself<br />
creating the following structure:</p>
<p>&lt;HTML&gt;<br />
&lt;HEAD&gt;&lt;TITLE&gt;&lt;/TITLE&gt;&lt;/HEAD&gt;<br />
&lt;BODY&gt;</p>
<p>&lt;/BODY&gt;<br />
&lt;/HTML&gt;</p>
<p>Instead of having to type that every single time you create a new .html<br />
file, you can write that structure into a template file.  In your home<br />
directory, there should be a .vim directory.  If there isn&#8217;t go ahead<br />
and create one, then create a directory called templates and write your<br />
template file under the name html.tpl.</p>
<p>Now, add the following line to your .vimrc:</p>
<p><code>:autocmd BufNewFile *.html 0r ~/.vim/templates/html.tpl</code></p>
<p>That line tells VIM that you&#8217;re defining a new autocommand that is to be<br />
executed when the BufNewFile action is triggered.  BufNewFile gets<br />
triggered every time a new file is created in vim.  In this case, if the<br />
new file&#8217;s name matches the pattern &#8220;*.html&#8221;, it&#8217;s going to read in the<br />
contents of ~/.vim/templates.html.tpl.  So now, if you type:</p>
<p><code>vim brandnewfile.html</code></p>
<p>VIM is going to create the new file and read in the contents of your<br />
HTML template.</p>
<p>One note about this tip &#8211; I have no idea what the 0 in &#8220;0r&#8221; is for.  If<br />
anyone knows why the zero is needed, please let me know.</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.571em; margin-left: 0px; padding: 0px;">Happy VIMming!</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.571em; margin-left: 0px; padding: 0px;">- David Roth</p>
<img style='display:none' id="post-570-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/novimber-automating-tasks-with-vim/',title:'noVIMber: Automating tasks with VIM',tweet:' 			 				 			 		 VIM has a bunch of built-in event handlers which can be used to automate certain ta',description:' 			 				 			 		 VIM has a bunch of built-in event handlers which can be used to automate certain ta'})"><script type='text/javascript'>document.getElementById("post-570-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/novimber-automating-tasks-with-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>noVIMber: Seeing the unseeable with VIM</title>
		<link>http://www.rjamestaylor.com/novimber-seeing-the-unseeable-with-vim/</link>
		<comments>http://www.rjamestaylor.com/novimber-seeing-the-unseeable-with-vim/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 22:51:00 +0000</pubDate>
		<dc:creator>druzziel</dc:creator>
				<category><![CDATA[Guest Articles]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[guest]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.rjamestaylor.com/?p=566</guid>
		<description><![CDATA[This is why ninjas are scared of VIM &#8211; it allows you to see that which cannot be seen.  This is a trick that I learned when editing a lot of Python code in a massive project.  As you may or may not know, in Python, whitespace is syntactically significant.  Indented lines are used to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-seeing-the-unseeable-with-vim%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.rjamestaylor.com%2Fnovimber-seeing-the-unseeable-with-vim%2F&amp;source=rjamestaylor&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>This is why ninjas are scared of VIM &#8211; it allows you to see that which<br />
cannot be seen.  This is a trick that I learned when editing a lot of<br />
Python code in a massive project.  As you may or may not know,<br />
in Python, whitespace is syntactically significant.  Indented lines are<br />
used to indicate the bodies of functions, classes, and loops.  Problems<br />
can arise when bothspaces and tabs are used for indentation, because<br />
Python doesn&#8217;t necessarily consider eight spaces to be the equivalent<br />
of two tabs, even though they may look the same to a human eye.</p>
<p>So when you have a file open in VIM and you want to view non-printing<br />
characters, you can turn on list mode to see non-printing characters:</p>
<p><code>:se list</code></p>
<p>With list mode enabled, tabs will appear as <code>^I</code>, carriage returns will<br />
appear as <code>^M</code>, etc.  To turn list mode off, type:</p>
<p><code>:se nolist</code></p>
<p>If you see a character and you&#8217;re not sure what it is, you can use<br />
another couple of tricks to view the ASCII value of the character.  Put<br />
your cursor on top of it and type:</p>
<p><code>ga</code></p>
<p>(Think &#8220;get ASCII&#8221;).  If you&#8217;re editing a UTF-8 file, the command is:</p>
<p><code>g8</code></p>
<p>Then you can look up the value at <a href="http://www.asciitable.com/">http://www.asciitable.com/</a> or<br />
<a href="http://www.utf8-chartable.de/">http://www.utf8-chartable.de/</a> to see what it is. (Unless you&#8217;ve memorized the ASCII and UTF-8 tables, in which case you&#8217;re probably an emacs user and not interested in these VIM tips anyway.)</p>
<p>Happy VIMming!</p>
<p>- David Roth</p>
<img style='display:none' id="post-566-blankimage" onload="Meebo('discoverSharable', {element: ((this.parentNode.className.match('post')) ? this.parentNode : this.parentNode.parentNode) ,url:'http://www.rjamestaylor.com/novimber-seeing-the-unseeable-with-vim/',title:'noVIMber: Seeing the unseeable with VIM',tweet:' 			 				 			 		 This is why ninjas are scared of VIM &#8211; it allows you to see that which cannot',description:' 			 				 			 		 This is why ninjas are scared of VIM &#8211; it allows you to see that which cannot'})"><script type='text/javascript'>document.getElementById("post-566-blankimage").onload();</script>]]></content:encoded>
			<wfw:commentRss>http://www.rjamestaylor.com/novimber-seeing-the-unseeable-with-vim/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
