<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                目前為止,我們已經完成了一個原型,是時候擴充它,讓它更加強大。 記住:我們初始目標是創建"grep運算符"。我們還需要做一大堆新的東西來達成目標, 但要像前一章的過程一樣:從簡單的東西開始,并逐步改進直到它滿足我們的需求。 在開始之前,注釋掉`~/.vimrc`中在前一章創建的映射。我們還要用同樣的快捷鍵來映射新的運算符。 ## 新建一個文件 創建一個新的運算符需要許多命令,把它們手工打出來將很快變成一種折磨。 你可以把它附加到`~/.vimrc`,但讓我們為這個運算符創建一個獨立的文件。我們有足夠的必要這么做。 首先,找到你的Vim`plugin`文件夾。在Linux或OS X,這將會是`~/.vim/plugin`。 如果你是Windows用戶,它將位于你的主目錄下的`vimfiles`文件夾。(如果你找不到,在Vim里使用`:echo $HOME命令) 如果這個文件夾不存在,創建一個。 在`plugin/`下新建文件`grep-operator.vim`。這就是你放置新運算符的代碼的地方。 一旦文件被修改,你可以執行`:source %`來重新加載代碼。 每次你打開Vim,這個文件也會被重新加載,就像`~/.vimrc`。 不要忘了,在你source之前,你_必須_先保存文件,這樣才能看到變化! ## 骨架(Skeleton) 要創建一個新的Vim運算符,你需要從兩個組件開始:一個函數還有一個映射。 先添加下面的代碼到`grep-operator.vim`: ~~~ nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@ function! GrepOperator(type) echom "Test" endfunction ~~~ 保存文件并用`:source %`source它。嘗試通過按下`<leader>giw`來執行"grep整個詞"。 Vim將在接受`iw`動作(motion)后,輸出`Test`,意味著我們已經搭起了骨架。 函數部分是簡單的,沒有什么是我們沒講過的。不過映射部分比較復雜。 我們首先對函數設置了`operatorfunc`選項,然后執行`g@`來以運算符的方式調用這個函數。 看起來這有點繞,不過這就是Vim工作的原理。 暫時把這個映射看作黑魔法吧。稍后你可以到文檔里一探究竟。 ## 可視模式 我們已經在normal模式下加入了這個運算符,但還想要在visual模式下用到它。 在之前的映射下面添加多一個: ~~~ vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr> ~~~ 保存并source文件。現在在visual模式下選擇一些東西并按下`<leader>g`。 什么也沒發生,但Vim確實輸出了`Test`,所以我們的函數已經運行了。 之前我們就見過`<c-u>`,但是還沒有解釋它是做什么的。試一下在可視模式下選中一些文本并按下`:`。 Vim將打開一個命令行就像平時按下了`:`一樣,但是命令行的開頭自動添加了`'<,'>`! Vim為了提高效率,插入了這些文本來讓你的命令在被選擇的范圍內執行。 但是這次,我們不需要它添倒忙。我們用`<c-u>`來執行"從光標所在處刪除到行首的內容",移除多余文本。 最后剩下一個孤零零的`:`,為調用`call`命令作準備。 我們傳遞過去的`visualMode()`參數還沒有講過呢。 這個函數是Vim的內置函數,它返回一個單字符的字符串來表示visual模式的類型:?`"v"`代表字符寬度(characterwise),`"V"`代表行寬度(linewise),`Ctrl-v`代表塊寬度(blockwise)。 ## 動作類型 我們定義的函數接受一個`type`參數。我們知道在visual模式下它將會是`visualmode()`的返回值, 但是在normal模式下呢? 編輯函數體部分,讓代碼像這樣: ~~~ nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@ vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr> function! GrepOperator(type) echom a:type endfunction ~~~ Source文件,然后繼續并用多種的方式測試它。你可能會得到類似下面的結果: * 按下`viw<leader>g`顯示`v`,因為我們處于字符寬度的visual模式。 * 按下`Vjj<leader>g`顯示`V`,因為我們處于行寬度的visual模式。 * 按下`<leader>giw`顯示`char`,因為我們在字符寬度的動作(characterwise motion)中使用該運算符。 * 按下`<leader>gG`顯示`line`,因為我們在行寬度的動作(linewise motion)中使用該運算符。 現在我們已經知道怎么區分不同種類的動作,這對于我們選擇需要搜索的詞是很重要的。 ## 復制文本 我們的函數將需要獲取用戶想要搜索的文本,而這樣做最簡單的方法就是復制它。 把函數修改成這樣: ~~~ nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@ vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr> function! GrepOperator(type) if a:type ==# 'v' execute "normal! `<v`>y" elseif a:type ==# 'char' execute "normal! `[v`]y" else return endif echom @@ endfunction ~~~ 哇。好多新的東西啊。試試按下`<leader>giw`,`<leader>g2e`和`vi(<leader>g`看看。 每次Vim都會輸出動作所包括的文本,顯然我們已經走上正道了! 讓我們把這段代碼一步步分開來看。首先我們用`if`語句檢查`a:type`參數。如果是`'v'`, 它就是使用在字符寬度的visual模式下,所以我們復制了可視模式下的選中文本。 注意我們使用大小寫敏感比較`==#`。如果我們只用了`==`而用戶設置`ignorecase`,?`"V"`也會是匹配的,結果_不會_如我們所愿。重視防御性編程! `if`語句的第二個分支則會攔住normal模式下使用字符寬度的動作。 剩下的情況只是默默地退出。我們直接忽略行寬度/塊寬度的visual模式和對應的動作類型。 Grep默認情況下不會搜索多行文本,所以在搜索內容中夾雜著換行符是毫無意義的。 我們每一個`if`分支都會執行`normal!`命令來做兩件事: * 在可視狀態下選中我們想要的文本范圍: * 先移動到范圍開頭,并標記 * 進入字符寬度的visual模式 * 移動到范圍結尾的標記 * 復制可視狀態下選中的文本。 先不要糾結于特殊標記方式。你將會在完成本章結尾的練習時學到為什么它們會不一樣。 函數的最后一行輸出變量`@@`。不要忘了以`@`開頭的變量是寄存器。`@@`是"未命名"(unnamed)寄存器: 如果你在刪除或復制文本時沒有指定一個寄存器,Vim就會把文本放在這里。 簡明扼要地說:我們選中要搜索的文本,復制它,然后輸出被復制的文本。 ## 轉義搜索文本 既然得到了Vim字符串形式的需要的文本,我們可以像前一章一樣將它轉義。修改`echom`命令成這樣: ~~~ nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@ vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr> function! GrepOperator(type) if a:type ==# 'v' normal! `<v`>y elseif a:type ==# 'char' normal! `[v`]y else return endif echom shellescape(@@) endfunction ~~~ 保存并source文件,然后在可視模式下選中帶特殊字符的文本,按下`<leader>g`。 Vim顯示一個被轉義了的能安全地傳遞給shell命令的文本。 ## 執行Grep 我們終于可以加上`grep!`命令來實現真正的搜索。替換掉`echom`那一行,代碼看起來就像這樣: ~~~ nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@ vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr> function! GrepOperator(type) if a:type ==# 'v' normal! `<v`>y elseif a:type ==# 'char' normal! `[v`]y else return endif silent execute "grep! -R " . shellescape(@@) . " ." copen endfunction ~~~ 看起來眼熟吧。我們簡單地執行上一章得到的`silent execute "grep! ..."`命令。 由于我們不再把所有的代碼塞進單個`nnoremap`命令里,現在代碼甚至更加清晰易懂了! 保存并source文件,然后嘗試一下,享受自己辛勤勞動的成果吧! 因為定義了一個全新的Vim運算符,現在我們可以在許多場景下使用它了,比如: * `viw<leader>g`: 可視模式下選中一個詞,然后grep它。 * `<leader>g4w`: Grep接下來的四個詞。 * `<leader>gt;`: Grep到分號為止的文本。 * `<leader>gi[`: Grep方括號里的文本. 這里彰顯了Vim的優越性:它的編輯命令就像一門語言。當你加入新的動詞,它會自動地跟(大多數)現存的名詞和形容詞搭配起來。 ## 練習 閱讀`:help visualmode()`。 閱讀`:help c_ctrl-u`。 閱讀`:help operatorfunc`。 閱讀`:help map-operator`。
                  <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>

                              哎呀哎呀视频在线观看