vscode 自定義代碼片斷

實現效果

原由

最近在寫一個全新的項目,在項目中頻繁建立各類類,這就致使不少重複的東西須要頻繁的寫,例如類名,命名空間,繼承關係...那麼有沒有一種 辦法能解決這個問題呢?php

提出設想

我想起了,最初用 sublime text 的時候,能夠利用代碼片斷功能大段的生成html代碼,當時就以爲十分的方便,那麼 vscode 有沒有這個功能呢?通過 google 以後我知道 vscode 是有代碼片斷功能的。既然有了想法,也具有了基礎實施條件,那麼接下來開始嘗試實現以前的想法。html

資料查詢

通過一番 google 後發現對於 vscode snippet 介紹都在相對基礎的簡單應用(只是一些插入固定代碼和光標介紹),者顯然沒法實現咱們生成類名和明明空間的想法,google 無果,那麼只能看看 vscode 官方文檔果真有意想不到的收穫,看完官網介紹後,基本就肯定此路是可行的。linux

snippet 示例

File > Preferences (Code > Preferences on macOS) 中選擇 User Snippets 在彈出框裏選擇對應的代碼片斷語言,我這裏使用的是php正則表達式

"Print to console": {
         "prefix": "log",
         "body": [
             "console.log('$1');",
             "$2"
         ],
         "description": "Log output to console"
    }

在打開的 php.json 中有示例代碼:json

  • Print to console 代碼片斷名稱
  • prefix 插件前綴
  • body 插件內容能夠是字符串,也能夠爲數組,若爲數組每一個元素都作爲單獨的一行插入。
  • description 插件描述

Snippet 語法

製表位(Tabstops)

使用製表位(Tabstops)但是在代碼片斷中移動光標位置,使用$1,$2來指定光標的位置,數字表明光標的移動的順序,值得注意的時$0表明光標的最後位置。若是有多個相同的製表位(Tabstops)會在編譯器裏同時出現多個光標(相似編譯器的塊編輯模式)。windows

佔位符(Placeholders)

佔位符(Placeholders) 是帶默認值的製表位(Tabstops),佔位符(Placeholders)的文本會被插入到製表位(Tabstops)所在位置而且全選以方便修改,佔位符(Placeholders)能夠嵌套使用,好比${1:another ${2:placeholder}}數組

選擇項(Choice)

佔位符(Placeholders)能夠有多選值,每一個選項的值用 , 分隔,選項的開始和結束用管道符號(|)將選項包含,例如: ${1|one,two,three|},當插入代碼片斷,選擇制製表位(Tabstops)的時候,會列出選項供用戶選擇。app

變量(Variables)

使用 $name 或者 ${name|default} 能夠插入變量的值,若是變量未被賦值則插入 default 的值或者空值 。當變量未被定義,則將變量名插入,變量(Variables)將被轉換爲佔位符(Placeholders)
系統變量以下this

  • TM_SELECTED_TEXT 當前選定的文本或空字符串
  • TM_CURRENT_LINE 當前行的內容
  • TM_CURRENT_WORD 光標下的單詞的內容或空字符串
  • TM_LINE_INDEX 基於零索引的行號
  • TM_LINE_NUMBER 基於一索引的行號
  • TM_FILENAME 當前文檔的文件名
  • TM_FILENAME_BASE 當前文檔的文件名(不含後綴名)
  • TM_DIRECTORY 當前文檔的目錄
  • TM_FILEPATH 當前文檔的完整文件路徑
  • CLIPBOARD 剪切板裏的內容

插入當前日期或時間:google

  • CURRENT_YEAR 當前年(四位數)
  • CURRENT_YEAR_SHORT 當前年(兩位數)
  • CURRENT_MONTH 當前月
  • CURRENT_MONTH_NAME 本月的全名(’七月’)
  • CURRENT_MONTH_NAME_SHORT 月份的簡稱(’Jul’)
  • CURRENT_DATE 當前日
  • CURRENT_DAY_NAME 當天的名稱(’星期一’)
  • CURRENT_DAY_NAME_SHORT 當天的短名稱(’Mon’)
  • CURRENT_HOUR 當前小時
  • CURRENT_MINUTE 當前分鐘
  • CURRENT_SECOND 當前秒

