Posts for the month of March 2008

Where We Are - Rewriting Scala for NetBeans

>>> Updated:
The rewritten plugin will be available, depending on the NetBeans' nightly build, it may be available after 10 hours or more. New features include a formatter (CTRL+SHIFT+F), and better brace completer. Smart auto-completion does not work now, needs further working.
===

The new Scala for NetBeans is going to form a good shape, I've got syntax highlighting, indentation, formatting, brace matching, and basic structure outline working. Here's a snapshot showing complex Scala statements being highlighted and reformatted properly:

nn

Begin Rewriting Scala for NetBeans

I'm re-writing Scala for NetBeans. Everything is broken except syntax highlighting.

Please be patient to wait for further progress.

Developing IDE Based on GSF for NetBeans#1 - Minimal Support

There has been GSF (Generic Scripting Framework) which is Tor's working derived and abstracted from Java supporting code, and, the base of Ruby/JavaScript support for NetBeans.

So, how to develop an IDE based on GSF for NetBeans? I'd like to share some experiences in this series of articles, a series of outline description, without too much code and details, for detailed information, please go into the source code on hg.netbeans.org

I. Minimal Support - Highlighting

To implement a minimal support of your editor, you need to implement/extend following classes/interface:

public class ScalaLanguage implements GsfLanguage
public class ScalaMimeResolver extends MIMEResolver
public enum ScalaTokenId implements TokenId
public class ScalaLexer implements Lexer<ScalaTokenId>

Where ScalaLexer is the token scanner of your language.

Then, register your language in layer.xml:

<filesystem>
    <folder name="Editors">
        <folder name="text">
            <folder name="x-scala">
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.scala.editing.Bundle"/>

                <file name="language.instance">
                    <attr name="instanceCreate" methodvalue="org.netbeans.modules.scala.editing.lexer.ScalaTokenId.language"/>
                    <attr name="instanceOf" stringvalue="org.netbeans.api.lexer.Language"/>
                </file>
                
                <folder name="FontsColors">
                    <folder name="NetBeans">
                        <folder name="Defaults">
                            <file name="coloring.xml" url="fontsColors.xml">
                                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.scala.editing.Bundle"/>
                            </file>
                        </folder>
                    </folder>
                </folder>
                
                <folder name="CodeTemplates">
                    <folder name="Defaults">
                        <file name="codetemplates.xml" url="codetemplates.xml">
                            <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.scala.editing.Bundle"/>
                        </file>
                    </folder>
                </folder>

                <folder name="Keybindings">
                    <folder name="NetBeans">
                        <folder name="Defaults">
                            <file name="org-netbeans-modules-scala-editing-keybindings.xml" url="DefaultKeyBindings.xml"/>
                        </folder>
                    </folder>
                </folder>
            </folder>
        </folder>
    </folder>
      
    <folder name="GsfPlugins">
        <folder name="text">
            <folder name="x-scala">
                <file name="language.instance">
                    <attr name="instanceOf" stringvalue="org.netbeans.modules.gsf.api.GsfLanguage"/>
                    <attr name="instanceClass" stringvalue="org.netbeans.modules.scala.editing.ScalaLanguage"/>
                </file>
            </folder>
        </folder>
    </folder>
    
    <folder name="Loaders">
        <folder name="text">
            <folder name="x-scala">
                <attr name="SystemFileSystem.icon" urlvalue="nbresloc:/org/netbeans/modules/scala/editing/resources/scala16x16.png"/>
                <attr name="iconBase" stringvalue="org/netbeans/modules/scala/editing/resources/scala16x16.png"/>
                <folder name="Actions">
                    <file name="OpenAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.OpenAction"/>
                        <attr name="position" intvalue="100"/>
                    </file>
                    <file name="Separator1.instance">
                        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                        <attr name="position" intvalue="200"/>
                    </file>
                    <file name="CutAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.CutAction"/>
                        <attr name="position" intvalue="300"/>
                    </file>     
                    <file name="CopyAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.CopyAction"/>
                        <attr name="position" intvalue="400"/>
                    </file>
                    <file name="PasteAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.PasteAction"/>
                        <attr name="position" intvalue="500"/>
                    </file>
                    <file name="Separator2.instance">
                        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                        <attr name="position" intvalue="600"/>
                    </file>
                    <file name="NewAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.NewAction"/>
                        <attr name="position" intvalue="700"/>
                    </file>
                    <file name="DeleteAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.DeleteAction"/>
                        <attr name="position" intvalue="800"/>
                    </file>
                    <file name="RenameAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.RenameAction"/>
                        <attr name="position" intvalue="900"/>
                    </file>
                    <file name="Separator3.instance">
                        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                        <attr name="position" intvalue="1000"/>
                    </file>
                    <file name="SaveAsTemplateAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.SaveAsTemplateAction"/>
                        <attr name="position" intvalue="1100"/>
                    </file>
                    <file name="Separator4.instance">
                        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                        <attr name="position" intvalue="1200"/>
                    </file>
                    <file name="FileSystemAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.FileSystemAction"/>
                        <attr name="position" intvalue="1300"/>
                    </file>
                    <file name="Separator5.instance">
                        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                        <attr name="position" intvalue="1400"/>
                    </file> 
                    <file name="ToolsAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.ToolsAction"/>
                        <attr name="position" intvalue="1500"/>
                    </file> 
                    <file name="PropertiesAction.instance">
                        <attr name="instanceClass" stringvalue="org.openide.actions.PropertiesAction"/>
                        <attr name="position" intvalue="1600"/>
                    </file> 
                </folder>            
            </folder>
        </folder>
    </folder>
