Showing posts with label netbeans. Show all posts
Showing posts with label netbeans. Show all posts

Tuesday, June 04, 2013

typescript syntax highlighting in jedit and netbeans

Typescript syntax-highlighting is available in a few editors (vim, emacs, sublime) thanks to editor plugins published by Microsoft, and deeper type-aware language support with code-completion and refactoring is available for Visual Studio. Of course the code editors I usually use (jedit and netbeans) don't include typescript support, so I took a little time to see if I could get something working.

Adding basic typescipt support to jedit was easy. JEdit's syntax highlighting and indentation logic for a particular file is driven by the "mode" xml file associated with the file's extension (.js, .ts, .java, whatever). JEdit extracts lexical rules for syntax-coloring from the lists of keywords, operators, and regular expressions in the mode file. For typescript I associated .ts files with jedit's javascript mode, and added a few items to the keyword lists in javascript's mode xml file (declare, export, ...), and I was pretty happy with the result. This thread on stackoverflow describes where to find mode xml files, and the mode "catalog" file. I also disabled the typoscript (European CMS - who knew?) entry in the catalog, because typoscript also uses the ".ts" file extension:

<MODE NAME="javascript"  FILE="javascript.xml"
    FILE_NAME_GLOB="{*.{js,ts},Buildsub}" />

...
<MODE NAME="typoscript"  FILE="typoscript.xml"
    FILE_NAME_GLOB="*.tsXXX"/<


I tried a similar trick with netbeans, and followed these instructions to configure netbeans to treat ".ts" files as javascript. Unfortunately the resulting behavior in a netbeans editor is not that great. Netbeans builds its language support around a parser of the full language grammar - it doesn't just highlight keywords. The various syntax structures in typescript that are not legal in javascript are highlighted as errors in netbeans. Ugh! Anyway - it's better than nothing. This page has instructions for coding in java a netbeans module for a new language. It would be a fun project to code up a typescript extension for netbeans using the typescript tsc compiler via the java-based rhino javascript engine. This entry describes running tsc with rhino on the command line. I'll save that project for another day ...

Monday, May 27, 2013

ant rules for typescript compile

I extended littleware's ant template with rules to compile typescript (*.ts) files in web projects using this ant-macro posted on stackoverflow. The typescript and yuidoc rules are listed further below.

Littleware's build system just extends netbeans' ant templates with IVY support. Netbeans' ant scripts are designed to support extension hooks that run before and after the different build stages (initialization, compile, package, ...). This is from the comment at the top of a new netbeans project's build.xml file:


    There exist several targets which are by default empty and which can be 
    used for execution of your tasks. These targets are usually executed 
    before and after some main targets. They are: 

      -pre-init:                 called before initialization of project properties 
      -post-init:                called after initialization of project properties 
      -pre-compile:              called before javac compilation 
      -post-compile:             called after javac compilation 
      -pre-compile-single:       called before javac compilation of single file
      -post-compile-single:      called after javac compilation of single file
      -pre-compile-test:         called before javac compilation of JUnit tests
      -post-compile-test:        called after javac compilation of JUnit tests
      -pre-compile-test-single:  called before javac compilation of single JUnit test
      -post-compile-test-single: called after javac compilation of single JUunit test
      -pre-dist:                 called before archive building 
      -post-dist:                called after archive building 
      -post-clean:               called after cleaning build products 
      -pre-run-deploy:           called before deploying
      -post-run-deploy:          called after deploying

...

Anyway - I'm glad for netbeans' extensible ant templates. Littleware's build system could benefit from another rework to better support scala and IVY, but it's good enough for now.

Finally - I also wanted to mention that Ian Obermiller posted on github a typescript brush for Alex Gorbatchev's syntax highlighter. It seems to work great ...

Here are those ant rules I mentioned earlier ...

