Friday 8 August 2008

jEdit for Ruby on Rails

jEdit is a mature programmer's (the editor, not necessarily the programmer) text editor with hundreds (counting the time developing plugins) of person-years of development behind it.

Caveat: I wrote this article about one and a half years ago (before i even had this blog) and then lost the file. I just dug it up almost accidentally, and so am posting it now because jEdit development moves along fairly slowly, and the information is probably still useful. please tell me in the comments, if something wrong or no longer current. i'll try to update the blog post, but can't test anything out as i'm no longer on jEdit.

What's nice about jEdit




  • Written in Java, so it runs on Mac OS X, OS/2, Unix, VMS and Windows.


  • Built-in macro language; extensible plugin architecture. Dozens of macros
    and plugins available.

  • Auto indent, and syntax highlighting for more than 130 languages.

  • Supports a large number of character encodings including UTF8 and Unicode.

  • Folding for selectively hiding regions of text.

  • Highly configurable and customizable.

  • Every other feature, both basic and advanced, you would expect to find in
    a text editor. See a full list of features.

  • Scriptable in Ruby!!

  • Lighter weight than most other Java based editors.


Installation



I am was running Ubuntu Edgy so this section details my experiences installing jEdit on that platform. This is the only platform specific section in this tutorial (and is also probably hopelessly out of date). If you are running some other system check out the jEdit download page for details. Disclaimer: I am by no means an Ubuntu expert so this information may be completely off.

First you need Java. You need to have sun-java5-jre installed, which is in ubuntu multiverse. You also want to make sure that you have java in your path. Edgy has a symbolic link chain which goes /usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-1.5.0-sun/jre/bin/java which you should make sure is intact. Mine got screwed up (i think) when I was experimenting with sun-java6-jre. Incidentally sun-java6-jre causes an invalid pointer exception when you try to load a project in jEdit's project viewer plugin, so avoid it.

Then download the 'Java-based installer' (jedit42install.jar) file from the jEdit download page. Make sure it is version 4.2 final, because some ruby support is broken in the latest development releases.

Install it:

$ sudo java -jar jedit42install.jar

And run it:

$ jedit

The Plugins



jEdit should now be running. Go to Plugins->Plugin Manager, click on the Install tab, and now click Download Options. Update the mirror list and then choose a mirror, the default one never seems to work. Now check and install the following plugins:

Console

Allows you to interact with your rails app in a shell right in jEdit

IRC

Talk to other railers on IRC without leaving jEdit

Project Viwer

Gives you a view of your project filesytem. Required by the RubyPlugin but for some reason is not included in that plugin's dependencies so you have to manually select it

Ruby Plugin

Does a whole lot of good ruby stuff.

SideKick

Gives you a birds eye view of your file structure (classes methds etc), which also works for many other languages including html. It is also involved in parsing your ruby code, catching error, autocompletion, etc.

SuperAbbrevs

Allows TextMate like snippets

XML

XML, HTML, CSS and Javascript tools

SuperScript

Allows you to script jEdit in Ruby amongst other languages

Macro Manager

An easy way to download and manage macros


