From 9d5b0a3e909c1a4bacb55c09ca2c8538bcbd9dae Mon Sep 17 00:00:00 2001 From: Andrew Radev Date: Mon, 8 Aug 2016 20:49:43 +0300 Subject: [PATCH] Reverse an :Unpack with :Inline --- autoload/ember_tools.vim | 4 +- autoload/ember_tools/unpack.vim | 52 ++++++++++++-- spec/plugin/inline_spec.rb | 118 ++++++++++++++++++++++++++++++++ spec/plugin/unpack_spec.rb | 88 ++++++++++++++++++++++++ 4 files changed, 255 insertions(+), 7 deletions(-) create mode 100644 spec/plugin/inline_spec.rb create mode 100644 spec/plugin/unpack_spec.rb diff --git a/autoload/ember_tools.vim b/autoload/ember_tools.vim index 53657d8..e8b3099 100644 --- a/autoload/ember_tools.vim +++ b/autoload/ember_tools.vim @@ -19,8 +19,8 @@ function! ember_tools#Init() setlocal includeexpr=ember_tools#Includeexpr() command! -count=0 -nargs=1 -buffer Extract call ember_tools#extract#Run(, , ) - command! -count=0 -buffer Unpack call ember_tools#unpack#Run() - command! -count=0 -buffer Pack call ember_tools#unpack#Reverse() + command! -buffer Unpack call ember_tools#unpack#Run() + command! -buffer Inline call ember_tools#unpack#Reverse() endfunction function! ember_tools#Includeexpr() diff --git a/autoload/ember_tools/unpack.vim b/autoload/ember_tools/unpack.vim index 7d62caf..d397251 100644 --- a/autoload/ember_tools/unpack.vim +++ b/autoload/ember_tools/unpack.vim @@ -1,6 +1,5 @@ -function! ember_tools#unpack#Run(visual) +function! ember_tools#unpack#Run() " TODO (2016-08-07) Multiline imports (look for the closing ; of the line?) - " TODO (2016-08-07) Visual mode support " TODO (2016-07-06) Nested unpacking: " const { computed, Controller, inject: { service }, observer } = Ember; @@ -51,9 +50,52 @@ function! ember_tools#unpack#Run(visual) call setline('.', 'const { '.member.' } = '.namespace.';') call winrestview(saved_view) - silent! call repeat#set(":call ember_tools#unpack#Run(0)\") + silent! call repeat#set(":call ember_tools#unpack#Run()\") endfunction -function! ember_tools#unpack#Reverse(visual) - " code +function! ember_tools#unpack#Reverse() + let saved_view = winsaveview() + let variable = expand('') + + if searchpair('const {', '', '}\s*=\s*\zs\k\+', 'W') <= 0 + return + endif + + let prefix = expand('') + + call search('\<'.variable.'\>', 'bW') + + " Remove variable from const line + exe 's/,\s*\%#'.variable.'//e' + exe 's/\%#'.variable.',\=\s*\ze\%(\k\| }\)//e' + + " Handle empty const blocks + if getline('.') =~ '^const {\s*} =' + let next_lineno = nextnonblank(line('.') + 1) + + if getline(next_lineno) !~ '^const' + " it's something other than another const line, let's delete all the + " whitespace up until that point + exe line('.').','.(next_lineno - 1).'delete _' + else + " just delete this line + delete _ + endif + endif + + " Add prefix everywhere + normal! G$ + let search_flags = "w" + let variable_pattern = '\%('.prefix.'\.\)\@' + + while search(variable_pattern, search_flags) > 0 + if synIDattr(synID(line('.'), col('.'), 1), 'name') !~ 'String\|Comment' + exe 'normal! i'.prefix.'.' + " go back to the search + call search(variable_pattern) + endif + let search_flags = "W" + endwhile + + call winrestview(saved_view) endfunction diff --git a/spec/plugin/inline_spec.rb b/spec/plugin/inline_spec.rb new file mode 100644 index 0000000..d7785d8 --- /dev/null +++ b/spec/plugin/inline_spec.rb @@ -0,0 +1,118 @@ +require 'spec_helper' + +describe ":Inline" do + describe "const unpacking" do + specify "deletes a const line if nothing is left of it after inlining" do + edit_file 'test.js', <<-EOF + const { Controller } = Ember; + + export default Controller.extend({}); + EOF + + vim.search 'const { \zsController' + vim.command 'Inline' + vim.write + + expect_file_contents current_file, <<-EOF + export default Ember.Controller.extend({}); + EOF + end + + specify "deletes an const line with another const line following" do + edit_file 'test.js', <<-EOF + const { Controller } = Ember; + const { foo } = bar; + + export default Controller.extend({}); + EOF + + vim.search 'const { \zsController' + vim.command 'Inline' + vim.write + + expect_file_contents current_file, <<-EOF + const { foo } = bar; + + export default Ember.Controller.extend({}); + EOF + end + + specify "inlines entries from the beginning" do + edit_file 'test.js', <<-EOF + import Ember from 'ember'; + + const { computed, Controller, isPresent } = Ember; + + export default Controller.extend({ + foo: Ember.computed.equal('bar', 'baz') + }); + EOF + + vim.search 'const.*\zscomputed' + vim.command 'Inline' + vim.write + + expect_file_contents current_file, <<-EOF + import Ember from 'ember'; + + const { Controller, isPresent } = Ember; + + export default Controller.extend({ + foo: Ember.computed.equal('bar', 'baz') + }); + EOF + end + + specify "inlines entries in the middle" do + edit_file 'test.js', <<-EOF + import Ember from 'ember'; + + const { computed, Controller, isPresent } = Ember; + + export default Controller.extend({ + foo: Ember.computed.equal('bar', 'baz') + }); + EOF + + vim.search 'const.*\zsController' + vim.command 'Inline' + vim.write + + expect_file_contents current_file, <<-EOF + import Ember from 'ember'; + + const { computed, isPresent } = Ember; + + export default Ember.Controller.extend({ + foo: Ember.computed.equal('bar', 'baz') + }); + EOF + end + + specify "inlines entries at the end" do + edit_file 'test.js', <<-EOF + import Ember from 'ember'; + + const { computed, Controller, isPresent } = Ember; + + export default Controller.extend({ + foo: Ember.computed.equal('bar', 'baz') + }); + EOF + + vim.search 'const.*\zsisPresent' + vim.command 'Inline' + vim.write + + expect_file_contents current_file, <<-EOF + import Ember from 'ember'; + + const { computed, Controller } = Ember; + + export default Controller.extend({ + foo: Ember.computed.equal('bar', 'baz') + }); + EOF + end + end +end diff --git a/spec/plugin/unpack_spec.rb b/spec/plugin/unpack_spec.rb new file mode 100644 index 0000000..f65ca14 --- /dev/null +++ b/spec/plugin/unpack_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe ":Unpack" do + specify "creates a const line if there is none, at the top of the file" do + edit_file 'test.js', <<-EOF + export default Ember.Controller.extend({}); + EOF + + vim.search 'Ember\.Controller' + vim.command 'Unpack' + vim.write + + expect_file_contents current_file, <<-EOF + const { Controller } = Ember; + + export default Controller.extend({}); + EOF + end + + specify "creates a const line if there is none, after the import lines" do + edit_file 'test.js', <<-EOF + import Ember from 'ember'; + + export default Ember.Controller.extend({}); + EOF + + vim.search 'Ember\.Controller' + vim.command 'Unpack' + vim.write + + expect_file_contents current_file, <<-EOF + import Ember from 'ember'; + + const { Controller } = Ember; + + export default Controller.extend({}); + EOF + end + + specify "adds entries to the const line if it exists" do + edit_file 'test.js', <<-EOF + import Ember from 'ember'; + + const { Controller } = Ember; + + export default Controller.extend({ + foo: Ember.computed.equal('bar', 'baz') + }); + EOF + + vim.search 'Ember\.computed' + vim.command 'Unpack' + vim.write + + expect_file_contents current_file, <<-EOF + import Ember from 'ember'; + + const { Controller, computed } = Ember; + + export default Controller.extend({ + foo: computed.equal('bar', 'baz') + }); + EOF + end + + specify "adds a new const line for nested unpacking" do + edit_file 'test.js', <<-EOF + import Ember from 'ember'; + + const { Controller } = Ember; + + export default Controller.extend({}); + EOF + + vim.search 'Controller\.extend' + vim.command 'Unpack' + vim.write + + expect_file_contents current_file, <<-EOF + import Ember from 'ember'; + + const { Controller } = Ember; + const { extend } = Controller; + + export default extend({}); + EOF + end +end