當前語言的行註釋或塊註釋:

  • BLOCK_COMMENT_START 塊註釋開始標識,如 PHP /* 或 HTML <!--
  • BLOCK_COMMENT_END 塊註釋結束標識,如 PHP */ 或 HTML -->
  • LINE_COMMENT 行註釋,如: PHP // 或 HTML <!-- -->

下面片則會生成 PHP / Hello World /

{
    "hello": {
        "scope": "php",
        "prefix": "hello",
        "body": "$BLOCK_COMMENT_START Hello World $BLOCK_COMMENT_END"
    }
}

變量轉換(Variable transforms)

變量轉換(Variable transforms) 容許變量在插入前改變變量的值,變量轉換(Variable transforms)由三部分組成

  1. 正則匹配:使用正則表達式匹配變量值,若變量沒法解析則值爲空。
  2. 格式串:容許引用正則表達式匹配組。格式串容許條件插入和作簡單的修改。
  3. 正則表達式匹配選項

下面例子是使用變量轉換(Variable transforms)將帶後綴的文件名轉換爲不帶後綴的文件名

${TM_FILENAME/(.*)\\..+$/$1/}
  |           |         |  |
  |           |         |  |-> 無選項設置
  |           |         |
  |           |         |-> 引用捕獲組的第一個分組內容
  |           |             
  |           |
  |           |-> 匹配後綴前的全部字符串
  |               
  |
  |-> 文件名(帶後綴)

需求實現

要解決的問題

生成Class 的命名空間、類名、選擇繼承關係

問題分析

項目目錄結構以下所示

peoject
|
|----application
|--------admin
|------------services
|----------------TestServices.php

類名能夠直接使用 TM_FILENAME_BASE 變量的值便可,命名空間則須要使用 TM_DIRECTORY 變量,以 TestServices.php 爲例,TM_DIRECTORY 獲得的目錄爲 peoject\application\admin\services咱們只須要將peoject\application\ 替換爲 app 獲得 app\admin\services 就是咱們的明明空間了,至於繼承就是一個選擇項就能夠了。既然已經所有知道該如何實現,接下來就是代碼實現的過程了。

代碼實現

"service-construct" :{
        "prefix": "gen",
        "body": [
            "namespace ${TM_DIRECTORY/.*application/app/};\n",
            "class $TM_FILENAME_BASE extends ${1|BaseService,BaseController,BaseModel|}",
            "{",
            "\tpublic function __construct() \r\n    {\n\t\t\\$this->model = new \r\n\t}",
            "}"
        ],
        "description": "generate service class"

    },

一些思考

上述代碼基本上完成了我要實現的功能,可是也存在了一些問題,例如:我如今是用 windows 操做系統,於是TM_DIRECTORY 獲得的目錄爲 peoject\application\admin\services 如果 linux 系統,此代碼片斷是沒法正常的生成命名空間的,我作了一些資料的搜索,代碼片斷並無自定義變量的功能(也許能夠,只是我麼有找到方法,若是有知道的大牛,請留言賜教。
隨着對 vscode snippet 的深刻了解,我以前所設想的方案要用代碼片斷的方式實現是有些困難的,vscode 將其做爲一個快速生成代碼的解決方案,咱們所寫的代碼片斷至關於一個帶有填空模板,而對代碼片斷的應用就是生成帶有製表符的代碼模板,而後根據製表符順序補全代碼。
至於這個不完美的方案,我打算再研究一下代碼片斷是否能徹底實現,若是依舊解決不了,就選用其它方案進行嘗試。

參考連接

Creating your own snippets

相關文章
相關標籤/搜索