Login

Objective-C Variable Declaration Tidier

I try to write neat, easy to read code and one pet peeve of mine is when variable declarations do not line up. This can be a difficult task as the project grows and more and more declarations are added. If you take the time to re-align them you start to look like Monk!

This is a personal preference of mine so please do not take offense if you write code this way. :)

I have written a small Ruby script to help easy my pain. It takes the longest declaration and adds two spaces after it to determine the right margin. Handles inline comments and end-of-line comments.

Instructions

It works in TextMate and Xcode without alteration. Add it as a TextMate command or an Xcode user script and assign a shortcut. Highlight the text, execute your shortcut and the text is reformatted.

Before and After

before.png



after.png

Ruby Code

#!/usr/bin/env ruby -w

PAD_LENGTH      = 2
@max_length     = 0
@declarations   = []

def pad_me(line)
  str = ''
  (@max_length - line.to_s.length).times { str << ' ' }
  return str
end

def set_longest_length
  # Discover the longest length of a declaration and add PAD_LENGTH to it
  @declarations.each do |declaration|
    @max_length = declaration[:declaration].size if declaration[:declaration].size > @max_length
  end
  @max_length += PAD_LENGTH
end

def output_string
  list_formatted = ''
  
  @declarations.each do |declaration|
    decl = declaration[:declaration]
    
    if !declaration[:comment].empty?
      list_formatted << "#{declaration[:comment]}\n"

    elsif declaration[:blank_line]
      list_formatted << "\n"

    elsif declaration[:pointer]
      list_formatted << "\t#{decl}#{pad_me(decl)} *#{declaration[:variable]}\n"

    else
      list_formatted << "\t#{decl}#{pad_me(decl)} #{declaration[:variable]}\n"
    end
  end
  return list_formatted.rstrip
end

def unwrap_declarations(lines)
  lines.each do |line|
    blank_line  = false
    pointer     = false
    comment     = ''
    eol_comment = ''
    decl        = ''
    var         = ''

    # blank line with possible spaces and/or tabs
    if line =~ /^\s{0,}$/
      blank_line = true

      # line is a comment
    elsif line =~ /^\s?\/\//
      comment = line;

      # declaration is int, BOOL etc
    elsif line.split('*')[1] == nil

      # end-of-line comment
      if line =~ /\/\//
        line, eol_comment = line.split("//")
        eol_comment = " //#{eol_comment}"
      end

      items = line.split("\s")

      # If the line contains more than two words
      if items.size > 2
        decl = items[0..-2].join(' ')
        var  = items[-1].to_s + eol_comment

      else
        decl = items[0].to_s
        var  = items[-1].to_s + eol_comment
      end

    else
      decl, var = line.split('*')
      pointer   = true
    end

    @declarations << {
      :comment     => comment,
      :blank_line  => blank_line,
      :declaration => decl.empty? ? decl : decl.strip,
      :variable    => var.empty? ? var : var.strip,
      :pointer     => pointer
    }
  end
end


# Script Execution
#
lines = STDIN.read.split("\n")
exit if lines.empty?

unwrap_declarations(lines)
set_longest_length
print output_string


 

Add comment


Security code
Refresh

 

Product Categories