<target name="config-check">
     <!--
    <available file="${ivy.jar.dir}/littlesettings.xml" property="settings.exists"/>
    -->
    <available file="${ivy.jar.file}" property="ivyjar.exists"/>
    <condition property="skip.download">
        <and>
            <isset property="ivyjar.exists" />
        </and>
    </condition>
    <available file="ivy/test" property="ivy.resolve.test.exists" />
    <available file="ivy/compile" property="ivy.resolve.compile.exists" />

    ...
    
    <condition property="ivy.resolve.exists">
        <and>
            <isset property="ivy.resolve.test.exists" />
            <isset property="ivy.resolve.compile.exists" />
        </and>
    </condition>
    
    <condition property="typescript.ready">
        <and>
            <isset property="build.web.dir" />
            <isset property="typescript.compiler.path" />
            <available file="${typescript.compiler.path}" />
        </and>
    </condition>    
    
    <condition property="ydoc.ready">
        <and>
            <isset property="build.web.dir" />
            <isset property="ydoc.path" />
            <available file="${ydoc.path}" />
        </and>
    </condition>    
    
</target>

<!-- web project stuff -->

<property name="typescript.compiler.path" value="${user.home}/AppData/Roaming/npm/tsc.cmd" />
<property name="ydoc.path" value="${user.home}/Documents/Code/yuidoc/bin/ydoc.bat" />


<target name="ydoc" depends="config-check" if="ydoc.ready" 
    description="run ydoc on build/ js"
    >
  <exec executable="${ydoc.path}">
    <arg value="${build.web.dir}/resources/js/littleware"/>
 </exec>    
</target>

    
<!--
    Recursively read a source directory for TypeScript files, generate a compile list in the
    format needed by the TypeScript compiler adding every parameters it take.
    Thanks Tekool.net:
       http://stackoverflow.com/questions/12799237/how-to-watch-and-compile-all-typescript-sources
-->
<macrodef name="TypeScriptCompileDir">

    <!-- required attribute -->
    <attribute name="src" />

    <!-- optional attributes -->
    <attribute name="out" default="" />
    <attribute name="module" default="" />
    <attribute name="comments" default="" />
    <attribute name="declarations" default="" />
    <attribute name="nolib" default="" />
    <attribute name="target" default="" />

    <sequential>

        <!-- local properties -->
        <local name="out.arg"/>
        <local name="module.arg"/>
        <local name="comments.arg"/>
        <local name="declarations.arg"/>
        <local name="nolib.arg"/>
        <local name="target.arg"/>
        <local name="typescript.file.list"/>
        <local name="tsc.compile.file"/>

        <property name="tsc.compile.file" value="@{src}compile.list" />

        <!-- Optional arguments are not written to compile file when attributes not set -->
        <condition property="out.arg" value="" else='--out "@{out}"'>
            <equals arg1="@{out}" arg2="" />
        </condition>

        <condition property="module.arg" value="" else="--module @{module}">
            <equals arg1="@{module}" arg2="" />
        </condition>

        <condition property="comments.arg" value="" else="--comments">
            <equals arg1="@{comments}" arg2="" />
        </condition>

        <condition property="declarations.arg" value="" else="--declarations">
            <equals arg1="@{declarations}" arg2="" />
        </condition>

        <condition property="nolib.arg" value="" else="--nolib">
            <equals arg1="@{nolib}" arg2="" />
        </condition>

        <!-- Could have been defaulted to ES3 but let the compiler uses its own default is quite better -->
        <condition property="target.arg" value="" else="--target @{target}">
            <equals arg1="@{target}" arg2="" />
        </condition>

        <!-- Recursively read TypeScript source directory and generate a compile list -->
        <pathconvert property="typescript.file.list" dirsep="\" pathsep="${line.separator}">

            <fileset dir="@{src}">
                <include name="**/*.ts" />
                <exclude name="**/*.d.ts" />
            </fileset>

            <!-- In case regexp doesn't work on your computer, comment <mapper /> and uncomment <regexpmapper /> -->
            <mapper type="regexp" from="^(.*)$" to='"\1"' />
            <!--regexpmapper from="^(.*)$" to='"\1"' /-->

        </pathconvert>


        <!-- Write to the file -->
        <echo message="Writing tsc command line arguments to : ${tsc.compile.file}" />
        <echo file="${tsc.compile.file}" message="${typescript.file.list}${line.separator}${out.arg}${line.separator}${module.arg}${line.separator}${comments.arg}${line.separator}${declarations.arg}${line.separator}${nolib.arg}${line.separator}${target.arg}${line.separator}--sourcemap" append="false" />

        <!-- Compile using the generated compile file --> 
        <echo message="Calling ${typescript.compiler.path} with ${tsc.compile.file}" />
        <exec dir="." executable="${typescript.compiler.path}">
            <arg value="@${tsc.compile.file}"/>
        </exec>

        <!-- Finally delete the compile file 
        <echo message="${tsc.compile.file} deleted" />
        <delete file="${tsc.compile.file}" />
        -->

    </sequential>

