<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國際加速解決方案。 廣告
                既然知道了段移動的工作原理,讓我們重新映射這些命令來使得它們對于Potion文件起作用。 首先我們要決定Potion文件中"段"的意義。 有兩對段移動命令,所以我們可以總結出兩套組合,我們的用戶可以選擇自己喜歡的一個。 讓我們使用下面兩個組合來決定哪里是Potion中的段: 1. 任何在空行之后的,第一個字符為非空字符的行,以及文件首行。 2. 任何第一個字符為非空字符,包括一個等于號,并以冒號結尾的行。 稍微拓展我們的`factorial.pn`例子,這就是那些規則當作段頭的地方: ~~~ # factorial.pn 1 # Print some factorials, just for fun. factorial = (n): 1 2 total = 1 n to 1 (i): total *= i. total. print_line = (): 1 2 "-=-=-=-=-=-=-=-\n" print. print_factorial = (i): 1 2 i string print '! is: ' print factorial (i) string print "\n" print. "Here are some factorials:\n\n" print 1 print_line () 1 10 times (i): print_factorial (i). print_line () ~~~ 我們的第一個定義更加自由。它定義一個段為一個"頂級的文本塊"。 第二個定義則嚴格一點。它定義一個段為一個函數定義。 ## 自定義映射 在你的插件的repo中創建`ftplugin/potion/sections.vim`。 這將是我們放置段移動代碼的地方。記得一旦一個緩沖區的`filetype`設置為`potion`,這里的代碼就會執行。 我們將重新映射全部四個段移動命令,所以繼續并創建一個骨架: ~~~ noremap <script> <buffer> <silent> [[ <nop> noremap <script> <buffer> <silent> ]] <nop> noremap <script> <buffer> <silent> [] <nop> noremap <script> <buffer> <silent> ][ <nop> ~~~ Notice that we use?`noremap`?commands instead of?`nnoremap`, because we want these to work in operator-pending mode too. That way you'll be able to do things like?`d]]`?to "delete from here to the next section". 注意我們使用`noremap`而不是`nnoremap`,因為我們想要這些命令也能在operator-pending模式下工作。 這樣你就能使用`d]]`命令來刪除從這到下一段之間的內容。 我們設置映射生效于buffer-local,所以它們只對Potion文件起作用,不會替換全局選項。 我們也設置了silent,因為用戶不應關心我們實現段移動的細節。 ## 使用一個函數 每個命令中實現段移動的代碼會是非常相似的,所以讓我們把它抽象出供映射調用的一個函數。 你將在那些創建了一些相似的映射的Vim插件中頻繁看到這種策略。 比起把所有的功能堆砌于各個映射中,這樣做不僅更易讀,而且更易維護。 在`sections.vim`文件中加上下面內容: ~~~ function! s:NextSection(type, backwards) endfunction noremap <script> <buffer> <silent> ]] \ :call <SID>NextSection(1, 0)<cr> noremap <script> <buffer> <silent> [[ \ :call <SID>NextSection(1, 1)<cr> noremap <script> <buffer> <silent> ][ \ :call <SID>NextSection(2, 0)<cr> noremap <script> <buffer> <silent> [] \ :call <SID>NextSection(2, 1)<cr> ~~~ 這里我用到了Vimscript的斷行特性,因為我不想看到又長又臭的代碼。 注意反斜杠是放在第二行前面進行轉義的。閱讀`:help line-continuation`以了解更多。 注意我們使用`<SID>`和一個腳本本地命名空間內定義的函數來避免污染全局空間。 每個映射簡單地以適當參數調用`NextSection`實現對應的移動。 現在我們可以開始實現`NextSection`了。 ## 基本移動 讓我們考慮下我們的函數需要做什么。 我們想要移動光標到下一段,而移動光標,有一個簡單的辦法就是利用`/`和`?`命令。 編輯`NextSection`成這樣: ~~~ function! s:NextSection(type, backwards) if a:backwards let dir = '?' else let dir = '/' endif execute 'silent normal! ' . dir . 'foo' . "\r" endfunction ~~~ 現在這個函數使用我們之前見過的`execute normal!`來執行`/foo`或`?foo`,取決于`backwards`的值。 這將是個好的開始。 繼續前進,我們顯然需要搜索`foo`以外的東西,是什么則取決于用的是段頭的第一個還是第二個定義。 把`NextSection`改成這樣: ~~~ function! s:NextSection(type, backwards) if a:type == 1 let pattern = 'one' elseif a:type == 2 let pattern = 'two' endif if a:backwards let dir = '?' else let dir = '/' endif execute 'silent normal! ' . dir . pattern . "\r" endfunction ~~~ 現在只需要補上匹配的模式了(pattern),讓我們繼續完成它吧。 ## 頂級文本段 用下面一行替換掉第一個`let pattern = '...'`: ~~~ let pattern = '\v(\n\n^\S|%^)' ~~~ 如果不理解這個正則表達式是干什么的,請回憶我們正在實現的"段"的定義。 > 任何在空行之后的,第一個字符為非空字符的行,以及文件首行。 開頭的`\v`強制切換為"very magic"模式,一如之前的幾次。 剩下的正則表達式由兩個選項組成。第一個,`\n\n^\S`,搜索"兩個換行符,接著之后是一個非空字符"。 這正好是我們的定義中的第一種情況。 另一個是`%^`,在Vim中,這是一個代表文件開頭的特殊正則符號。 我們現在已經到了嘗試前兩個映射的時機了。 保存`ftplugin/potion/sections.vim`并在你的Potion例子緩沖區中執行`:set filetype=potion`。?`[[`和`]]`命令應該可以工作,但會顯得古怪。 ## 搜索標記 你大概注意到了,在段之間移動時光標會位于真正想要移動到的地方上方的空行。 在繼續閱讀之前,先想想為什么會這樣。 問題在于我們使用`/`(或`?`)進行搜索,而在默認情況下Vim會把光標移動到匹配開始處。 舉個例子,當你執行`/foo`光標會位于`foo`中的`f`。 為了讓Vim把光標移動到匹配結束處而不是開始處,我們可以使用搜索標記(search flag)。 試試在Potion文件中這么搜索: ~~~ /factorial/e ~~~ Vim將找到`factorial`并帶你到那。按下幾次`n`來在匹配處之間移動。?`e`標記將使得Vim把光標移動到到匹配結束處而不是開始處。在另一個方向也試試: ~~~ ?factorial?e ~~~ 讓我們來修改我們的函數,用搜索標記來放置光標到匹配的段頭的另一端。 ~~~ function! s:NextSection(type, backwards) if a:type == 1 let pattern = '\v(\n\n^\S|%^)' let flags = 'e' elseif a:type == 2 let pattern = 'two' let flags = '' endif if a:backwards let dir = '?' else let dir = '/' endif execute 'silent normal! ' . dir . pattern . dir . flags . "\r" endfunction ~~~ 我們這里改動了兩處。首先,我們依照段移動的類型設置`flags`變量的值。 現在我們僅需處理第一種情況,所以設置了標記`e`。 其次,我們在搜索字符串中連接`dir`和`flags`。這將依照我們搜索的方向加入`?e`或`/e`。 保存文件,切換回Potion示例文件,并執行`:set ft=potion`來讓改動生效。 現在嘗試`[[`和`]]`來看看我們的成果吧! ## 函數定義 是時候處理我們對"段"的第二個定義了,幸運的是這個比起第一個簡單多了。 重新說一下我們需要實現的定義: > 任何第一個字符為非空字符,包括一個等于號,并以冒號結尾的行。 我們可以使用一個簡單的正則表達式來查找這樣的行。 修改函數中第二個`let pattern = '...'`成這樣: ~~~ let pattern = '\v^\S.*\=.*:$' ~~~ 這個正則表達式比上一個沒那么嚇人多了。我把指出它是怎么工作的任務作為你的練習 -- 它只是我們的定義的一個直白的翻譯。 保存文件,在`factorial.pn`處執行`:set filetype=potion`,然后試試新的`][`和`[]`映射。它們應該能如期工作。 在這里我們不需要搜索標記,因為默認的移動到匹配處開頭正是我們想要的。 ## 可視模式 我們的段移動命令在normal模式下一切正常,但要讓它們也能在visual模式下工作,我們還需要增加一些東西。 首先,把函數改成這樣: ~~~ function! s:NextSection(type, backwards, visual) if a:visual normal! gv endif if a:type == 1 let pattern = '\v(\n\n^\S|%^)' let flags = 'e' elseif a:type == 2 let pattern = '\v^\S.*\=.*:$' let flags = '' endif if a:backwards let dir = '?' else let dir = '/' endif execute 'silent normal! ' . dir . pattern . dir . flags . "\r" endfunction ~~~ Two things have changed. First, the function takes an extra argument so it knows whether it's being called from visual mode or not. Second, if it's called from visual mode we run?`gv`?to restore the visual selection. 兩個地方改變了。首先,函數接受的參數多了一個,這樣它能知道自己是否是在visual模式下調用的。 其次,如果它是在visual模式下調用的,我們執行`gv`來恢復可視選擇區域。 為什么我們要這么做?來,讓我展示給你看。 在visual模式下隨意選擇一些文本并執行下面命令: ~~~ :echom "hello" ~~~ Vim將顯示`hello`,但可視模式下選擇的范圍也隨之清空! 當用`:`執行一個ex模式下的命令,可視選擇的范圍總會被清空。?`gv`命令重新選擇之前的可視選擇范圍,相當于撤銷了清空。 這是個有用的命令,你會在日常工作中因此受益的。 現在我們需要更新前面的映射,傳遞`0`給新的`visual`參數: ~~~ noremap <script> <buffer> <silent> ]] \ :call <SID>NextSection(1, 0, 0)<cr> noremap <script> <buffer> <silent> [[ \ :call <SID>NextSection(1, 1, 0)<cr> noremap <script> <buffer> <silent> ][ \ :call <SID>NextSection(2, 0, 0)<cr> noremap <script> <buffer> <silent> [] \ :call <SID>NextSection(2, 1, 0)<cr> ~~~ 這里沒什么是過于復雜的。現在讓我們加上visual模式映射,作為最后一塊拼圖。 ~~~ vnoremap <script> <buffer> <silent> ]] \ :<c-u>call <SID>NextSection(1, 0, 1)<cr> vnoremap <script> <buffer> <silent> [[ \ :<c-u>call <SID>NextSection(1, 1, 1)<cr> vnoremap <script> <buffer> <silent> ][ \ :<c-u>call <SID>NextSection(2, 0, 1)<cr> vnoremap <script> <buffer> <silent> [] \ :<c-u>call <SID>NextSection(2, 1, 1)<cr> ~~~ 這些映射都設置`visual`參數的值為`1`,來告訴Vim在移動之前重新選擇上一次的選擇范圍。 這里也用到了我們在Grep Operator那幾章學到的`<c-u>`技巧。 保存文件,在Potion文件中`set ft=potion`,大功告成!嘗試一下你的新映射吧。 像`v]]`和`d[]`這樣的命令現在應該可以正常地工作了。 ## 我們得到了什么? 這是冗長的一章,盡管我們只實現了一些看上去簡單的功能,但是你學到了(并充分地練習了)下列有用的知識: * 使用`noremap`而不是`nnoremap`來創建可以作為移動和動作使用的命令。 * 在創建相關聯的映射時,使用一個單一的接受多個參數的函數來簡化你的工作。 * 逐漸增強一個Vimscript函數的能力。 * 動態地組建一個`execute 'normal! ...'字符串。 * 結合正則表達式,使用簡單的搜索來實現移動。 * 使用特殊的正則符號,比如`%^`(文件開頭) 。 * 使用搜索標記來改變搜索的行為。 * 實現不會改變可視選擇范圍的visual模式映射 堅持下并完成練習(不過是閱讀一些文檔),然后賞自己一些冰激凌。你值得擁有! ## 練習 閱讀`:help search()`。這是一個值得了解的函數,不過你也可以使用跟`/`和`?`列在一起的標記。 閱讀`:help ordinary-atom`來認識能在搜索模式(pattern)中用到的更多有趣的東西。
                  <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>

                              哎呀哎呀视频在线观看