Posted by Jim Morris
Thu, 31 May 2007 20:27:00 GMT
I have been using JEdit more and more for my rails development, I have
gone back and forth between it and Epsilon, however JEdit is starting
to win out. I have upgraded to the latest pre version (4.3pre9).
I have modified a number of macros to do my bidding, and I dumped the
Ruby Plugin because I kept running into things it did that I disliked,
and it still seems a little buggy.
The best thing I did was update the ruby.xml Language mode to fully
indent properly, like unindent end else rescue etc, and do this when
you type those words. This is now possible with some new features in
the 4.3pre9 series.
I also wrote a HAML language mode.
The plugins I currently use are...
- Buffer Selector
- BufferTabs
- Common Controls
- Console
- CssEditor
- CtagsSideKick
- ErrorList
- Highlight
- Info Viewer
- Latest Version
- Log Viewer
- MacroManager
- OpenIt
- Project Viewer
- QuickNotepad
- RecentBufferSwitcher
- SideKick
- SuperAbbrevs
- SwitchBuffer
- Tags
- TextTools
- XercesPlugin
The macros I have downloaded, modified or written to help with rails development
are...
- Expand_Hash.bsh - My macro to expand # to #{} when in a string
- Go_to_Ruby_method_v0.5.bsh - Downloaded from the macromanager
- Open_Related_File.bsh - Downloaded from the macromanager
- Search_Ruby_documentation - A modified version of the one I
downloaded, modified to use qri, and select from a list if multiple hits
- Run_Test_Case.bsh - My macro to run a specific test case or
specification. Bind it to a key (I use Shift-F11), put the cursor in a test case or specification and type the shortcut, and that specific test case will run, the results going to the console plugin.
- Select_Super_Abbrevs.bsh - My macro to select from a list of matching
SupperAbbrevs
- Find_Next_Selected.bsh - Downloaded from the macromanager
I have linked the ones I have written or modified so you can download
them if you like.
Read more...
Posted in Rails, JEdit | Tags editor, jedit, macros, rails | 4 comments | no trackbacks
Posted by Jim Morris
Sat, 02 Dec 2006 02:09:00 GMT
I've just started a new RoR project and thought I'd try out
HAML for the views instead of rhtml.
Seeing as I just switched to JEdit, I looked for a HAML language mode,
and to my surprise no one had done one yet.
So here is my first attempt at a language mode for JEdit and version
1.0 of the HAML language mode. It needs more work, and I hope someone
with a better understanding of JEdit language modes will help out.
This will set the indent to 2 spaces and auto-indent after a %tag that
has nothing else on the line...
%p
stuff
It will not auto indent if there is more stuff on the line like in the
following example the line after %p gets indented but the line
after %label does not.
%p
%label{ :for => "login" }Login
%br/
= f.text_field :login
I have setup a basic syntax coloring scheme that should color %tags
and .classes and #ids differently. It will color anything
following an = or ~ and defer the syntax highlighting to the ruby
mode for anything following them, ditto for anything inside { }.
Feedback and better ideas are welcome.
Download from here
To install copy the file to ~/.jedit/modes, and edit the catalog file
in that directory and add this line:
<MODE NAME="haml" FILE="haml.xml" FILE_NAME_GLOB="*.haml" />
Then restart jedit, and your haml files will be syntax highlighted.
I like HAML but there simply is not enough example code out there
yet, so here are two simple conversions from well know rhtml files
into HAML...
First the standard login form from acts_as_authenticated
- form_tag sessions_path do
%p
%label{ :for => "login"} Login
%br/
= text_field_tag 'login'
%p
%label{ :for => "password" }Password
%br/
= password_field_tag 'password'
%p
%label{ :for => "remember_me" }Remember me:
= check_box_tag 'remember_me'
%p
= submit_tag 'Log in'
Next the new user form from the same place...
= error_messages_for :user
- form_for :user, :url => users_path do |f|
%p
%label{ :for => "login" }Login
%br/
= f.text_field :login
%p
%label{ :for => "email" }Email
%br/
= f.text_field :email
%p
%label{ :for => "password" }Password
%br/
= f.password_field :password
%p
%label{ :for => "password_confirmation" } Confirm Password
%br/
= f.password_field :password_confirmation
%p
= submit_tag 'Sign up'
If this is dumb HAML coding please let me know how to improve it :)
Posted in Rails, HAML, JEdit | Tags haml, jedit, rails | 4 comments | no trackbacks
Posted by Jim Morris
Sat, 25 Nov 2006 03:05:00 GMT
I imported the rest of the Textmate ruby and rails snippets I had to combine them
into the one ruby file though.
I have added about 80 new ones to the existing ones by Scott Becker
that I found here
The list of snippets I now have is at the end of this post, note I did change the
abbreviation for some of the assertions they all now start with as so
I can search for them faster with my select_superabbrevs macro
described in the previous post.
download the new snippets from here
unzip and replace the ruby file in the .jedit/SuperAbbrevs directory with the one in
this zip archive.
You need the Beta version of SuperAbbrevs to use this from here
Super Abbreviations for the ruby mode
--------------------------------------- : --------------------------------------
:${1:key} => ${2:"value"}$end
-------------------------------------- all -------------------------------------
all? { |${1:e}| $end }
-------------------------------------- am --------------------------------------
alias_method :${1:new_name}, :${2:old_name}
-------------------------------------- any -------------------------------------
any? { |${1:e}| $end }
-------------------------------------- app -------------------------------------
if __FILE__ == \$PROGRAM_NAME
$end
end
-------------------------------------- ase -------------------------------------
assert_equal ${1:value}, @${2:thing}.${3:attr}$end
------------------------------------- asid -------------------------------------
assert_in_delta(${1:expected_float}, ${2:actual_float}, ${3:2 ** -20})
------------------------------------- asio -------------------------------------
assert_instance_of(${1:ExpectedClass}, ${2:actual_instance})$end
------------------------------------- asko -------------------------------------
assert_kind_of ${1:Class}, @${2:thing}$end
-------------------------------------- asm -------------------------------------
assert_match(/${1:expected_pattern}/, ${2:actual_string})
-------------------------------------- asn -------------------------------------
assert_nil(${1:instance})$end
------------------------------------- asne -------------------------------------
assert_not_equal(${1:unexpected}, ${2:actual})
------------------------------------- asnm -------------------------------------
assert_no_match(/${1:unexpected_pattern}/, ${2:actual_string})
------------------------------------- asnn -------------------------------------
assert_not_nil ${1:true}$end
------------------------------------- asnr -------------------------------------
assert_nothing_raised(${1:Exception}) { $end }
------------------------------------- asns -------------------------------------
assert_not_same(${1:unexpected}, ${2:actual})$end
------------------------------------- asnt -------------------------------------
assert_nothing_thrown { $end }
-------------------------------------- aso -------------------------------------
assert_operator(${1:left}, :${2:operator}, ${3:right})
-------------------------------------- asr -------------------------------------
assert_raise(${1:ActiveRecord::RecordNotFound}) { ${2:Class}.find(@${3:thing}.${4:id}) }$end
------------------------------------- asrar ------------------------------------
assert_raise(${1:ActiveRecord::RecordNotFound}) { ${2:Class}.find(@${3:thing}.${4:id}) }
------------------------------------- asre -------------------------------------
assert_response :${1:success}$end
------------------------------------- asrt -------------------------------------
assert_redirected_to :action => "${1:index}"$end
-------------------------------------- ass -------------------------------------
assert(${1:test}, "${2:Failure message.}")
------------------------------------- assm -------------------------------------
assert_same(${1:expected}, ${2:actual})$end
-------------------------------------- ast -------------------------------------
assert_throws(:${1:expected}) { $end }
-------------------------------------- bt --------------------------------------
belongs_to :${1:object}, :class_name => "${2:ClassName}", :foreign_key => "${3:foreign_key}_id"$end
------------------------------------- case -------------------------------------
case ${1:object}
when ${2:condition}
$end
end
-------------------------------------- cl --------------------------------------
classify { |${1:e}| $end }
------------------------------------- clafn ------------------------------------
split("::").inject(Object) { |par, const| par.const_get(const) }
------------------------------------- class ------------------------------------
class ${1:ClassName}
$end
end
-------------------------------------- col -------------------------------------
collect { |${1:e}| $end }
------------------------------------ collect -----------------------------------
collect { |${1:element}| ${1:element}.$2 }$end
------------------------------------- Comp -------------------------------------
include Comparable
def <=>(other)
$end
end
-------------------------------------- dee -------------------------------------
Marshal.load(Marshal.dump(${1:obj_to_copy}))
-------------------------------------- def -------------------------------------
def ${1:method_name}
$end
end
------------------------------------- defd -------------------------------------
def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}
------------------------------------- defds ------------------------------------
def_delegators :${1:@del_obj}, :${2:del_methods}
------------------------------------- defs -------------------------------------
def self.${1:class_method_name}
$end
end
------------------------------------- deft -------------------------------------
def test_${1:case_name}
$end
end
-------------------------------------- det -------------------------------------
detect { |${1:e}| $end }
-------------------------------------- do --------------------------------------
do
$end
end
-------------------------------------- doo -------------------------------------
do |${1:object}|
$end
end
-------------------------------------- ea --------------------------------------
each { |${1:e}| $end }
-------------------------------------- eab -------------------------------------
each_byte { |${1:byte}| $end }
-------------------------------------- eac -------------------------------------
each_char { |${1:chr}| $end }
------------------------------------- each -------------------------------------
each { |${1:element}| ${1:element}.$end }
-------------------------------- each_with_index -------------------------------
each_with_index { |${1:element}, ${2:idx}| ${1:element}.$end }
-------------------------------------- eai -------------------------------------
each_index { |${1:i}| $end }
-------------------------------------- eak -------------------------------------
each_key { |${1:key}| $end }
-------------------------------------- eal -------------------------------------
each_line$1 { |${2:line}| $end }
-------------------------------------- eap -------------------------------------
each_pair { |${1:name}, ${2:val}| $end }
------------------------------------- easl -------------------------------------
each_slice(${1:2}) { |${2:group}| $end }
-------------------------------------- eav -------------------------------------
each_value { |${1:val}| $end }
------------------------------------- eawi -------------------------------------
each_with_index { |${1:e}, ${2:i}| $end }
------------------------------------- Enum -------------------------------------
include Enumerable
def each(&block)
$end
end
-------------------------------------- fin -------------------------------------
find { |${1:e}| $end }
------------------------------------- fina -------------------------------------
find_all { |${1:e}| $end }
-------------------------------------- fl --------------------------------------
flunk("${1:Failure message.}")
------------------------------------- flao -------------------------------------
inject(Array.new) { |${1:arr}, ${2:a}| ${1:arr}.push(*${2:a}) }
------------------------------------- flash ------------------------------------
flash[:${1:notice}] = "${2:Successfully created...}"$end
------------------------------------- forin ------------------------------------
for ${1:element} in ${2:collection}
${1:element}.$3
end$end
------------------------------------- Forw -------------------------------------
extend Forwardable
-------------------------------------- gre -------------------------------------
grep(${1:/${2:pattern}/}) { |${3:match}| $end }
------------------------------------- Hash -------------------------------------
Hash.new { |${1:hash}, ${2:key}| ${1:hash}[${2:key}] = $end }
-------------------------------------- hm --------------------------------------
has_many :${1:objects}, :class_name => "${2:ClassName}", :foreign_key => "${3:foreign_key}_id"$end
-------------------------------------- ho --------------------------------------
has_one :${1:object}, :class_name => "${2:ClassName}", :foreign_key => "${3:foreign_key}_id"$end
-------------------------------------- if --------------------------------------
if ${1:condition}
$end
end
-------------------------------------- ife -------------------------------------
if ${1:condition}
$2
else
$3
end
-------------------------------------- inj -------------------------------------
inject(${1:init}) { |${2:mem}, ${3:var}| $end }
------------------------------------ inject ------------------------------------
inject(${1:object}) { |${2:injection}, ${3:element}| $4 }$end
------------------------------------- logi -------------------------------------
logger.info "${1:Current value is...}"$end
-------------------------------------- mac -------------------------------------
add_column :${1:table_name}, :${2:column_name}, :${3:string}$end
-------------------------------------- mai -------------------------------------
add_index :${1:table_name},[:${2:column_name}], :name => "${2:column_name}_index"$end
-------------------------------------- map -------------------------------------
map { |${1:e}| $end }
------------------------------------- mapwi ------------------------------------
enum_with_index.map { |${1:e}, ${2:i}| $end }
-------------------------------------- max -------------------------------------
max { |a, b| $end }
-------------------------------------- mcc -------------------------------------
change_column :${1:table_name}, :${2:column_name}, :${3:string}, ${4:default => 1}$end
-------------------------------------- mct -------------------------------------
create_table :${1:table_name} do |t|
$2
end
-------------------------------------- Md --------------------------------------
File.open(${1:"${2:path/to/file}.dump"}, "w") { |${3:file}| Marshal.dump(${4:obj}, ${3:file}) }
-------------------------------------- mdt -------------------------------------
drop_table :${1:table_name}$end
-------------------------------------- mex -------------------------------------
execute "$1"$end
-------------------------------------- min -------------------------------------
min { |a, b| $end }
-------------------------------------- mm --------------------------------------
def method_missing(meth, *args, &block)
$end
end
-------------------------------------- mnc -------------------------------------
rename_column :${1:table_name}, :${2:column_name}, :${3:new_column}$end
-------------------------------------- mod -------------------------------------
module ${1:ModuleName}
module_function
$end
end
-------------------------------------- mrc -------------------------------------
remove_column :${1:table_name}, :${2:column_name}$end
-------------------------------------- mri -------------------------------------
remove_index :${1:table_name}, :${2:column_name}$end
-------------------------------------- mtc -------------------------------------
t.column :${1:column_name}, :${2:string}$end
--------------------------------------- p --------------------------------------
params[:${1:id}]$end
-------------------------------------- par -------------------------------------
partition { |${1:e}| $end }
--------------------------------------- r --------------------------------------
attr_reader :${1:attr_names}
-------------------------------------- ra --------------------------------------
render :action => "${1:action}"$end
-------------------------------------- ral -------------------------------------
render :action => "${1:action}", :layout => "${2:layoutname}"$end
-------------------------------------- ran -------------------------------------
sort_by { rand }
-------------------------------------- rb --------------------------------------
#!/usr/bin/env ruby -w
------------------------------------- rcea -------------------------------------
render_component :action => "${1:index}"$end
------------------------------------- rcec -------------------------------------
render_component :controller => "${1:items}"$end
------------------------------------- rceca ------------------------------------
render_component :controller => "${1:items}", :action => "${2:index}"$end
-------------------------------------- rea -------------------------------------
redirect_to :action => "${1:index}"$end
------------------------------------- reai -------------------------------------
redirect_to :action => "${1:show}", :id => ${2:@item}$end
-------------------------------------- rec -------------------------------------
redirect_to :controller => "${1:items}"$end
------------------------------------- reca -------------------------------------
redirect_to :controller => "${1:items}", :action => "${2:list}"$end
------------------------------------- recai ------------------------------------
redirect_to :controller => "${1:items}", :action => "${2:show}", :id => ${3:@item}$end
-------------------------------------- rej -------------------------------------
reject { |${1:e}| $end }
------------------------------------ reject ------------------------------------
reject { |${1:element}| ${1:element}.$end }
-------------------------------------- req -------------------------------------
require "$end"
------------------------------------- reve -------------------------------------
reverse_each { |${1:e}| $end }
-------------------------------------- rf --------------------------------------
render :file => "${1:filepath}"$end
-------------------------------------- rfu -------------------------------------
render :file => "${1:filepath}", :use_full_path => ${2:false}$end
-------------------------------------- ri --------------------------------------
render :inline => "${1:<%= 'hello' %>}"$end
-------------------------------------- ril -------------------------------------
render :inline => "${1:<%= 'hello' %>}", :locals => { ${2::name} => "${3:value}"$4 }$end
-------------------------------------- rit -------------------------------------
render :inline => "${1:<%= 'hello' %>}", :type => ${2::rxml}$end
-------------------------------------- rl --------------------------------------
render :layout => "${1:layoutname}"$end
-------------------------------------- rn --------------------------------------
render :nothing => ${1:true}$end
-------------------------------------- rns -------------------------------------
render :nothing => ${1:true}, :status => ${2:401}$end
-------------------------------------- rp --------------------------------------
render :partial => "${1:item}"$end
-------------------------------------- rpc -------------------------------------
render :partial => "${1:item}", :collection => ${2:items}$end
-------------------------------------- rpl -------------------------------------
render :partial => "${1:item}", :locals => { :${2:name} => "${3:value}"$4 }$end
-------------------------------------- rpo -------------------------------------
render :partial => "${1:item}", :object => ${2:object}$end
-------------------------------------- rps -------------------------------------
render :partial => "${1:item}", :status => ${2:500}$end
-------------------------------------- rt --------------------------------------
render :text => "${1:text to render...}"$end
-------------------------------------- rtl -------------------------------------
render :text => "${1:text to render...}", :layout => "${2:layoutname}"$end
------------------------------------- rtlt -------------------------------------
render :text => "${1:text to render...}", :layout => ${2:true}$end
-------------------------------------- rts -------------------------------------
render :text => "${1:text to render...}", :status => ${2:401}$end
-------------------------------------- rw --------------------------------------
attr_accessor :${1:attr_names}
--------------------------------------- s --------------------------------------
session[:${1:user}]$end
-------------------------------------- sca -------------------------------------
scan(/${1:pattern}/) { |${2:match}| $end }
-------------------------------------- sel -------------------------------------
select { |${1:e}| $end }
------------------------------------ select ------------------------------------
select { |${1:element}| ${1:element}.$2 }$end
-------------------------------------- sor -------------------------------------
sort { |a, b| $end }
------------------------------------- sorb -------------------------------------
sort_by { |${1:e}| $end }
-------------------------------------- tc --------------------------------------
require "test/unit"
require "${1:library_file_name}"
deli delete_if { |${1:e}| $end }
-------------------------------------- ts --------------------------------------
require "test/unit"
require "tc_${1:test_case_file}"
require "tc_${2:test_case_file}"
-------------------------------------- uni -------------------------------------
ARGF.each_line$1 do |${2:line}|
$end
end
------------------------------------ unless ------------------------------------
unless ${1:condition}
$end
end
------------------------------------- usai -------------------------------------
if ARGV.$1
puts "Usage: #{\$PROGRAM_NAME} ${2:ARGS_GO_HERE}"
exit
end
------------------------------------- usau -------------------------------------
unless ARGV.$1
puts "Usage: #{\$PROGRAM_NAME} ${2:ARGS_GO_HERE}"
exit
end
-------------------------------------- va --------------------------------------
validates_associated :${1:attribute}, :on => "${2:create}"$end
------------------------------------- vaif -------------------------------------
validates_associated :${1:attribute}, :on => "${2:create}", :if => proc { |obj| ${3:obj.condition?} }$end
-------------------------------------- vc --------------------------------------
validates_confirmation_of :${1:attribute}, :on => "${2:create}", :message => "${3:should match confirmation}"$end
------------------------------------- vcif -------------------------------------
validates_confirmation_of :${1:attribute}, :on => "${2:create}", :message => "${3:should match confirmation}", :if => proc { |obj| ${4:obj.condition?} }$end
-------------------------------------- ve --------------------------------------
validates_exclusion_of :${1:attribute}, :in => ${2:enumerable}, :on => "${3:create}", :message => "${4:is not allowed}"$end
------------------------------------- veif -------------------------------------
validates_exclusion_of :${1:attribute}, :in => ${2:enumerable}, :on => "${3:create}", :message => "${4:is not allowed}", :if => proc { |obj| ${5:obj.condition?} }$end
------------------------------------ verify ------------------------------------
verify :only => [:$1], :method => :post, :render => {:status => 500, :text => "use HTTP-POST"}$end
------------------------------------ verifyr -----------------------------------
verify :only => [:$1], :session => :user, :params => :id, :redirect_to => {:action => '${2:index}'}$end
------------------------------------- vlen -------------------------------------
validates_length_of ${1::name}, :maximum=>${2:10}, :message=>"${3:less than %d if you don't mind}"
-------------------------------------- vp --------------------------------------
validates_presence_of :${1:attribute}, :on => "${2:create}", :message => "${3:must be present}"$end
------------------------------------- vpif -------------------------------------
validates_presence_of :${1:attribute}, :on => "${2:create}", :message => "${3:must be present}", :if => proc { |obj| ${4:obj.condition?} }$end
-------------------------------------- vu --------------------------------------
validates_uniqueness_of :${1:attribute}, :on => "${2:create}", :message => "${3:must be unique}"$end
------------------------------------- vuif -------------------------------------
validates_uniqueness_of :${1:attribute}, :on => "${2:create}", :message => "${3:must be unique}", :if => proc { |obj| ${4:obj.condition?} }$end
--------------------------------------- w --------------------------------------
attr_writer :${1:attr_names}
------------------------------------- when -------------------------------------
when ${1:condition}
$end
------------------------------------- ydump ------------------------------------
File.open(${1:"${2:path/to/file}.yaml"}, "w") { |${3:file}| YAML.dump(${4:obj}, ${3:file}) }
------------------------------------- yload ------------------------------------
File.open(${1:"${2:path/to/file}.yaml"}) { |${3:file}| YAML.load(${3:file}) }
-------------------------------------- zip -------------------------------------
zip(${1:enums}) { |${2:row}| $end }
Posted in Rails, Ruby, JEdit | Tags jedit, rails, ruby, snippets, superabbrevs | 8 comments | no trackbacks
Posted by Jim Morris
Wed, 22 Nov 2006 07:20:07 GMT
OK after
expounding
on how much I like Epsilon as an editor, I finally hit a wall with it.
I wanted tabs of the currently open files, and it simply does not
provide that facility yet. (I know all modern editors do!). On X11 (IE
Linux and OS/X) Epsilon is not really a graphical app, it does open an
X11 window, but within it most dialogs and lists (like buffer lists
etc) are text, a little like a curses app. The advantage is it opens
really fast, and loads huge files pretty fast. The downside is you
don't get all those nice windowing facilities like movable pop-up
windows, dialogs, trees and tabs!
So after hearing so much about JEdit, I bit the bullet and gave it a
whirl. Following the instructions from a number of blogs (too numerous
to mention) I installed it on my KUbuntu Linux box, with all the
plugins people recommend, and of course the Ruby plugin and
SupperAbbrevs (The beta version), so I have my snippets!
Being used to an Emacs like editor I had to fuss around remapping all
my keys (or at least some of them), then map the new plugins to
reasonable key-bindings (called shortcuts in JEdit lingo).
I have to say I am pretty impressed, it does everything I want (or
almost). It has a plugin for tabs, it has a project manager, and
HTML/XML modes. The Ruby mode is pretty good, modeled after Textmate.
So the things that were missing that I had become accustomed to were.
- Expanding #{} in a string when you type # - Wrote a macro to do that
- Being able to select a snippet (called abbreviation in the lingo)
from a list rather than having to remember the abbreviation. - wrote a macro to do it
- Some Emacs like behavior like control-K etc. - found it in the macros manager
- Toggling between view and controller (and model) in a rails project - Wrote one, but found a better one in macros
- Being able to use snippets (OK abbreviations!) from a different
language mode. eg I'm in rhtml but I want an HTML abbreviation, or
vice versa. - wrote a macro to do it
- Running ruby scripts into a local buffer - the console plugin solved this
- Running Focused Ruby Unit tests - wrote a macro to do it
So at first I thought I would have to hack the various plugins, but
then I discovered the beanShell macros are extremely powerful,
basically they are java syntax, but have full access to the JEdit
internals and most of the plugins internals too. As Java is my second
favorite language, this was a nice surprise. (You should guess by now
Ruby is my current favorite language).
So I went about writing macros to fill in the gaps, to see if I could
switch to JEdit.
As a side note I will not buy a Mac so I can use Textmate! as awesome
as Textmate is, it is not enough to get me to switch, so I will get
JEdit as close to it as I can, maybe even further. (I worked on a
MacBook Pro Intel for 3+ months, and was not sold).
Yes JEdit actually has intellisense-like completion for Ruby. A
previous blog entry
of mine explained how I tried Komodo to get this, but it was not very
good, however the JEdit version found in the latest RubyPlugin, works
pretty well, I think it uses parsing from the JRuby project, so no
surprise it works.
In addition it also has a pretty good ruby and rails help, that is
linked to the autocomplete, it is missing a few rails entries, but is
very handy. Features of this clever plugin are found
here.
All this and JEdit is free!
Back to the macro writing.
The first hack, er I mean Macro, was to expand # to #{} when it is in
a string. This was relatively easy, as shown below. I just has to make
sure I was actually in a string, and take into account escaped quotes
and escaped #. Anyway the macro works quite well, I think it would be
better off in the RubyPlugin, but never mind.
It took me a while to think of beanshell as Java, I kept wanting to
leave off ; and other scripting language things, but it really is
Java, just scripted, very impressive language, I have no idea how they
do it, if they compile on the fly or interpret, but it works, and you
have full access to Swing, and as I have written many thousands of
lines of Java/Swing code over the years, I was back in business. (It
did take me a while to remember that stuff though as my Swing Feng was
a few years old).
// Expand # to #{} if in quotes
boolean escaped() {
pos= textArea.getCaretPosition();
str= textArea.getText(pos-1, 1);
return(str.equals("\\"));
}
boolean inQuotes() {
cl= textArea.getCaretLine();
str= textArea.getLineText(cl);
pos= (textArea.getCaretPosition() - textArea.getLineStartOffset(cl))-1;
cnt= 0;
do{
off= str.lastIndexOf("\"", pos);
if(off < 0)
break;
else if(off == 0 || str.charAt(off-1) != '\\')
cnt++;
pos= off-1;
}while(pos >= 0);
return (cnt & 1) != 0;
}
if((buffer.getMode().getName().equals("ruby") || buffer.getMode().getName().equals("rhtml")) && inQuotes() && !escaped()){
textArea.setSelectedText("#{}");
textArea.goToPrevCharacter(false);
}else{
textArea.setSelectedText("#");
}
The next one was recreating my Epsilon Hack that toggles between view
and controller. I found a great starting macro which toggled between
model and controller, so I just modified that a bit, using the same
basic technique, and within a few hours I had my view/controller
toggle. It may not be as robust as my Epsilon version, as it does a
pretty naive search to find what method it is in, in the controller,
but it seems to work. Of course, as with Textmates version, it only works
if the rails naming conventions are followed.
Download from here
UPDATE I have found a much better implementation with all the bells
and whistles of the Textmate version
here.
The big one was getting a list up to show the SupperAbbrevs snippets
for any given mode, and selecting the one you want. This took a good
part of a day, I had to study the SupperAbbrevs code, and I found a
good starting point with a macro that lists abbreviations from the
built-in JEdit abbreviations. I use a good part of that, and just
changed it so you can select one of the abbreviations and use that to
insert the snippet. I ran into a few quirks with JTable and selection,
but that was because I was pretty rusty, I have solved those problems
before, I had just forgotten how to.
So now I can type a portion or just one letter of an abbreviation, hit
Alt-Space and I get a pop-up with all the abbreviations of the current
mode, and the first one that matches what I have typed so far already
selected. Hitting enter will insert that one, or I can select the one
I want, and hit enter or click Expand, and it does its magic. I need
this as I can never remember all those abbreviations, for all the
rails and ruby snippets. (Not even Textmate can do that!) Of course I
can still type in the whole abbreviation and hit TAB to get the quick
expansion as before.
Now something that Textmate does that I like is you can click on an
icon and you get a list of all the modes then you can select a snippet
from any mode and insert it. I don't think macros will let you do
exactly that, (I think that would require a plugin), but the next best
thing is hitting Alt-Space with nothing in front of it, and I get a
pop up. I can select the mode I want then the snippet from the table,
and click insert, and it does the same thing. Just a few extra mouse
clicks than Textmate, but close enough for me.
Now I just have to figure out how to contribute these macros to the
Textmate community, the Wiki is closed to registered users only, and I
got no reply when I tried to register.
I'll put all my macros here for now, until they register me. Then you
will be able to download these macros from the nice MacroManager
plugin they have in JEdit. So far there seems to be a plugin or macro
for almost everything. The other macros are all available via the
macroManager plugin, including the toggle between model and controller
one. The Emacs macros are also available from the same utility.
I should say I am using the 4.2stable version of JEdit, I played with
4.3pre8 but it was throwing a lot of exceptions on the screen,
although none fatal, but it did seem to be a little slower, I'll wait
for it become more stable before trying again.
The RubyPlugin is available from the plugin manager, the latest
version of superAbbrevs is not however, I got it from this
link explained
here
These were the most useful howtos I found
ruby-rails-jedit,
and jedit-for-ruby-rails-development.
but there are literally hundreds around.
Another idea taken from Textmate is a macro that runs the current Ruby
Unit Test case, download from here.
It will run a focused test only on the testcase the cursor is currently in.
Here is the download link
for the biggest Macro I have done to date, it is the
one that allows you to select a SuperAbbrev snippet.
Posted in Rails, Ruby, JEdit | Tags jedit, rails, ruby, textmate | 5 comments | no trackbacks