Calvin's Tech Space

          成于堅(jiān)忍,毀于浮躁

             :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
          在VIM下使用gg=G格式化shell代碼時(shí),如果代碼中有heredoc,經(jīng)過(guò)格式化后會(huì)造成代碼運(yùn)行失敗。如下:
          do
          ??? echo "Deploying..."
          ??? ssh $USER@$HOST <<-EOF
          cd clat
          mv client client-bak-`date +%Y%m%d`
          tar zxf `basename $TARGET_DEPLOY_ZIP` -C .
          exit
          EOF

          ??? echo ""


          格式化后會(huì)成這樣:
          do
          ??? echo "Deploying..."
          ??? ssh $USER@$HOST <<-EOF
          ???? cd clat
          ???? mv client client-bak-`date +%Y%m%d`
          ???? tar zxf `basename $TARGET_DEPLOY_ZIP` -C .
          ???? exit

          ??? EOF
          ??? echo ""
          done


          vim對(duì)heredoc的代碼進(jìn)行了縮進(jìn)(四個(gè)空格),這樣會(huì)導(dǎo)執(zhí)行出錯(cuò)。

          解決:修改vim格式化shell腳本的規(guī)則,格式化時(shí)忽略heredoc。

          將如下腳本保存到.vim/indent/sh.vim:
          (來(lái)源:http://vim.1045645.n5.nabble.com/bash-heredoc-in-a-for-loop-indented-incorrectly-td1177006.html)
          " Vim indent file
          " Language:??? Shell Script
          " Maintainer:?????? Nikolai Weibull <[hidden email]>
          " Latest Revision:? 2006-04-19

          if exists("b:did_indent")
          ? finish
          endif
          let b:did_indent = 1

          setlocal indentexpr=GetShIndent()
          setlocal indentkeys+==then,=do,=else,=elif,=esac,=fi,=fin,=fil,=done,=EOF,=END
          setlocal indentkeys-=:,0#

          if exists("*GetShIndent")
          ? finish
          endif

          let s:cpo_save = &cpo
          set cpo&vim

          function GetShIndent()
          ? let lnum = prevnonblank(v:lnum - 1)
          ? if lnum == 0
          ??? return 0
          ? endif

          ? " Add a 'shiftwidth' after if, while, else, case, until, for, function()
          ? " Skip if the line also contains the closure for the above
          ? let ind = indent(lnum)
          ? let line = getline(lnum)
          ? if line =~ '^\s*\(if\|then\|do\|else\|elif\|case\|while\|until\|for\)\>'
          ??????? \ || line =~ '^\s*\<\k\+\>\s*()\s*{'
          ??????? \ || line =~ '^\s*{'
          ??? if line !~ '\(esac\|fi\|done\)\>\s*$' && line !~ '}\s*$'
          ????? let ind = ind + &sw
          ??? endif
          ? endif

          ? if line =~ '^.*<<.*\(EOF\|END\)'
          ??? let ind = 0
          ? endif
          ? if line =~ '^"\?\(EOF\|END\)"\?$'
          ??? let ind = indent(search('>.*EOF', 'b'))
          ? endif
          ? " Subtract a 'shiftwidth' on a then, do, else, esac, fi, done
          ? " Retain the indentation level if line matches fin (for find)
          ? let line = getline(v:lnum)
          ? if (line =~ '^\s*\(then\|do\|else\|elif\|esac\|fi\|done\)\>' || line =~ '^\s*}')
          ??????? \ && line !~ '^\s*fi[ln]\>'
          ??? let ind = ind - &sw
          ? endif

          ? return ind
          endfunction

          let &cpo = s:cpo_save
          unlet s:cpo_save

          不過(guò)delimiter只能是EOF或者END。

          posted on 2011-05-26 18:23 calvin 閱讀(458) 評(píng)論(0)  編輯  收藏 所屬分類: VIM

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 千阳县| 秭归县| 瑞安市| 永登县| 彭阳县| 会东县| 呼玛县| 班戈县| 宜君县| 定州市| 乌兰浩特市| 崇州市| 吴旗县| 昭通市| 广南县| 宾阳县| 高陵县| 襄樊市| 赤水市| 沁阳市| 平定县| 白河县| 宜春市| 隆化县| 思茅市| 颍上县| 涿鹿县| 婺源县| 高雄市| 金门县| 永川市| 克什克腾旗| 班玛县| 睢宁县| 新郑市| 隆昌县| 宁蒗| 平山县| 万全县| 阿巴嘎旗| 温州市|