Writing jEdit macros in Java (in Eclipse)

2009 December 30th

Message from the future: there's no easy way - but hey, let's rejoice, since noone cares :D

Right now I don’t know which one sucks more: doing complex beanshell macros in a text editor or doing a proper plugin with an ant deploy script and a reloader (helper) plugin. So, here comes another crappy solution: writing jEdit macros in pure java, with real content assist and code completion.

  1. in the plugin manager install the JavaMacros plugin
  2. in Eclipse create a jEdit_Java_Macros java project
  3. Project Properties: Java Build Path: Libraries: Add External Jars —-» add jedit.jar and JavaMacros.jar
  4. create package: macros.CompiledMacros
  5. create a CompiledMacros subfolder in your personal macros dir
  6. create a class (HelloWorld for example); at the interfaces section add “MacroClass”; you can add a constructor or a main method, but it doesn’t make a difference
  7. now, oh my, you would think about setting the bin path to the Macros folder in the settings directory (Default output folder), but don’t do that – that will just mess up your macros folder, instead use this jEdit macro to automatically copy, reload and execute the compiled class file:
macroName = "CompiledMacros/HelloWorld";
from = "Q:/dev/workspace-java-jedit/jEdit_Java_Macros/bin/macros/";
to = "Q:/.jedit/macros/";

void reloadClassMacro(macroName, from, to) {
import java.io.*;
from += macroName + ".class";
to += macroName + ".class";

in = new FileInputStream(from);
out = new FileOutputStream(to);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) out.write(buf, 0, len);
in.close();
out.close();
Macros.loadMacros();
macro = Macros.getMacro(macroName);
macro.invoke(view);
}

reloadClassMacro(macroName, from, to);
return;

Now assign this macro to key in jEdit and it will automatically rerun the class macro. Since class macros are tied to a given location (meaning that if you copy the class file to another directory or you rename it it will not work) this method is useful for developing macros; in the end one might want to copy the final code into a bsh file (with cleaning out the class wrapper of course).

