Calvin's Tech Space

          成于堅忍,毀于浮躁

             :: 首頁 :: 聯系 :: 聚合  :: 管理
          在VIM下使用gg=G格式化shell代碼時,如果代碼中有heredoc,經過格式化后會造成代碼運行失敗。如下:
          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 ""


          格式化后會成這樣:
          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對heredoc的代碼進行了縮進(四個空格),這樣會導執行出錯。

          解決:修改vim格式化shell腳本的規則,格式化時忽略heredoc。

          將如下腳本保存到.vim/indent/sh.vim:
          (來源: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

          不過delimiter只能是EOF或者END。

          posted on 2011-05-26 18:23 calvin 閱讀(458) 評論(0)  編輯  收藏 所屬分類: VIM
          主站蜘蛛池模板: 遂溪县| 蒲城县| 临海市| 板桥市| 霍城县| 屏边| 淮安市| 江津市| 玉树县| 承德县| 宝山区| 三穗县| 德惠市| 上杭县| 石城县| 天等县| 呈贡县| 桂平市| 金阳县| 上栗县| 建宁县| 巴彦淖尔市| 大渡口区| 建水县| 西林县| 清流县| 区。| 信丰县| 西盟| 临朐县| 澎湖县| 衡山县| 巍山| 长汀县| 锦屏县| 丰台区| 壶关县| 威信县| 漠河县| 石城县| 尉氏县|