</filesystem>

Don't forget to prepare all these resource files that registered in above layer.xml, such as scala16x16.png etc

After that, write an one-line service descriptor org.openide.filesystems.MIMEResolver under META-INF/services, which looks like

org.netbeans.modules.scala.editing.ScalaMimeResolver

That's it.

Fortress for NetBeans Screenshot#2: Mark Occurrences and Instant Rename

Well, I'm going on Fortress for NetBeans, and quickly get some basic Mark-Occurrences working, and of course, Instant-Rename .

As more thoughts are proved, I may begin new Scala editor module soon.

nn

Where We Are - Stock Marketing of China

I bought a stock in Dec 7, 2007, which was delisted soon, till now, that's why I don't care recent down of China stock markets.

But it seems the stock I bought is near to be listed again, so, I did some quick computing, and here's a summary prediction of SSE Composite Index (000001.ss):

The index will bounce to about 5600 in April, then down to about 4000 at June/July.

But I'll be very care to rely on this prediction, because it's a quick result (a carefully result needs a lot of computing time) and looks like really no-directions in the near future.

Fortress for NetBeans Screenshot#1: Syntax Highlighting

>>> Updated Mar 19:
The outline navigator will do some unicode rendering; Brace matching works.
===

I'm planning to re-write Scala editor module, based on a new parser (maybe Tor from Sun and Carl from Google will help this project too). But before that, I'd like to prove some thoughts. That comes Fortress for NetBeans.

To know more about Fortress, please go to http://projectfortress.sun.com/Projects/Community/

Fortress's grammar is expressed in PEG (Parsing Expression Grammars), and is implemented on Rats!, a clean PEG parser generator.

I got some interesting experiences on how to let Rats! become a simple lexical token stream generator, of course, it has some limits, but these lexical tokens are used only for basic/quick highlighting, brace-matching etc, I do not use it for syntax parsing and semantic analysis, so the limits are not an effect. The syntax parsing, semantic analysis and grammar checking will be from original Fortress parser.

Here's a screenshot of my experimental work:

nn

Actually I've done a bit of semantic works too, thus you can see the function definitions were bold highlighted and the outline navigator window was almost there.

ErlyBird 0.16.0 Released - An Erlang IDE based on NetBeans

I'm pleased to announce ErlyBird 0.16.0, an Erlang IDE based on NetBeans. This is an important feature release in size of 25M. If you have latest NetBeans nightly build installed, you can also install ErlyBird modules via update center.

CHANGELOG:

  • Project metadata file is changed, please see Notes
  • Instant rename (put caret on variable or function name, press CTRL+R, when rename finished, press ENTER)
  • Go-To-Declaration to macros that are defined included header files
  • Fixed: Go-To-Declaration to -inlcudelib won't work again after this include header file was opened in editor once
  • Fixed: syntax broken for packaged import attribute
  • Fixed: syntax broken for wild attribute
  • Completion suggestion will not search other projects
  • Track GSF changes, reindex performance was improved a lot; Can live with other GSF based language support now (Ruby, Groovy etc)

Java JRE 5.0+ is required.

To download, please go to: http://sourceforge.net/project/showfiles.php?group_id=192439

To install:

  1. Unzip erlybird-bin-0.16.0-ide.zip to somewhere.
  2. Make sure 'erl.exe' or 'erl' is under your environment path
  3. For Windows user, execute 'bin/erlybird.exe'. For *nix user, 'bin/erlybird'.
  4. Check/set your OTP path. From [Tools]->[Options], click on 'Erlang', then 'Erlang Installation' tab, fill in the full path of your 'erl.exe' or 'erl' file. For instance: "C:/erl/bin/erl.exe"
  5. The default -Xmx option for jvm is set to 256M, ErlyBird now works good with less memory, such as -Xmx128M. If you want to increase/decrease it, please open the config file that is located at etc/erlybird.conf, set -J-Xmx of 'default_options'.

When run ErlyBird first time, the OTP libs will be indexed. The indexing time varies from 10 to 30 minutes deponding on your computer.

Notes:

  1. Since project metadata format is changed, to open old ErlyBird created project, you should modify project.xml which is located at your project folder: nbproject/project.xml, change line:
    <type>org.netbeans.modules.languages.erlang.project</type>
    
    to:
    <type>org.netbeans.modules.erlang.project</type>
    
  2. If you have previous version ErlyBird installed, you should delete the old cache files which are located at:
    • *nix: "${HOME}/.erlybird/dev"
    • mac os x: "${HOME}/Library/Application Support/erlybird/dev"
    • windows: "C:\Documents and Settings\yourusername\.erlybird\dev" or some where

The status of ErlyBird is still Alpha, feedbacks and bug reports are welcome.