Finally, if you happen to be on Windows you can use this autohotkey script to “call” the macro from within Eclipse (I call the AHK script with Win+F12 (#F12) and I assigned the classloader to F12 in jEdit so that’s why I forward F12 there):

#F12::
Process, Exist, eclipse.exe
If ErrorLevel
{
WinActivate, ahk_pid %ErrorLevel%
Send ^s
}
IfWinExist jEdit
{
WinActivate
Send {F12}
}
return

EDIT: no, I was wrong, this sucks too; I can’t add internal classes, like eventlisteners… thank you very much, jEdit.

Catalogizer software

2009 December 28th

Message from the future: too bad I'm just plain tired to code at home nowdays; guess I should drink COla, Hell, RedBull and other assorted liquified shit

I have tried many and did not like either one; enough said. Finally I decided to write one for ourselves: first I wanted to do it in full java, but right now I’m hesitating -

  • I need multiple users (so that we can upload from my machine or the laptop in the same time)
  • proper database is a must (I’m tired of hashmap dumps, xml files and half baked lucene caches)
  • simple gui (I don’t want a command line tool while swing may be too steep for me)
Either way, on the client side I must have a crawler; right now the crawler is finished and does what I need: it reads directories and saves them as xml files. Can read mp3, zip, 7zip, rar and DOS descript.ion files (which is supported by Total Commander for example). It mainly uses XML Directory Listing, jID3, J7Zip and JUnRar (these are Apache/LGPL/free libraries) – I had been thinking about the exif info and the avi metadata, but the exif info is way too complex to be fully stored (and I just don’t need it) while the avi metadata is a total pain in the back in java (JMF player realization, broken/legacy libs etc).

I’ll upload the source to Google Code sooner or later, til then the binary is here:
http://www.rosamez.com/download/xml-dir-listing-ex.7z
(this is only the crawler; it’s a command line application! Example usage:

java -jar xml-dir-listing-ex.jar -o c:\test.xml -m -a -dion c:\temp)

Zen Coding – Expand Abbreviations for jEdit

2009 December 27th

Message from the future: not amused

Zen Coding didn’t excite me too much since I have some pretty similar macros/superabbrevs myself, but its dombuilder is quite nice I must admit. I’m not really interested in writing a fully working jEdit connector for all the ZC macros, but I did convert the expander to jEdit; download here.

Macro is in javascript, requires the JavaScriptShell plugin.

jEdit JavaScriptShell macro – write jEdit macros in javacsript

2009 December 25th

Message from the future: diy

I have compiled a fixed version for the JavaScriptShell macro, so that the menu bug I reported three months ago is now fixed here. This is version 0.3, all open bugs are fixed (mostly by others), is tested against Jedit current stable (4.3) and 4.4pre1 (svn trunk; btw I could not reproduce Satoda’s bug with the compiled version). Download it, place it into the jars directory of the settings directory and write nice javascript macros!

Javascript optimization: for vs while loop

2009 December 19th

Message from the future: premature opti... eh, fuck, real men write assembly

Since it is nearly impossible to find up to date statistical data on the various javascript speedhacks (in google the first three ones are from 2003-2006), I decided to do a quick and dirty test to see how fast the while(i–){} method is (since for in should only be used with objects, I’m not going to test that, period).

This is 1000*1000 iterations, done 5 times and averaged (each one is relative to its own browser); first one is vanilla for, second is length property stored beforehand, third is reversed while as seen above:

chrome 3:  0: 100%  1:  42.86%   2:  41.07%
safari 4: 0: 100% 1: 50% 2: 50.11%
ff 2.0: 0: 100% 1: 69.07% 2: 45.09%
ff 3.0.3: 0: 100% 1: 82.37% 2: 48.44%
ff 3.5.6: 0: 100% 1: 153.56% 2: 154.9%
ff 3.5.6*: 0: 100% 1: 151.85% 2: 159.26%
opera 9: 0: 100% 1: 83.26% 2: 64.93%
opera 10: 0: 100% 1: 81.67% 2: 69.26%
ie8**: 0: 100% 1: 35% 2: 29%

*: portable install, no extensions
**: only one test, the rest did not work

Now, oh my, these are some interesting numbers. If you check this simple test directly, you can test for milliseconds – have some fun; my conclusions:

  1. First of all, Safari 4 (and bleeding edge webkit) is lightning fast. Honestly, I’m not even sure if I want to optimize there, because it’s unbeatable.
  2. Internet Explorer (6,7,8, you name it) is a shame; period. In version 8 I couldn’t disable the annoyingly short script execution timeout (which can be disabled in the registry for 5.5/6/7) and I did not want to do burst measurements via setTimeouts, so out of the six tests only the simplest worked and the durations are utter crap. No words can express my sadness seeing this underdog browser.
  3. To my greatest surprise Firefox 3.5 literally hates these optimization attempts. I totally don’t understand what’s going on, but using while just for making a damn loop “faster” seems a very very bad idea here.

While and array length prefetching is (and shall be) faster, but we have enough quirks here to have a serious headache. Why? As we can see, hoping for the best while using “while” is not the way to go (it should be, I admit it though); a general solution would be using a wrapper function (forEach/each), BUT that would be much slower (because of the function callback) – while being nicer. Unless in one case, which is the most common case: arrays and native forEach – Webkit, Opera, Firefox, they all support it. Internet Explorer does not – nothing new.

In the end this means that a clean forEach wrapper function (like with the javascript libraries) speedwise is not good (and I’m being very polite here), but checking for the native forEach (in case of arrays) and deciding which solution to use in place is a waste of code and is serious readability rape.

So, in the end, though only with a tiny margin, I still say that premature optimization is evil – we have no holy grail method in the world of browser quirks; and even if we have, it will go sour in a couple of months.