So lets put some of these plugins to good use. Go to Plugins->Project Viewer->Show Project Viewer. Now in the window that pops up there is a triangle at the top left. Click that to dock it in jEdit's main window. Once you've docked it, click the hard drive looking thingy (or right click the 'All Projects' folder to add a new rails project.

Now go to Plugins->Plugin Options and under Sideckick->Parsers make sure that mode ruby also has parser set to ruby. Now go to Plugins->Ruby Plugin->Structure Browser and doc the window that pops up in the main window. I usually doc it on the opposite side of the project viewer so i can see both at once. Note that the structure browser is the Sidekick structure browser and will work for other languages as well. Open a ruby file from your rails project and you can see the structure browser at work.

Have a goof around later with the plugins we just downloaded. And also with the many we haven't yet because there are some real gems in there.

Setting Key Bindings



For the sections that follow you'll need to know how to set key bindings. jEdit calls them 'shortcuts'.

To set a shortcut go to Utilities->Global Options, and then under Shortcuts set Edit Shorcuts to Built-in Commands, Macros, or your choice of Plugin. Once you have chosen one, you will see a list of the possible commands to bind for that category. Just click on one of the primary or alternative shortcut fields to enter key for a command. If you are over-writing another command you will be warned before it is saved.

Editing Modes



The ruby editing mode that comes default with jEdit aint that great so let's upgrade it. Go pick up the latest greatest (v0.6) jEdit ruby editing mode. There is a small download link, right click it and save file as ruby.xml. Don't just left click on it, it'll confuse you, it did me.

Once you have it put it in ~/.jedit/modes and then edit the ~/.jedit/modes/catalog file and add the following mode entry:
<MODE NAME="ruby" FILE="ruby.xml" FILE_NAME_GLOB="*.{rb,rbw}"
FIRST_LINE_GLOB="#!*/*ruby*" />

Your ruby editing should now be a whole lot prettier. You should see the effects immediately by the way, just close and reopen the ruby file you've been toying with.

Some other modes of interest and their catalog entries:

yaml

<MODE NAME="yaml" FILE="yaml.xml" 
FILE_NAME_GLOB="*.{yml,yaml}" />

haml

<MODE NAME="haml" FILE="haml.xml" 
FILE_NAME_GLOB="*.haml" />

rdoc

<MODE NAME="ruby" FILE="ruby.xml" 
FILE_NAME_GLOB="*.{rb,rbw}" FIRST_LINE_GLOB="#!*/*ruby*" />


Macros



Open related file

This macro lets you easily jump between models, controllers, etc. of the same base name. I don't think it's possible to install this one via. MacroManager so you'll need to get it off the web.

Download the open related file macro and place the decompressed folder under ~/.jedit/macros. Then do Macros->Rescan Macros and there should now be a Rails entry.

I like to set this binding to CS+o (Control Shift o)

Go To Ruby Method

Brings up a popup menu of Ruby methods that are in the current buffer grouped by class and ordered alphabeticaly. Selecting a class or method from the menu places the caret at that member's location in the file. I like to set this binding to CS+m (Control Shift m)

Redundant Macros

A few macros have been added to the RubyPlugin and so are now redundant, namely: 'Search Ruby Documentation using ri', and 'Auto indent and insert end'



SuperAbbrevs, Snippets for jEedit



You've probably seen the DHH screencasts where he is hardly typing anything and code is just appearing magically all over the place. The SuperAbbrevs plugin allows you to do just that using abbreviations.

You can get a nice set of 'Snippets' here. There is also a reference to the same here. There is a great tutorial on what they are and how to use them here.
I personally like just using Tab to expand so I didn't follow his advice on C+Enter.

Tips on writing abbrevs for ruby



Try to keep your abbrevs generic and rubyish. For instance the default 'for' abbrev for ruby is of this form (from memory because i changed it, so it may not be exactly this):

for ${1:i} in 0..${2:to} do
$end
end

Which is a fairly C way of thinking of a for loop. A more generic or polymorphic way of writing this while also keeping in mind that tab is also good for moving out of the body of a block, might be written thusly:

for $1 in $2
$end
end

Simpler, and more flexible.

Polishing Up



You are never going to have to type another 'end' again. Set a key binding to the RubyPlugin command 'Auto indent and insert end'. You should set the primary shortcut to 'Enter'. Don't worry about the fact that you are overriding the built in command, it won't break anything. Now try typing up a quick class and a few method defs, and while you're at it a couple control structures too.

In ruby we don't like big tabs. Go to Utilities->Global Options and in the left pane choose Editing. Here you can set your tab width and indent width, and set soft tabbing which means when you hit tab it will insert space characters instead. I usually set tab width and indent width to 2, and check soft tabbing as well. Haml likes two space 'tabs' as well.

It would be nice if we could collapse methods classes etc in order to make the file easier to look at in certain circumstances. jEdit does indeed implement code folding, let's enable it for ruby. Go to Utilities->Global Options and then under Editing set 'change settings for mode' to ruby, make sure that 'Use default settings' is unchecked and then set 'Folding mode' to Sidekick. You should now have collapsable ruby code in your edit buffer.

RubyPlugin and SideKick work together to give you code completion features. If you go to Plugins->Plugin Options and then SideKick you can tweek these settings. If you are like me and you hate stuff popping up all over the place without your asking for it then uncheck 'Show completion popups where possible'. If you want to still be able to request completions on demand set a key binding for the 'Complete code' command of the RubyPlugin. You should leave 'Immediately complete if possible' checked as it generally doesn't get in the way and is quite useful in some modes.

One last very useful couple keybings to set are the XML plugin's 'Characters to Entities' and 'Entities to Characters' commands. I like to set these to CS+x CS+c and CS+x CS+e respectively.

Conclusion



As you can see with all the bells and whistles installed Jedit is a powerful Ruby and Rails editor. Jedit, it should be noted, is also a great editor for many other languages including the usual web lineup. I hope that this guide has eased your entry into the Ruby on Jedit world. Thanks to the very many authors, both of software, docs, and blogs who have made this document possible.

Friday 1 August 2008

gem_server & lingon on os x leopard

hi folks. been gone for a while, but an intercontinental house move followed by a switch of operating systems can take its toll. i hope to be posting a little bit more regularly from now on.

gem_server for those not in the know is a small http server which displays which ruby gems you have installed, as well as their documentation. you may have noticed that gem_server is not installed by default on os x leopard (i'm running 10.5.3). you don't need it though because you can now just write:

$ gem server

to get it to start up automatically when you log in, just download a great little app for writing launchd plists called lingon.

once you have that installed just start'er up and hit the '+' sign at the top left. choose 'my agents' (or one of the other options if you prefer).



then under 'Name' write:

com.yourname.gem_server

and under 'What', write (note the space):

gem server

then make sure that 'Enabled' and 'Run it when it is loaded by the system' are both checked (if you click on the pic above you can see a more detailed screenshot). hit save, give your password, and then log off, back on, and in your browser go to:

http://localhost:8808/

and voila!

Monday 19 November 2007

generating prettier rdoc

If you've ever looked at the rails documentation you may have wondered how DHH and crew generated it. I find it a lot prettier to look at than vanilla rdoc. It turns out that you can quite easily change the template used by rdoc.

To get the rails api look, just download the jamis rdoc template, courtesy of Jamis Buck. Copy it into your rdoc html templates directory, which on my Ubuntu system sits at /usr/lib/ruby/1.8/rdoc/generators/template/html/. Then pass '--template=jamis' to rdoc and you're good to go.

Another template of note is allison, which comes packaged as a gem, and is not installed directly with the other templates. It is a bit annoying when you are writing a rake file because you must spell out the entire path to the template to get it to load.

Note that if you use rake's rdoc task you must use the template method of the task object to set it, you cannot add '--template' to the rdoc options it won't work for some reason. I wasted a good 15 minutes figuring that one out.

Below are all the templates i know of. Those marked with * are not included by default. If you know of any other nice templates out there, please let me know and I'll add them to the list.


html

the default template we know and, well, just live with.




hefss

similar in layout to the jamis template but using a rather unwieldy fourth frame for the main content, and (imho) nowhere near as pretty



kilmer

this one is layed out just like jamis, but is a bit lighter weight




old_html

just like regular html but with a lighter color scheme. i almost like it better than the standard html template




jamis*

a nice template used by rails, rake, and a host of other projects online



allison*

another nice one which, refreshingly, has no frames




one_page_html

this one doesn't even work for me, i get

Generating HTML...
rake aborted!
uninitialized constant RDoc::Page::STYLE




As you can see there are quite a few templates to choose from. It would be nice if there were some standardized way of packaging and distributing them though, maybe even with a web based repository that users could submit to. I'd also like to be able to include the template which i want used when the rdoc for a gem is automatically generated, something which i don't think is possible at the moment? Maybe some of you out there know how to do this. Hope I've been of some help, cheers and happy hacking.

Saturday 3 November 2007

Advanced Ruby Tips And Tricks, Part 1

Welcome to this first installment of Advanced Ruby Tips and Tricks. In this little series I plan on covering anything ruby which goes beyond writing basic classes and methods; topics like meta-programming, runtime callbacks, closures and continuations. Doubtless for some of you none of these topics will seem particularly advanced, but that's because you're already advanced :) So here goes...

Problem


You are designing an API. You want to include some small class which has dependencies the rest of your library does not have, and whose use is only optional, but you don't want the end user to have to require the files manually.

Solution

class XMLTracer

def self.new
puts "loading..."
require 'rubygems'
require 'builder'
rescue LoadError
raise LoadError, "must have builder installed..."
else
def self.new
puts "new is the new new"
super
end
new
end

def initialize
@xml = Builder::XmlMarkup.new(
:target => STDOUT,
:indent => 2
)
end

def identity
@xml.instruct!
@xml.comment! "Crepuscular Homunculus :: " +
"Advanced Ruby Tips and Tricks, Part 1"
@xml.class do |c|
c.name self.class.name
c.id object_id
end
end

end

x1 = XMLTracer.new
x2 = XMLTracer.new
puts
x1.identity
x2.identity
Which Outputs

loading...
new is the new new
new is the new new

<?xml version="1.0" encoding="UTF-8"?>
<!-- Crepuscular Homunculus :: Advanced Ruby Tips and Tricks, Part 1 -->
<class>
<name>XMLTracer</name>
<id>-607742088</id>
</class>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Crepuscular Homunculus :: Advanced Ruby Tips and Tricks, Part 1 -->
<class>
<name>XMLTracer</name>
<id>-607742198</id>
</class>


Walkthrough



The first odd thing you might notice, which you don't see in the wild that often, is that the body of our self.new method contains a rescue and else clause. This is possible because method bodies implicitly are begin end blocks.

The other slightly odd thing if you're coming from more static languages is that the require statements are actually just methods and so can be called dynamically at runtime. What we are doing here is calling require only if the end-user creates a new instance of our XMLTracer class. If for some reason the requires fail, we'll catch and rethrow the load error.


def self.new
require 'rubygems'
require 'builder'
rescue LoadError
raise LoadError, "must have builder installed, blah blah blah"


Here is where it starts to get interesting. The code after the else clause is only run if no exceptions are thrown, so we know that builder has been successfully loaded. At this point we could just call super because require is smart enough not to reload previously loaded files, but that represents some unnecessary overhead every time a new XMLTracer is instantiated.


else
def self.new
puts "new is the new new"
super
end
new
end


Ruby's dynamic nature means that methods can be re-bound at runtime, so we redefine the new method to just call super, and then we call it explicitly to return a new instance. But from then on calling XMLTracer.new will not attempt to require anything. Which you can see in the output, where "loading..." is written only once.

Well, that wraps up this first installment of ARTT. Hope it has been of some use to you. If you have any suggestions/requests for future articles, please let them be known through the comments.

cheers, and happy hacking!

Tuesday 23 October 2007

Gedit for Ruby (and everything else) on Gutsy, or No you don't need that Mac Mini.

You can find many blog posts online about turning Gedit, Ubuntu's default text editor, into a Textmate clone.

Unfortunately most of these posts no longer apply, because Gedit is now even better than before, as Gutsy Gibbon is now shipping with a new and improved version based on the GTKSourceView2 widget, which allows for context sensitive syntax highlighting, and big speed improvements, amongst other things.

The first thing you'll want to do is use your favorite package management front-end and install the gedit-plugins package, which includes a few extra plugins. Then go here, and follow his instructions on installing the mime types and lang files. He also has a few snippets, and other tips which are quite up to date. If you are running rails 2.0 you'll also want to edit his mime types file and add a couple of glob entries to handle the new view naming scheme.

<mime-type type="text/rhtml">
<sub-class-of type="text/html">
<comment>RHTML Template</comment>
<glob pattern="*.rhtml"/>
<glob pattern="*.erb"/>
</mime-type>

<mime-type type="application/x-ruby">
<comment>Ruby XML Template</comment>
<glob pattern="*.rxml"/>
<glob pattern="*.builder"/>
</mime-type>

You can find many more snippets here, and in case you don't understand Spanish, here are the files. You will only want to use his snippets and discard the rest though. Place them in '.gnome2/gedit/snippets'. There are other snippets around the web if you just google a bit. You'll probably end up customizing them a lot, i did. Also be sure to download the textmate-like syntax highlighting style. Place all downloaded styles in '/usr/share/gtksourceview-2.0/styles'.


Now just open up 'Applications->Accessories->Text Editor' and then in Gedit, 'Edit->Preferences' and check all options under View.



Then under Editor set your tab prefs, I like a width of 2 and I also check insert spaces instead of tabs, and enable automatic indentation.



Under 'Fonts and Colors' you might want to enable Darkmate or Oblivion. You can also download the monaco font used on apple, but remember that much of what he says in the post no longer applies, so tread carefuly.

Then under plugins be sure to activate: Bracket Completion, Embedded Terminal, External Tools, File Browser Pane, and Snippets. There is a Gemini plugin out there which does kind of what Bracket Completion does but I prefer the latter. You might also want to check out Session Saver, Class Browser, and Snap Open plugins. Check out this list of Gedit plugins.

You should now be good to go! A big heads up to Joselo, and Robert from Nationcode and Insane Terminology respectively, and Luigi for the textmate theme!