Skip to content

Instantly share code, notes, and snippets.

@t9md
Last active August 29, 2015 14:15
Show Gist options
  • Save t9md/59d9850f51ff6ba228af to your computer and use it in GitHub Desktop.
Save t9md/59d9850f51ff6ba228af to your computer and use it in GitHub Desktop.
syntax transformer

STDIN => transform => STDOUT

Thats' filter command. Filter command in other word => transformer.

you can write transformer whichever language you want.

Using vim's ! command you can transform selected area by that transformer.
This have great possibility to reduce typing!

Movie

Problem and Idea

  • :'<,'>! is always linewise, you can't transform partial area within single line.
  • Even if transformer raise error, buffer is replaced with that error msg.
  • template engine like erb is better in most case?
  • Whats' defference in advanced snipett plugin?(maybe this is way simple).
  • Make chainable multiple tranformer like stringfy selected area then surround by import( and ).
  • chosing appropriate transformer is hard, better to do_what_I_mean behavior by invoking controller and controller choose appropriate transformer from context(language and passed string).
  • Transformer Specification? when first arg is 'check', it shoud return 1 or 0 which is used by controller to determine appropreate transformer.
  • CofferScript will be great helper as transformer for its simple syntax to JavaScript syntax(some of which is legal in other language).
let s:t = {}
let s:t.dir = "~/Dev/transform/transformer"
function! s:t.transform(startline, endline, mode)
let line_start = getline(a:startline)
let line_start_minus_one = getline(a:startline-1)
if line_start =~# '\v^const\s*\('
let f = "go_const_stringfy.rb"
elseif line_start_minus_one =~# '\v^import\s*\('
let f = "go_import.rb"
else
let f = "stringfy_word.rb"
endif
let input = join(getline(a:startline, a:endline), "\n")
if !len(input)
return
endif
let filter = join([self.dir, f], "/")
let output = system('ruby ' . filter , input)
if empty(output)
return
endif
if a:mode ==# 'v'
normal! gv"_d
else
" linewise
normal! "_dd
endif
call append(a:startline-1, split(output, "\n"))
endfunction
command! -range -bar -nargs=* Transform
\ call s:t.transform(<line1>, <line2>, <q-args>)
nnoremap <Plug>(transform) :Transform n<CR>
xnoremap <Plug>(transform) :Transform v<CR>
nmap <D-R> <Plug>(transform)
xmap <D-R> <Plug>(transform)
nmap <buffer> <D-R> <Plug>(transform)
xmap <buffer> <D-R> <Plug>(transform)
" old style one-to-one mapping from keymap to transformer.
" xnoremap <Space>rc :! ruby ~/Dev/tranform/transformer/go_const_stringfy.rb<CR>
" xnoremap <Space>rs :! ruby ~/Dev/tranform/transformer/stringfy_word.rb<CR>
" xnoremap <Space>ri :! ruby ~/Dev/tranform/transformer/go_import.rb<CR>
def parse(s)
enums = []
type = ""
s.split("\n").each do |e|
next if e =~ /\(|\)/
n = e.split
type << n[1] if n.size > 1
enums << n.first
end
[type, enums]
end
def transform(s)
type, enums = *parse(s)
v = type[0].downcase
out = ""
enums.each do |e|
out << " case #{e}:\n"
out << " return \"#{e}\"\n"
end
return <<-EOS
#{s}
func (#{v} #{type}) String() string {
switch #{v} {
#{out.chomp}
default:
return "Unknown"
}
}
EOS
end
# "const (\n\tRunning State = iota\n\tStopped\n\tRebooting\n\tTerminated\n)"
s = "const (
Running State = iota
Stopped
Rebooting
Terminated
)"
input = STDIN.read
puts transform(input)
input = STDIN.readlines
r = []
input.each do |l|
l.strip.split.map do |e|
if e =~ /^gh\//
e = e.sub "gh", 'github.com'
end
r << e
%!"#{e}"!
end
end
r = r.map do |e|
%!\t"#{e}"!
end.join("\n").chomp
puts r
input = STDIN.readlines
input.each do |l|
puts l.chomp.split.map {|e| %!"#{e}"! }.join(", ")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment