<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>griffinqiu (griffinqiu)</title>
    <link>https://ruby-china.org/griffinqiu</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Vim 下开发 Ruby on Rails 必装插件之 rails.vim 简单介绍</title>
      <description>&lt;h2 id="rails.vim"&gt;rails.vim&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;刚刚抛弃世界上最强大的语言转投 Ruby on Rails 怀抱。刚开始被被 Rails 的 View, Model, Controller, UnitTest 文件之间跳来跳去折腾的够呛。单独的 CtrlP 或者 Fzf 明显不能满足要求。仔细研究 rails.vim 插件后豁然开朗。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="常规命令"&gt;常规命令&lt;/h2&gt;
&lt;p&gt;rails.vim 提供了一些直接在 Vim 执行的 Rails 命令。但是在 Vim 8 之前 执行外部命令都是同步运行的，需要等待的时间比较久，这段时间不能在 Vim 不能做其他的操作。虽然 Vim 8 提供了异步模式，但大多数插件都没跟上。在目前主流的 Tmux + Vim 搭配下，反而不如在 Tmux 里切换到另外一个 Pane 或者 Window 来执行外部命令。所以在这里不对 Vim 执行的 Rails 命令做介绍，详情请见 &lt;code&gt;:help rails-commands&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="导航"&gt;导航&lt;/h2&gt;
&lt;p&gt;这才是 rails.vim 的强大之处。没有太多需要记忆的命令而又功能强大，处处体现了 Rails 的哲学。&lt;/p&gt;
&lt;h3 id="Goto File"&gt;Goto File&lt;/h3&gt;
&lt;p&gt;gf 本是一个自带的 Vim 命令，Normal 模式下，当光标下为文件路径时，按下 gf 可以基于相对路径跳转到该文件。但是在实际项目开发过程中很多时候 gf 不会命中。rails.vim 遵循 Rails 的习惯大于配置的原则加强了 gf 命令，大大的提高了这个命令的命中率。只要我们项目文件的路径和命名是符合 Rails 的约定。gf 的命中率是 100%。下面列举了一些常见的跳转案例。 &lt;code&gt;*&lt;/code&gt; 为光标所在的位置。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Pos&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt; 
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; 

&lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:c&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;omments&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; 

&lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s1"&gt;'Home'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:controller&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'bl*og'&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;blog_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; 

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= render 'sh*ared/sidebar' %&amp;gt;
app/views/shared/_sidebar.html.erb 

&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;stylesheet_link_tag&lt;/span&gt; &lt;span class="s1"&gt;'scaf*fold'&lt;/span&gt; &lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="kp"&gt;public&lt;/span&gt;&lt;span class="sr"&gt;/stylesheets/s&lt;/span&gt;&lt;span class="n"&gt;caffold&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt; 

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Applica&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tionController&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;application_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; 

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionCont&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;roller&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="sr"&gt;/action_controller/&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; 

&lt;span class="n"&gt;fixtures&lt;/span&gt; &lt;span class="ss"&gt;:pos&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;
&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fixtures&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;yml&lt;/span&gt; 

&lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="ss"&gt;:pri&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;nt&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;layouts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;erb&lt;/span&gt; 

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to "New", new_comme*nt_path %&amp;gt;
app/controllers/comments_controller.rb (并且会跳转到 def new) 

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Alternate 和 Related 文件"&gt;Alternate 和 Related 文件&lt;/h3&gt;
&lt;p&gt;Alternate 和 Related 是 rails.vim 插件定义的两个概念，命令分别是 :A 和 :R。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;注意 A 和 R 都为大写，在 Vim 里有个约定，插件提供的命令都是需大写开头&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;:A 跳转到当前文件的 Alternate 文件&lt;/li&gt;
&lt;li&gt;:R 跳转到当前文件的 Related 文件&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alternate 和 Related 对应表：&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th style="text-align:left;"&gt;Current file&lt;/th&gt;
&lt;th style="text-align:left;"&gt;Alternate file&lt;/th&gt;
&lt;th style="text-align:left;"&gt;Related file&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:left;"&gt;model&lt;/td&gt;
&lt;td style="text-align:left;"&gt;unit test&lt;/td&gt;
&lt;td style="text-align:left;"&gt;schema definition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:left;"&gt;controller (in method)&lt;/td&gt;
&lt;td style="text-align:left;"&gt;functional test&lt;/td&gt;
&lt;td style="text-align:left;"&gt;template (view)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:left;"&gt;template (view)&lt;/td&gt;
&lt;td style="text-align:left;"&gt;functional test&lt;/td&gt;
&lt;td style="text-align:left;"&gt;controller (jump to method)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:left;"&gt;migration&lt;/td&gt;
&lt;td style="text-align:left;"&gt;previous migration&lt;/td&gt;
&lt;td style="text-align:left;"&gt;next migration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:left;"&gt;database.yml&lt;/td&gt;
&lt;td style="text-align:left;"&gt;database.example.yml&lt;/td&gt;
&lt;td style="text-align:left;"&gt;environments/*.rb&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;配合 S, V, T 可以在不同的 Vim 窗口模式下打开，如&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;:AS       在一个新的 Vim Split 窗口打开 Alternate 文件&lt;/li&gt;
&lt;li&gt;:RV       在一个新的 Vim 垂直的 Split 窗口打开 Related 文件&lt;/li&gt;
&lt;li&gt;:AS       在一个新的 Vim Tab 打开 Alternate 文件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="快速在指定文件类型中打开文件"&gt;快速在指定文件类型中打开文件&lt;/h3&gt;
&lt;p&gt;rails.vim 还提供一组命令可以快速指定文件类型打开某个文件。如&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;:Econtroller users 可以打开 app/controllers/users_controller.rb
&lt;/li&gt;
&lt;li&gt;:Etask user 可以打开 lib/tasks/user.rake
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;类似的命令还很多，具体请查看 :h rails-type-navigation&lt;/p&gt;
&lt;h2 id="重构"&gt;重构&lt;/h2&gt;&lt;h3 id="提取 partial"&gt;提取 partial&lt;/h3&gt;
&lt;p&gt;日常 Rails 开发中，经常会碰到在 view 中需要将可重用或者逻辑较为独立的片段提取为一个 partial。rails.vim 里提供一个叫 Rextract 的命令来帮忙完成。&lt;/p&gt;

&lt;p&gt;如需要将下图的 simple_form 片段提取成 _form。先选中相关代码后执行 :Rextract form 即可。&lt;/p&gt;

&lt;p&gt;![alt text][rextract-cmd]&lt;/p&gt;

&lt;p&gt;![alt text][rextract-result]&lt;/p&gt;

&lt;p&gt;rails.vim 非常智能，如果是在 Helper 文件里 Rextract 为提取新的 helper。在 Model 和 Controller 里则是 concern。&lt;/p&gt;
&lt;h2 id="和 surround.vim 的集成"&gt;和 surround.vim 的集成&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/tpope/vim-surround" rel="nofollow" target="_blank" title=""&gt;surround.vim&lt;/a&gt; 是一个用来添加、修改、替换类似各种括号，引号等成对出现的符号。只要 Vim 安装了 surround.vim，rails.vim 便会自动对它增强。在 eruby 中可以用 &lt;code&gt;&amp;lt;C-g&amp;gt;s=&lt;/code&gt; 等快捷键快速插入 eruby 标签。如&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;C-g&amp;gt;s=&lt;/code&gt; 可以得到 &amp;lt;%= %&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;C-g&amp;gt;s-&lt;/code&gt; 可以得到 &amp;lt;% %&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;C-g&amp;gt;s#&lt;/code&gt; 可以得到 &amp;lt;%# %&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;C-g&amp;gt;s&amp;lt;C-e&amp;gt;&lt;/code&gt; 可以得到 &amp;lt;% %&amp;gt; &amp;lt;% end %&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;遗憾的是 rails.vim 并没有对删除和替换 surround 做增强。&lt;/p&gt;

&lt;p&gt;[rextract-cmd]: &lt;a href="https://ww4.sinaimg.cn/large/006tKfTcgy1fcuohz615jj31j60tkgv0.jpg" rel="nofollow" target="_blank"&gt;https://ww4.sinaimg.cn/large/006tKfTcgy1fcuohz615jj31j60tkgv0.jpg&lt;/a&gt;
[rextract-result]: &lt;a href="https://ww3.sinaimg.cn/large/006tKfTcgy1fcuoi0md08j31d80tqdov.jpg" rel="nofollow" target="_blank"&gt;https://ww3.sinaimg.cn/large/006tKfTcgy1fcuoi0md08j31d80tqdov.jpg&lt;/a&gt;&lt;/p&gt;</description>
      <author>griffinqiu</author>
      <pubDate>Sat, 18 Feb 2017 17:12:06 +0800</pubDate>
      <link>https://ruby-china.org/topics/32334</link>
      <guid>https://ruby-china.org/topics/32334</guid>
    </item>
  </channel>
</rss>
