Clang Format for Sublime text for KL

jfriedmanjfriedman Fabric for Houdini Posts: 81 ✭✭
edited December 2016 in KL Programming

So there's a really smart C++ code formatter in Clang. For a demo, see:

I was about to go and try to make all the formatting on all our KL code consistent, so I thought perhaps my time would be better spent trying to make the clang-format work for me. The result is- I've modified a sublime plugin in order to do this. This is basically a hacked version of another Sublime text plugin, Ross Hemsley's SublimeClangFormat.

It's here if you're interested: https://github.com/jonahf/SublimeClangFormatKL

For myself, I decided to go for broke and enabled it to run every time I press save. I also turn on a bunch of formatting features that are a pain to write but nice to read, like lining up all consecutive assignments, putting spaces in parens before and after arguments, and I have to say I like it a lot. I also decided on 100 character columns, because the names of things in the KL library are a little verbose, but of course feel free to change all this yourself.

The configuration is quite similar to what's specified in the KL style guide, which isn't overly specific about finer points of how to break arguments on lines or anything like that. Anyway, here's an example for the results from LittleDraw, only very slightly embellished:

/// \dfgPresetOmit
inline LittleDrawAxis.createLines( io Ref<Lines> lines, io Ref<ColorAttribute> vc, Vec3 pos ) {
  Vec3 origin = this.payload.multiplyVector3( Vec3() );
  Vec3 x      = this.payload.multiplyVector3( Vec3( 1, 0, 0 ) );
  Vec3 y      = this.payload.multiplyVector3( Vec3( 0, 1, 0 ) );
  Vec3 z      = this.payload.multiplyVector3( Vec3( 0, 0, 1 ) );
  switch( this.mode ) {
  case LD_MODE_A_AXIS_TRAIL:
    LittleDraw_addColoredLine( pos, origin, this.color * 0.50, this.color, lines, vc );
  case LD_MODE_A_AXIS:
    LittleDraw_addColoredLine( origin, x, this.color, Color( 1.0, 0.0, 0.0 ), lines, vc );
    LittleDraw_addColoredLine( origin, y, this.color, Color( 0.0, 1.0, 0.0 ), lines, vc );
    LittleDraw_addColoredLine( origin, z, this.color, Color( 0.0, 0.0, 1.0 ), lines, vc );
    break;
  }
}

//
// Create Geometry
//

function LitteDraw_createGeometry( LittleDraw jobs[], Geometry geo, io Points debugPoints,
                                   io Lines debugLines ) {
  Ref<Lines> lines           = debugLines;                             // a comment 
  Ref<Points> points         = debugPoints;                            // another comment
  Ref<Vec3Attribute> posAttr = geo.getAttributes().positionsAttribute; // look comments line up!
  Ref<ColorAttribute> linesVCAttr = lines.getAttributes().getOrCreateColorAttribute( "vertexColors" );
  Ref<ColorAttribute> pntsVCAttr = points.getAttributes().getOrCreateColorAttribute( "vertexColors" );
  Ref<ScalarAttribute> pointsSizesAttr = points.getOrCreateSizesAttribute();

  for( Size i = 0; i < jobs.size(); i++ ) {
    Ref<LittleDraw> job = jobs[i];

    while( job != null ) {
      switch( job.type() ) {
      // switched out by type to hopefully give the inliner a chance

      case LittleDrawVector:
        Ref<LittleDrawVector>( job ).createLines( lines, linesVCAttr, posAttr.values[i] );
        Ref<LittleDrawVector>( job ).createPoints( points, pntsVCAttr, pointsSizesAttr,
                                                   posAttr.values[i] );
        break;
      }
    }
  }
}

//
// HELPERS
//

/// \internal
inline LittleDraw_addColoredLine( Vec3 pos0, Vec3 pos1, Color color0, Color color1,
                                  io Ref<Lines> lines, io Ref<ColorAttribute> vc ) {
  lines.addLine( pos0, pos1 );
  vc.values[vc.size() - 2] = color0;
  vc.values[vc.size() - 1] = color1;
}

In addition to having all those annoying to write but nice to read formatting features, it's really nice when renaming every occurrence of something, like a method name for example. Normally that wrecks any kind of even marginally fancy formatting, but with auto formatting everything just falls in line.

This is implemented as just some modifications on that existing Sublime Text plugin. Clang format thinks it's dealing with C++, so a few modifications were necessary to make it not break things. For example, breaking string literals in the C++ way to multi line ones doesn't work, so that had to be disabled. Also certain keywords confuse it about how they should be formatted, and that's been fixed as well in the python code.

Hope others find this useful as well!

Comments

Sign In or Register to comment.