Skip to content

Instantly share code, notes, and snippets.

@binzume
Last active December 15, 2015 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save binzume/b599b1ec1d3b39882285 to your computer and use it in GitHub Desktop.
Save binzume/b599b1ec1d3b39882285 to your computer and use it in GitHub Desktop.
Erlangのコードのインデントをemacsっぽく調整する(仮)
#!/usr/bin/env ruby
#
# emacs style erl formatter.
# usage: ruby erl-format.rb [-w] [target.erl]
#
save = false
if ARGV[0] == '-w'
save = true
ARGV.shift
end
if ARGV[0]
files = ARGV
else
files = `git status --porcelain`.lines.map{|l|l.chomp =~/..\s(.*\.erl)$/; $1}.compact
end
indent_conf={'fun' => 4, 'receive' => 4, 'case' => 4, 'try' => 4, 'end' => -8, 'spec' => 1, '->' => 0,
'['=>1, ']' => -1, '{' => 1,'}' => -1, '(' => 1,')' => -1, '<<' => 2,'>>' => -2, '.' => -9, ';' => -1}
re = /(fun\s+[:\w]+\/|\d+\.+\d+|[\[\]\{\}\(\)\,;]|<<|>>|::|\.(?!\w)|\w*#\??\w+\{|(?<!\w)\w+(?!\w)|[>\/]?=[<:\/=]*|->|%.*|["].*?[^\\]["])/
files.each {|fname|
STDERR.puts fname
next unless File.file?(fname)
output = []
indents = []
indent = 0
locals = []
local = 0
tmp_indent = 0
File.open(fname).read.each_line{|line|
line.chomp!
org = line.clone
ii = indent + local + tmp_indent
ii = (indents.last || 0) if line =~/^\s*(catch|after)(?!\w)/
if line =~ re
if indent_conf[$1] && indent_conf[$1] < 0
if indent_conf[$1] > -9
ii = [indent + (locals.last||0)+indent_conf[$1] ,0].max
else
ii = (indents.last || 0) + (locals.last || 0)
end
end
end
ii = 0 if ii < 0
line.sub!(/^(\s*)(?=[^\s])/, " " * ii)
line.scan(re) {
a = $1
b = $~.begin(0)
if indent_conf[$1] && indent_conf[$1] >= 0
indents << indent
locals << local
indent = $~.begin(0) + indent_conf[$1] - local if indent_conf[$1] > 0
indent +=4 if indent_conf[$1] == 0
tmp_indent = 0
elsif indent_conf[$1]
if $1 == '.'
indents.clear
locals.clear
end
if $1 == 'end'
indent = indents.pop || 0
local = locals.pop || 0
end
indent = indents.pop || 0
local = locals.pop || 0
tmp_indent = 0
elsif $1 == ','
tmp_indent = 0
local = locals.last || 0
elsif $1 == ';'
tmp_indent = 0
elsif $1 == '='
tmp_indent = 4
elsif $1 == '::'
local = b + 1
elsif $1 == '->'
indent += 4
elsif a =~/^\w*#\??\w+\{/
indents << indent
locals << local
indent = b + indent_conf['{'] + 1 - local
tmp_indent = 0
end
}
# STDERR.puts org,line if line != org
puts line if !save
p indents if !save
output << line
}
p indents if indents.length > 0
File.open(fname, "wb").write(output.join("\n")+"\n") if save
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment