整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          vim 從嫌棄到依賴(22)-自動補全

          vim 從嫌棄到依賴(22)-自動補全

          篇文章我們將討論 vim 自帶的自動補全功能。當然,針對自動補全功能有許多好用的插件,但是了解vim自帶的功能有助于我們更好地用來插件的補全功能。因為我見過有的配置文件將插件的功能配置得比原有的更難用,而且只用基本的功能不一定有原版的好用。所以這里也介紹一下原始版本用法,算是幫助各位在以后的配置中提供一個標桿。

          make 命令

          在了解自動補全之前,讓我們先簡單聊聊 :make 這個命令,它與上一篇文章中介紹的 :grep 命令類似,也是對 shell 命令的一個封裝。它默認封裝的是 make 命令。

          我們對 c/c++ 語言執行 :make 也就是在調用 shell 中的 make 命令。它會將編譯產生的錯誤信息存儲在 quickfix 列表中。我們在上一節中介紹了如何操作 quickfix 列表。也介紹了如何對 :grep 命令進行改造。同樣的 :make 也支持使用相同的方法進行改造。

          :make 命令中,使用 makeprg 來執行外部命令,使用 errorformat 來格式化輸出到 quickfix 中。它們默認的值如下:

          makeprg="make"
          
          errorformag="errorformat=%*[^"]"%f"%*\D%l: %m,"%f"%*\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l:
          for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\,,%-GIn file incl
          uded from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\,,%-G%*[
          ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,"%f"\, line %l%*\D%c%*[^ ] %m,%D%*\a[%*\d]: Entering directory %*[`']%f',%X%*
          \a[%*\d]: Leaving directory %*[`']%f',%D%*\a: Entering directory %*[`']%f',%X%*\a: Leaving directory %*[`']%f',%DMaking
          %*\a in %f,%f|%l| %m"
          

          可以調整它們的值來適配不同的外部命令。這里就不再詳細展開了,相信閱讀過上一篇文章的小伙伴對這個應該不陌生。本來 :make 命令是vim中十分有用的一個命令,應該單獨寫一篇文章的。但是它于 :grep 重復度太高了,所以我決定在介紹其他內容的時候一筆帶過。想了解詳細信息的可以參考vim的用戶手冊。

          自動補全

          自動補全可以在插入模式下觸發,當我們觸發補全功能的時候,vim會根據當前編輯會話中所有緩沖區的內容建立一張補全列表,然后根據當前光標左側的字符進行檢測,看在表中能否找到單詞的一部分,能找到則會用這個未完成的單詞對補全列表進行過濾,所以不是以它為開頭的單詞都被過濾掉,剩余的組成一個彈出式菜單供用戶選擇。效果如下:


          上述例子中,因為以
          re 開頭的原本只有 require 一項,為了展示補全效果這里我們新增一個以 re 開頭的 return

          我們使用 <Ctrl +p><Ctrl + n> 來切換補全菜單中的上一條和下一條。除了這個,我們還有其他的用于操作補全菜單的快捷鍵。

          • <Ctrl - n> : 使用來自補全列表中的下一項內容(next)
          • <Ctrl - p> : 使用來自補全列表中的上一項內容(prev)
          • <Down> : 與 <Ctrl -n> 相同
          • <Up>: 與 <Ctrl - p> 相同
          • <Ctrl -y> : 確認使用當前選中的匹配項
          • <Ctrl - e> : 還原最初的輸入項
          • <Ctrl -h> : 從當前匹配項中刪除一個字符
          • <Ctrl - l> : 從當前匹配項中增加一個字符

          一般在輸入字符的時候,如果有匹配項可以匹配vim會自動彈出,或者也可以手動使用 <Ctrl - n> 彈出匹配項菜單。在確定要使用的匹配后就可以使用 <Ctrl-y> 來確認

          有時候雖然彈出了匹配項菜單,但是匹配項太多了,而你需要的單詞又在列表的太后面,這個時候可以使用 <Ctrl - e> 退出菜單,手動輸入幾個字符使匹配項更加精確?;蛘咭部梢暂斎?<Ctrl -p> 到達最開始的項,即我們目前的輸入,然后再次輸入字符來精簡菜單項,接著使用 <Ctrl - n> 彈出菜單。使用這種方式來一步一步地逼近我們想要的結果

          自定義補全項來源

          默認情況下,vim 補全項主要來源于以下幾個地方:

          1. 緩沖區列表:vim補全項最基本的來源就是當前的緩沖區列表。它可以通過 <Ctrl - x><Ctrl - n> 來觸發該項。
          2. 包含文件,所有的編程語言都有包含文件的概念,例如 c/c++中的 #include , python 中的 import 。使用 <Ctrl-x><Ctrl-i> 可以觸發這個選項,讓vim從被包含文件中提取補全項。vim本身使用 c 語言編寫的,它能夠識別 c/c++ 語言中的關鍵字,我們可以指定 include 項來使 vim認識其他不同的關鍵字。一般常用的編程語言 vim 都能夠識別,因此不需要修改 include 項。
          3. 標簽文件,我們使用 ctags 或者類似的插件的時候會生成一個標簽文件,該文件會將掃描到代碼中的關鍵字、函數、變量等的索引放入到一個文件中以供后續進行跳轉。同時他們也會產生一系列的補全項到補全列表中??梢允褂?<Ctrl+x><Ctrl+]> 來觸發

          一般直接使用 <Ctrl + n> 觸發的是當前緩沖區列表中的補全項,使用 <Ctrl+x> 作為前綴,可以觸發其他類型的補全項。這么做有一個好處是盡量精簡補全列表,減少了我們手動遍歷的過程。但是有時候我們并不知道我想要的內容該從哪里來,有沒有什么辦法能做到,用 <Ctrl + n> 這個按鈕就可以調用其他所有來源的補全項呢?

          要做到這點,可以使用 complete 這個配置項。該項包含一組由逗號分隔的單個字符表示的參數,當參數出現時表示需要掃描該參數代表的位置。使用 set complete? 可以看到,缺省項為 complete=.,w,b,u,t 。我們可以使用 set complete-=i 或者 set complete+=k 來刪除或者添加某個掃描位置。常見的位置參數如下所示:

          • . : 表示當前以打開的緩沖區
          • w : 當前打開的窗口
          • b : 當前緩沖區列表
          • u : 當前處于緩沖區列表中,但是未打開的緩沖區
          • t : 當前標簽文件
          • U : 當前打開的,不屬于緩沖區列表中的緩沖區
          • k : 從字典文件中加載的補全項
          • i : 從當前文件和包含文件中讀取
          • d : 從當前文件和包含文件中讀取使用 define定義的宏

          完整的內容可以使用 :h 'complete' 來查看。

          使用字典文件

          在上面的論述中,我們可以知道 vim 是可以自定義補全的字典文件,然后從字典中產生匹配的。我們可以使用 <Ctrl-x><Ctrl-k> 來加載字典中的匹配項。

          我們可以使用 set spell來啟動拼寫檢查,拼寫檢查也會產生新的字典文件。如果不想使用該項,也可以使用 set dictionary來指定含有一個或者多個單詞的字典文件。

          在這個例子中我們在 nvim-config 目錄中新建一個 spell.txt 文件,我們在里面寫入如下內容

          require
          return
          request
          

          然后使用 set dictionary=./spell.txt ,接著刪除 init.lua 中的 return ,輸入 re 然后使用 <Ctrl+x><Ctrl+k> 這個時候我們發現它已經加載了

          補全整行

          除了補全單詞,vim還可以補全整行的內容,使用 <Ctrl+x><Ctrl+l> 可以觸發補全整行的操作。
          補全行的補全項來源與補全單詞相同,需要注意的是補全行的操作會自動忽略行首的縮進。

          補全行的操作與之前介紹的 yy 或者 :t 產生的效果相同,我們應該要根據實際情況分別使用。

          補全文件名

          在 shell中輸入命令可以使用 <Tab> 鍵來自動補全文件路徑,vim中使用 <Ctrl+x><Ctrl+f> 來對文件路徑和文件名進行補全。

          需要注意的是當我們使用相對路徑來補全文件名時,使用的是工作目錄,也就是你從哪個目錄中進入的vim。我們可以在 vim中使用:cd來切換工作目錄。例如我在 nvim-config這個工程的根目錄執行 nvim init.lua,我們在這個文件中希望快速補全 basic/settings.lua這項,我們發現它在補全的時候報錯


          這個時候我們可以使用
          :cd lua 來切換工作目錄到 nvim-config/lua 。這個時候再執行補全命令就可以了。

          根據具體編程語言生成補全

          上述補全在編輯普通文本的時候顯的有點用處,但是作為程序員平時在寫代碼如果只能使用上述方式進行補全肯定會抓狂的。好在vim 提供了像其他IDE那樣的基于編程語言的補全方式。使用該補全方式的快捷鍵為 <Ctrl+x><Ctrl+o> 要啟用該方式,需要啟動文件類型識別。

          nvim 中已經啟用了這一特性,因此不必特意進行設置,但是這里我還是給出它的配置。

          vim.o.filetype="plugin"
          

          或者vim中可以使用如下代碼

          set filetype=plugin
          set nocompatiable # 設置與vi 不兼容
          

          例如我們可以嘗試著在 css 文件中使用補全


          vim 本身也確實支持很多語言的自動補全,但是為了獲得完整的體驗還是推薦使用各種專門的補全插件獲得更好的體驗

          最后的總結

          在這邊文章中,介紹了vim中補全項主要的幾個來源分別是:當前緩沖區和緩沖區列表、包含文件、外部程序生成的標簽等等。同時也介紹了如何使用快捷鍵來進行不同項的補全,現在對這些快捷鍵總結如下:

          • <Ctrl + n> : 普通關鍵字補全,主要來源自緩沖區列表和當前緩沖區
          • <Ctrl+x><Ctrl+n> : 與 <Ctrl+n>作用相同
          • <Ctrl+x><Ctrl+i> : 從包含文件中獲取補全項
          • <Ctrl+x><Ctrl+]> : 從外部標簽中獲取補全項
          • <Ctrl+x><Ctrl+k> : 從字典文件中獲取補全項
          • <Ctrl+x><Ctrl+l> : 補全整行
          • <Ctrl+x><Ctrl+f> : 補全文件名
          • <Ctrl+x><Ctrl+o> : 根據編程語言來進行補全

          堡之前寫過一篇關于前端開發常用的幾款ide編輯器,而其中vscode就是現在漢堡正在使用的一款很火的編輯器。其性能遠超其他幾款編輯器,另外它最特色的功能莫過于它無邊無際的插件市場。下面漢堡給大家介紹幾款自認為好用的插件:

          1、vscode-fileheader

          它是一款自動添加頭部注釋的插件,只需要簡單的配置就可以添加作者詳情以及可以查看創建時間和最后修改時間,平時多人協作的時候,可以方便的查看哪個文件是誰書寫的,另外最后修改的日期是什么時候。

          2、HTML Snippets

          比較實用且初級的H5代碼片段以及提示,比較方便代碼語義化的時候提高工作效率

          3、HTML CSS Support/CSS Peek

          CSS Support是css的提示,寫class智能提示當前項目所支持的樣式。而CSS Peek這個插件是追蹤到樣式表中的CSS類和ids定義的地方。

          css support

          css peek

          4、Auto Close Tag/Auto Rename Tag

          Close tag是自動補全html標簽,如輸入<a>將自動補全</a>

          Rename tag是自動重命名html標簽,如修改<a>為<b>,將自動修改結尾標簽</a>為</b>

          auto close tag

          auto rename tag

          5、Beautify

          聽名字都知道,格式化javascript,json,css,sass和HTML。

          6、Chinese (Simplified) Language Pack

          適用于vs code的中文簡體語言包

          部分截圖

          7、tag:icon-theme

          搜索標題文字的話,可以查到不同文件夾的圖標類型,這個的話可以根據個人的喜好選擇,沒有說哪種更好,只有更適合自己的。

          8、ESLint

          ESLint可以幫助我們檢查javascript編程時的語法錯誤并進行提示,找到bug并確保一定程序的語法書寫的正確性和規范性。

          9、React code snippets/vue2 snippets

          react和vue書寫時的代碼片段提示及填充。


          除了以上這些比較熱門的插件,vs code還有好多好用的插件需要大家去發掘。小編就不在這里一一列出了,大家如果有一些好用的可以在下方評論推薦哦。希望大家多關注關注小編。謝謝咯??!

          么是自動補全

          隨用戶輸入,給與提示信息,如下圖:

          ES實現原理

          ?戶每輸??個 字符,就需要即時發送?個查詢請求到后段查找匹配項。

          對性能要求?較苛刻。Elasticsearch 采?FST,FST 會被 ES 整個加載進內存, 速度很快。

          實現方式:

          Completion Suggester 實現

          1.定義 Mapping,使? “completion” type

          2.索引數據

          3.運? “suggest” 查詢,得到搜索建議。

          例子

          1.定義 Mapping,使? “completion” type

          DELETE inputcompletion
          # 設置mapping
          PUT inputcompletion
          {
            "mappings": {
              "_doc": {
                  "properties": {
                    "input_completion": {
                      "type": "completion"
                    }
                  }
                }
            }
          }

          2.索引數據

          POST inputcompletion/_doc/_bulk
          { "index" : { } }
          { "input_completion": "elasticsearch 教程"}
          { "index" : { } }
          { "input_completion": "elasticsearch api 中文"}
          { "index" : { } }
          { "input_completion": "elasticsearch"}

          3.運? “suggest” 查詢,得到搜索建議。

          POST inputcompletion/_doc/_search?pretty
          {
            "size": 0,
            "suggest": {
              "input-suggester": {
                "prefix": "ela",
                "completion": {
                  "field": "input_completion"
                }
              }
            }
          }

          結果

          {
            "took": 3,
            "timed_out": false,
            "_shards": {
              "total": 5,
              "successful": 5,
              "skipped": 0,
              "failed": 0
            },
            "hits": {
              "total": 0,
              "max_score": 0,
              "hits": []
            },
            "suggest": {
              "input-suggester": [
                {
                  "text": "ela",
                  "offset": 0,
                  "length": 3,
                  "options": [
                    {
                      "text": "elasticsearch",
                      "_index": "inputcompletion",
                      "_type": "_doc",
                      "_id": "ezqix3cBMB6-gr9-ORLt",
                      "_score": 1,
                      "_source": {
                        "input_completion": "elasticsearch"
                      }
                    },
                    {
                      "text": "elasticsearch api 中文",
                      "_index": "inputcompletion",
                      "_type": "_doc",
                      "_id": "ejqix3cBMB6-gr9-ORLt",
                      "_score": 1,
                      "_source": {
                        "input_completion": "elasticsearch api 中文"
                      }
                    },
                    {
                      "text": "elasticsearch 教程",
                      "_index": "inputcompletion",
                      "_type": "_doc",
                      "_id": "eTqix3cBMB6-gr9-ORLt",
                      "_score": 1,
                      "_source": {
                        "input_completion": "elasticsearch 教程"
                      }
                    }
                  ]
                }
              ]
            }
          }

          Context Suggester帶上下文的推薦

          例如:再手機品類下搜索,小米提示小米手機,再食品下,提示真空小米

          定義兩種類型的 Context

          Category – 任意的字符串

          Geo – 地理位置信息

          實現 Context Suggester 的具體步驟

          1.定制?個 Mapping 索引數據

          2.并且為每個?檔加? Context 信息

          3.結合 Context 進? Suggestion 查詢

          例子

          1. 定制?個 Mapping 索引數據

          DELETE inputcompletion
          
          PUT inputcompletion
          {
            "mappings": {
              "_doc": {
                  "properties": {
                    "input_completion": {
                      "type": "completion",
                      "contexts":[{
                        "type":"category",
                        "name":"goods_category"
                      }]
                    }
                  }
                }
            }
          }

          2.并且為每個?檔加? Context 信息

          POST inputcompletion/_doc
          {
            "comment":"小米手機",
            "input_completion":{
              "input":["小米"],
              "contexts":{
                "goods_category":"手機"
              }
            }
          }
          
          POST inputcompletion/_doc
          {
            "comment":"真空小米",
            "input_completion":{
              "input":["小米"],
              "contexts":{
                "goods_category":"食品"
              }
            }
          }

          3. 結合 Context 進? Suggestion 查詢

          POST inputcompletion/_search
          {
            "suggest": {
              "MY_SUGGESTION": {
                "prefix": "小米",
                "completion":{
                  "field":"input_completion",
                  "contexts":{
                    "goods_category":"食品"
                  }
                }
              }
            }
          }

          結果

          {
            "took": 3,
            "timed_out": false,
            "_shards": {
              "total": 5,
              "successful": 5,
              "skipped": 0,
              "failed": 0
            },
          
            "hits": {
              "total": 0,
              "max_score": 0,
              "hits": []
            },
          
            "suggest": {
          
              "MY_SUGGESTION": [
                {
                  "text": "小米",
                  "offset": 0,
                  "length": 2,
                  "options": [
                    {
                      "text": "小米",
                      "_index": "inputcompletion",
                      "_type": "_doc",
                      "_id": "bjqgx3cBMB6-gr9-vBL2",
                      "_score": 1,
                      "_source": {
                        "comment": "真空小米",
                        "input_completion": {
                          "input": [
                            "小米"
                          ],
                          "contexts": {
                            "goods_category": "食品"
                          }
                        }
                      },
                      "contexts": {
                        "goods_category": [
                          "食品"
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          }
          

          參考

          https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search-suggesters-completion.html

          https://www.elastic.co/guide/en/elasticsearch/reference/7.1/suggester-context.html


          主站蜘蛛池模板: 国产精品合集一区二区三区| 国产亚洲福利精品一区| 在线视频亚洲一区| 精品国产一区二区三区久久蜜臀| 国产一区二区三区精品视频| 亚洲福利一区二区精品秒拍| 亚洲美女一区二区三区| 精品无码人妻一区二区三区不卡| 精品国产一区二区三区四区| 国产福利电影一区二区三区久久久久成人精品综合 | 日韩精品电影一区亚洲| 无码AV天堂一区二区三区| 国产一区风间由美在线观看| 无码乱码av天堂一区二区| 中文字幕在线视频一区 | 精品一区二区三区| 无码一区二区三区爆白浆| 亚洲视频免费一区| 日韩精品一区二区三区中文| 一区二区在线视频观看| 亚洲AV无码一区二三区| 亚洲av区一区二区三| 国产凸凹视频一区二区| 国产精品无码一区二区在线观| 中文字幕无线码一区2020青青| 久久91精品国产一区二区| 国产精品久久久久久一区二区三区| 99久久精品午夜一区二区| 99精品国产一区二区三区2021| 无码精品人妻一区| 一区二区三区在线免费| 国产伦精品一区二区免费| 美女一区二区三区| 精品一区二区三区东京热| 欧美日韩精品一区二区在线观看| 国产日韩视频一区| 无码人妻精品一区二区三18禁| 麻豆果冻传媒2021精品传媒一区下载| 亚洲性无码一区二区三区| 色视频综合无码一区二区三区| 夜夜嗨AV一区二区三区|