Skip to content

Instantly share code, notes, and snippets.

@endash
Last active August 29, 2015 14:15
Show Gist options
  • Save endash/c983565c5c92a7bf0a49 to your computer and use it in GitHub Desktop.
Save endash/c983565c5c92a7bf0a49 to your computer and use it in GitHub Desktop.
Quick and dirty multiple file editing in one window for TextMate - Add the command to a bundle (I use source) with: keycombo ⌘S, save document, discard output. Upon saving a file with the 'scratch' extension the script will parse out all the included files and write them to disk IFF they are in the scratch file's directory or a subdirectory thereof
#!/usr/bin/env ruby
require '[..]/scratch_file.rb'
if (file_name = ENV['TM_FILEPATH']) && File.extname(file_name) == ".scratch"
ScratchFile.new(file_name).write!
end
#file "models/post.rb"
class Post < ActiveRecord::Base
end
#file "controllers/post.rb"
class PostsController < ApplicationController
end
#directory "tests"
#file "models/post.rb"
class TestPost < Minitest::Test
end
#!/usr/bin/env ruby
require 'fileutils'
class ScratchFile
DIRECTORY_REGEX = /^#directory "((.+\/)*[^\/]+)\/?"\s*$/
FILE_REGEX = /^#file "(.+)"\s*$/
def initialize scratch_file_name
@scratch_file_name = scratch_file_name
@working_directory = File.dirname(File.absolute_path(scratch_file_name))
@directory_prefix = ""
end
def write!
files.each do |name, lines|
if should_write_file name
FileUtils.mkdir_p(File.dirname(name))
lines = lines[1..-1] if lines[0] == "\n"
lines = lines[0..-2] if lines[-1] == "\n"
File.write(name, lines.join)
else
puts "!! Warning: File #{name} is outside the working directory (#{@working_directory}) of the scratch file. File NOT written."
end
end
end
def files
{}.tap do |files|
current_file = nil
each_line do |line|
if new_directory_prefix = new_directory_prefix_for_line(line)
@directory_prefix = new_directory_prefix + '/'
current_file = nil
elsif file_name = new_file_name_for_line(line)
files[file_name] = (current_file = [])
elsif current_file
current_file << line
end
end
end
end
def each_line &block
File.foreach(@scratch_file_name) do |line|
block.call(line)
end
end
def new_file_name_for_line (line)
if new_file_name = line[FILE_REGEX, 1]
return File.expand_path("../#{@directory_prefix + new_file_name}", @scratch_file_name)
end
end
def new_directory_prefix_for_line (line)
line[DIRECTORY_REGEX, 1]
end
def should_write_file (file_name)
File.dirname(file_name).start_with?(@working_directory)
end
end
@endash
Copy link
Author

endash commented Feb 22, 2015

Added ability to specify a common directory, to avoid typos. I avoided refactoring the class this time but if it gets any more complex I just might.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment