# Encoding: UTF-8

[{beforeRunningCommand: "nop",
  command: 
   "#!/usr/bin/env ruby\n#\n# Based on (from Source.tmbundle):\n#\n# Assignment block tidier, version 0.1.\n#\n# Copyright Chris Poirier 2006.\n# Licensed under the Academic Free License version 3.0.\n#\n# This script can be used as a command for TextMate to align all \n# of the assignment signs within a block of text.  When using it with\n# TextMate, set the command input to \"Selected Text\" or \"Document\",\n# and the output to \"Replace Selected Text\".  Map it to a key \n# equivalent, and any time you want to tidy up a block, either \n# select it, or put your cursor somewhere within it; then hit the\n# key equivalent.  Voila.\n#\n# Note that this is the first version of the script, and it hasn't\n# been heavily tested.  You might encounter a bug or two. \n#\n# Note (by Dr Nic) - the \"first version\" seems to have worked for years.\n# I hope the CoffeeScript version is as successful.\n#\n# Per the license, use of this script is ENTIRELY at your own risk.\n# See the license for full details (they override anything I've \n# said here).\n\nlines = STDIN.readlines()\nselected_text = ENV.member?(\"TM_SELECTED_TEXT\")\n\nrelevant_line_pattern = /^[^:]+:/\ncolumn_search_pattern = /[\\t ]*:/\n\ncomments = []\n\nbegin\n  #\n  # If called on a selection, every assignment statement\n  # is in the block.  If called on the document, we start on the \n  # current line and look up and down for the start and end of the\n  # block.\n\n  if selected_text then\n     block_top    = 1\n     block_bottom = lines.length\n  else\n \n     #\n     # We start looking on the current line.  However, if the\n     # current line doesn't match the pattern, we may be just\n     # after or just before a block, and we should check.  If\n     # neither, we are done.\n\n     start_on      = ENV[\"TM_LINE_NUMBER\"].to_i\n     block_top     = lines.length + 1\n     block_bottom  = 0\n     search_top    = 1\n     search_bottom = lines.length\n     search_failed = false\n\n     if lines[start_on - 1] !~ relevant_line_pattern then\n        if lines[start_on - 2] =~ relevant_line_pattern then\n           search_bottom = start_on = start_on - 1\n        elsif lines[start_on] =~ relevant_line_pattern then\n           search_top = start_on = start_on\n        else\n           search_failed = true\n        end \n     end\n\n     #\n     # Now with the search boundaries set, start looking for\n     # the block top and bottom.\n   \n     unless search_failed\n        start_on.downto(search_top) do |number|\n           if lines[number-1] =~ relevant_line_pattern then\n              block_top = number\n           else\n              break\n           end\n        end\n      \n        start_on.upto(search_bottom) do |number|\n           if lines[number-1] =~ relevant_line_pattern then\n              block_bottom = number\n           else\n              break\n           end\n        end\n     end\n  end\n\n  #\n  # Now, iterate over the block and find the best column number\n  # for the = sign.  The pattern will tell us the position of the\n  # first bit of whitespace before the equal sign.  We put the\n  # equals sign to the right of the furthest-right one.  Note that\n  # we cannot assume every line in the block is relevant.\n\n  best_column = 0\n  block_top.upto(block_bottom) do |number|\n    line = lines[number - 1]\n    if line =~ relevant_line_pattern then\n      m = column_search_pattern.match(line)\n      best_column = m.begin(0) if m.begin(0) > best_column\n    end\n  end\n\n   \n  #\n  # Reformat the block.  Again, we cannot assume all lines in the \n  # block are relevant.\n\n  block_top.upto(block_bottom) do |number|\n     if lines[number-1] =~ relevant_line_pattern then\n        before, after = lines[number-1].split(/[\\t ]*:[\\t ]*/, 2)\n        # lines[number-1] = [before.ljust(best_column), after].join(after[0,1] == '>' ? \":\" : \": \")\n        lines[number-1] = [\"\#{before}:\".ljust(best_column + 2), after].join\n     end\n  end\n\n\nrescue => e\n  comments << \"Error: \#{e.inspect}\"\n  comments << e.backtrace\nend\n\n#\n# Output the replacement text\n\nlines.each do |line|\n   puts line\nend\n\ncomments.flatten.each { |c| puts \"# \#{c}\" }\n\n",
  input: "selection",
  keyEquivalent: "~@]",
  name: "Align Assignments",
  output: "replaceSelectedText",
  scope: "source.coffee",
  uuid: "EE3293A5-3761-40BD-9CA8-DAAA176AA19E"},
 {beforeRunningCommand: "nop",
  command: 
   "#!/bin/bash\n\necho \"<pre style='font-family:Monaco; font-size: 20px;'>\"\ncoffee -scp --no-wrap\necho \"</pre>\"",
  fallbackInput: "document",
  input: "selection",
  keyEquivalent: "@b",
  name: "Compile and Display JS",
  output: "showAsHTML",
  scope: "source.coffee",
  uuid: "D749F761-1740-4918-9490-90DF376BA72E"},
 {beforeRunningCommand: "nop",
  command: 
   "#!/usr/bin/env ruby\n\ncolumn_number = ENV['TM_COLUMN_NUMBER']\nwhitespace    = \" \" * (column_number.to_i - 1)\n\nprint <<-EOS\n\"\"\"\n\#{whitespace}$0\n\#{whitespace}\"\"\"\nEOS\n",
  fallbackInput: "line",
  input: "none",
  keyEquivalent: "@\"",
  name: "Insert Heredoc \"\"\" quotes",
  output: "insertAsSnippet",
  scope: "source.coffee",
  uuid: "F08537AF-4F02-4040-999D-F0785CF64C02"},
 {beforeRunningCommand: "nop",
  command: 
   "cat <<SNIPPET\n${TM_SELECTED_TEXT:-$TM_CURRENT_WORD}: (\\${1:args}) ->\n  \\$0\nSNIPPET",
  fallbackInput: "word",
  input: "selection",
  keyEquivalent: "$\n",
  name: "New Function",
  output: "insertAsSnippet",
  scope: "source.coffee",
  uuid: "192428A1-8684-4172-8728-225B4C9E532F"},
 {beforeRunningCommand: "nop",
  command: 
   "#!/bin/bash\n\necho \"<pre style='font-family:Monaco; font-size: 20px;'>\"\ncoffee -s\necho \"</pre>\"",
  input: "document",
  keyEquivalent: "@r",
  name: "Run",
  output: "showAsHTML",
  scope: "source.coffee",
  uuid: "30395DAB-44A6-44F7-99E1-02D64621303A"},
 {beforeRunningCommand: "nop",
  command: "#!/bin/bash\n\ncoffee -s\n",
  input: "selection",
  keyEquivalent: "@R",
  name: "Run selected text",
  output: "showAsTooltip",
  scope: "source.coffee",
  uuid: "90424631-D00B-448C-B157-DAC92DFB2858"}]