</macrodef>


<target name="typescript" depends="config-check" if="typescript.ready" 
    description="compile typescript files build/*.ts"
    >
      <TypeScriptCompileDir
          src="${build.web.dir}/resources/js/"
          module="amd"
      />      
      
    <!-- out="${build.web.dir}/resources/js" -->
</target>


<!-- post-compile rule kicks in if build.web.dir netbeans property is defined -->
<target name="-post-compile" depends="ydoc,typescript" if="build.web.dir">
      <copy todir="${build.web.dir}/WEB-INF/lib">
        <fileset dir="ivy/test"/>
      </copy>
</target>

Saturday, January 05, 2013

scala 2.10 netbeans ant fix

I just upgraded the scala install on my laptop from 2.9.x to the latest 2.10.0 release candidate, and was depressed to discover that broke my crazy netbeans derived ant build scripts (ugh!).

> ant clean
Buildfile: C:\Users\pasquini\Documents\Code\littleware\WIP\littleware\webapp\lit
tleId\littleId\build.xml

config-check:

download-ivy:

install-ivy:

resolveIfNecessary:

-pre-init:

-init-private:

BUILD FAILED
C:\Users\pasquini\Documents\Code\littleware\WIP\littleware\webapp\littleId\littl
eId\nbproject\build-impl.xml:50: The following error occurred while executing th
is line:
jar:file:/C:/Program%20Files/Scala/scala-2.10.0-RC5/lib/scala-compiler.jar!/scal
a/tools/ant/antlib.xml:5: taskdef A class needed by class scala.tools.ant.FastSc
alac cannot be found: scala/reflect/internal/settings/MutableSettings$SettingVal
ue
 using the classloader AntClassLoader[C:\Program Files\Scala\scala-2.10.0-RC5\li
b\scala-compiler.jar;C:\Program Files\Scala\scala-2.10.0-RC5\lib\scala-library.j
ar]

Total time: 2 seconds

Fortunately - the fix was easy. Scala 2.10.x pushes some classes that its ant task depends on to a new scala-reflect jar file, so I added that to the classpath in one of the xml blocks in nbproject/build-impl.xml, and I was back in business:

        <property name="scala.compiler" value="${scala.home}/lib/scala-compiler.jar"/>
        <property name="scala.library" value="${scala.home}/lib/scala-library.jar"/>
        <property name="scala.lib" value="${scala.home}/lib"/>
        <taskdef resource="scala/tools/ant/antlib.xml">
            <classpath>
                <pathelement location="${scala.compiler}"/>
                <pathelement location="${scala.library}"/>
                <pathelement location="${scala.lib}/scala-reflect.jar"/>
            </classpath>
        </taskdef>

Anyway - scala 2.10 looks to be a great release. A lot of people are excited about the "macro" system, but I've been working with the new akka actors, and also look forward to playing around with the futures and promises APIs.