<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在本章和下一章中,我們將使用Vimscript來實現一個相當復雜的程序。我們將探討一些聞所未聞的東西, 也將在實戰中把之前學過的東西聯系起來。 在本實例研究中,遇到不熟悉的內容,你得用`:help`弄懂它。如果你只是走馬觀花,就將所獲無多。 ## Grep 如果你未曾用過`:grep`,現在你應該花費一分鐘讀讀`:help :grep`和`:help :make`。 如果之前沒用過quickfix window,閱讀`:help quickfix-window`。 簡明扼要地說:`:grep ...`將用你給的參數來運行一個外部的grep程序,解析結果,填充quickfix列表, 這樣你就能在Vim里面跳轉到對應結果。 我們將會添加一個"grep運算符"到任意Vim的內置(或自定義!)的動作中,來選擇想要搜索的文本, 讓`:grep`更容易使用。 ## 用法 在寫下每一個有意義的Vimscript程序的第一步,你需要思索一個問題:“它會被用戶怎么使用呢?”。 嘗試構思出一種優雅,簡易,符合直覺的調用方法。 這次我會替你把這活干了: * 我們將創造一個"grep運算符"并綁定到`<leader>g`。 * 它將表現得同其他任意Vim運算符一樣,還可以加入到組合鍵(比如`w`和`i{`)中。 * 它將立刻開始搜索并打開quickfix窗口展示結果。 * 它將_不會_跳到第一個結果,因為當第一個結果不是你想要的時候,這樣做會困擾你。 一些你將怎么使用它的用例: * `<leader>giw`: Grep光標下的詞(word)。 * `<leader>giW`: Grep光標下的詞的大寫形式(WORD)。 * `<leader>gi'`: Grep當前所在的單引號括住的詞。 * `viwe<leader>g`: 可視狀態下選中一個詞并拓展選擇范圍到下一詞,然后Grep。 有很多,_很多_其他的方法可以用它。看上去它好像需要寫很多,很多代碼, 但事實上我們只需要實現"運算符"功能然后Vim就會完成剩下的工作。 ## 一個原型 在埋頭寫下巨量(trickey bits)的Vimscript之前,有一個也許會幫上忙的方法是簡化你的目標并實現_它_, 來推測你最終解決方案可能的"外形"。 讓我們簡化我們的目標為"創造一個映射來搜索光標下的詞"。這有用而且應該更簡單,所以我們能更快得到可運行的成果。 目前我們將映射它到`<leader>g`。 我們從一個映射骨架開始并逐漸填補它。執行這個命令: ~~~ :nnoremap <leader>g :grep -R something .<cr> ~~~ 如果你閱讀過`:help grep`,你就能輕易理解這個命令。我們之前也看過許多映射,這里沒有什么是新的。 顯然我們還沒做什么,所以讓我們一步步打磨這個映射直到它符合我們的要求。 ## 搜索部分 首先我們需要搜索光標下的詞,而不是`something`。執行下面的命令: ~~~ :nnoremap <leader>g :grep -R <cword> .<cr> ~~~ 現在試一下。`<cword>`是一個Vim的command-line模式的特殊變量, Vim會在執行命令之前把它替換為"光標下面的那個詞"。 你可以使用`<cWORD>`來得到大寫形式(WORD)。執行這個命令: ~~~ :nnoremap <leader>g :grep -R <cWORD> .<cr> ~~~ 現在試試把光標放在諸如`foo-bar`的詞上面。Vim將grep`foo-bar`而不是其中的一部分。 我們的搜索部分還有一個問題:如果這里面有什么特殊的shell字符,Vim會毫不猶豫地傳遞給外部的grep命令。 這樣會導致程序崩潰(或更糟:鑄成某些大錯)。 讓我們看看如何使它掛掉。輸入`foo;ls`并把光標放上去執行映射。grep命令失敗了, 而Vim將執行`ls`命令!這肯定糟透了,如果詞里包括比`ls`更危險的命令呢? 為了解決這個問題,我們將調用參數用引號括起來。執行這個命令: ~~~ :nnoremap <leader>g :grep -R '<cWORD>' .<cr> ~~~ 大多數shell把單引號括起來的內容當作(大體上)字面量,所以我們的映射現在更加健壯了。 ## 轉義Shell命令參數 搜索部分還有一個問題。在`that's`上嘗試這個映射。它不會工作,因為詞里的單引號與grep命令的單引號發生了沖突! 為了解決問題,我們可以使用Vim的`shellescape`函數。 閱讀`:help escape()`和`:help shellescape()`來看它是怎樣工作的(真的很簡單)。 因為`shellescape()`要求Vim字符串,我們需要用`execute`動態創建命令。 首先執行下面命令來轉換`:grep`映射到`:execute "..."`形式: ~~~ :nnoremap <leader>g :execute "grep -R '<cWORD>' ."<cr> ~~~ 試一下并確信它可以工作。如果不行,找出拼寫錯誤并改正。 然后執行下面的使用了`shellescape`的命令。 ~~~ :nnoremap <leader>g :execute "grep -R " . shellescape("<cWORD>") . " ."<cr> ~~~ 在一般的詞比如`foo`上執行這個命令試試。它可以工作。再到一個帶單引號的詞,比如`that's`,上試試看。 它還是不行!為什么會這樣? 問題在于Vim在拓展命令行中的特殊變量,比如`<cWORD>`,的_之前_,就已經執行了`shellescape()`。 所以Vim shell-escaped了字面量字符串`"<cWORD>"`(什么都不做,除了給它添上一對單引號)并連接到我們的`grep`命令上。 通過執行下面的命令,你可以親眼目睹這一切。 ~~~ :echom shellescape("<cWORD>") ~~~ Vim將輸出`'<cWORD>'`。注意引號也是輸出字符串的一部分。Vim把它作為shell命令參數保護了起來。 為解決這個問題,我們將使用`expand()`函數來強制拓展`<cWORD>`為對應字符串, 搶在它被傳遞給`shellescape`_之前_。 讓我們單獨看看這一部分是怎么工作的。把你的光標移到帶單引號的詞(比如`that's`)上去, 并執行下面命令: ~~~ :echom expand("<cWORD>") ~~~ Vim輸出`that's`,因為`expand("<cWORD>")`以Vim字符串的形式返回當前光標下的詞。 是時候加入`shellescape`的部分了: ~~~ :echom shellescape(expand("<cWORD>")) ~~~ 這次Vim輸出`'that'\''s'`。 如果覺得這看上去真可笑,你大概沒有感受過看透了各種shell轉義的瘋狂形式后的淡定吧。 目前,不用為此而糾結。就相信Vim接受了`expand`的輸出并正確地轉義了它。 目前我們已經得到了光標下的詞的徹底轉義版本。是時候連接它到我們的映射了! 執行下面的命令: ~~~ :nnoremap <leader>g :exe "grep -R " . shellescape(expand("<cWORD>")) . " ."<cr> ~~~ 試一下。這個映射不再有問題,即使我們用它搜索帶古怪符號的詞。 "從簡單的Vimscript開始并一點點轉變它直到達成你的目標"這樣的工作方式將會被你一再取用。 ## 整理整理 在完成映射之前,還要處理一些小問題。首先,我們說過我們不想自動跳到第一個結果, 所以要用`grep!`替換掉`grep`。執行下面的命令: ~~~ :nnoremap <leader>g :execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr> ~~~ 再一次試試,發現什么都沒發生。Vim用結果填充了quickfix窗口,我們卻無法打開。 執行下面的命令: ~~~ :nnoremap <leader>g :execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr>:copen<cr> ~~~ 現在試試這個映射,你將看到Vim自動打開了包含搜索結果的quickfix窗口。 我們所做的僅僅是在映射的結尾續上`:copen<cr>`。 最后一點,在搜索的時候,我們要移除Vim所有的grep輸出。執行下面的命令: ~~~ :nnoremap <leader>g :silent execute "grep! -R " . shellescape(expand("<cWORD>")) . " ."<cr>:copen<cr> ~~~ 我們完成了,試一試并犒勞一下自己吧!`silent`命令僅僅是在運行一個命令的同時隱藏它的正常輸出。 ## 練習 把我們剛剛做出來的映射加入到你的`~/.vimrc`文件。 如果你未曾讀過`:help :grep`,去讀它。 閱讀`:help cword`。 閱讀`:help cnext`和`help cprevious`。修改你的grep映射,試一下它們。 設置`:cnext`和`:cprevious`的映射,讓在匹配內容間的移動更加方便。 閱讀`:help expand`。 閱讀`:help copen`。 在我們創建的映射中加入height參數到`:copen`命令中,看看quickfix窗口能不能以指定的高度打開。 閱讀`:help silent`。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看