溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

vue中實(shí)現(xiàn)Monaco Editor自定義提示功能

發(fā)布時(shí)間:2020-09-29 17:43:06 來源:腳本之家 閱讀:711 作者:豬九咩 欄目:web開發(fā)

這次接到一個(gè)需求,要在瀏覽器的 IDE 中支持自定義提示功能,如下所示:

vue中實(shí)現(xiàn)Monaco Editor自定義提示功能

可以看到,它可以根據(jù)用戶輸入的內(nèi)容來一項(xiàng)一項(xiàng)排除,只顯示完全匹配的那一項(xiàng)。

項(xiàng)目的框架是 Vue ,編輯器用的是 Monaco Editor

什么是 Monaco Editor

vscode 是我們經(jīng)常在用的編輯器,它的前身是微軟的一個(gè)叫 Monaco Workbench 的項(xiàng)目,而 Monaco Editor 就是從這個(gè)項(xiàng)目中成長(zhǎng)出來的一個(gè) web 編輯器,他們很大一部分的代碼都是共用的,所以 Monaco EditorVSCode 在編輯代碼,交互及 UI 上幾乎是一摸一樣的。不同的是,兩者的平臺(tái)不一樣, Monaco Editor 基于瀏覽器,而 VSCode 基于 electron ,所以功能上 VSCode 更加健全,性能比較強(qiáng)大。

用法

安裝

npm install monaco-editor --save

使用

<div id="monaco" class="monaco-editor"></div>
import * as monaco from 'monaco-editor';
this.fileEditor = this.monaco.editor.create(document.getElementById('monaco'), {
 value: null,
 language: 'sql' // 這里以sql為例
})

this.fileEditor.dispose(); // 使用完后銷毀

這里引入 monaco 要注意,在 react 中以下面方式引入:

import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';

實(shí)現(xiàn)自定義提示功能

查看了資料后,發(fā)現(xiàn)在 monaco 中有提供一個(gè)提示功能的方法 registerCompletionItemProvider ,具體實(shí)現(xiàn)如下:

this.monaco.languages.registerCompletionItemProvider('sql', { // 這里以sql語言為例
 provideCompletionItems () {
  return [{
   label: '${_DB', // 顯示的提示內(nèi)容
   kind: this.monaco.languages.CompletionItemKind['Function'], // 用來顯示提示內(nèi)容后的不同的圖標(biāo)
   insertText: '{_DB', // 選擇后粘貼到編輯器中的文字
   detail: '' // 提示內(nèi)容后的說明
  }];
 },
 triggerCharacters: ['$'] // 觸發(fā)提示的字符,可以寫多個(gè)
});

以上的用法,我試了一下之后發(fā)現(xiàn),雖然 triggerCharacters 的值是數(shù)組,可以有多個(gè),但是里面的字符串只能識(shí)別一個(gè)字符。一開始的需求是輸入 ${_ 之后提示 ${_DB ,但是由于不能識(shí)別多個(gè)字符,只能做到出現(xiàn) $ 就提示。

還有一個(gè)問題就是 registerCompletionItemProvider 的第一個(gè)參數(shù)只能是字符串,如果有多種語言只能疊加重復(fù)寫,恰巧我的需求是有多種語言,所以只能如下解決,也就是每種語言都寫了一遍:

['json', 'yaml', 'php', 'go', 'sql', 'java', 'markdown', 'plaintext'].map(item => {
 this.monaco.languages.registerCompletionItemProvider(item, {
  provideCompletionItems () {
   return [{
    label: '${_DB',
    kind: this.monaco.languages.CompletionItemKind['Function'],
    insertText: '{_DB',
    detail: ''
   }];
  },
  triggerCharacters: ['$']
 });
});

需求是 ${_DB:key:value ,也就是說在輸入 ${_DB 后,再輸入一個(gè) : 提示出 key ,在 key 之后輸入 : 提示 value 。

這里又碰到一個(gè)問題,需要知道當(dāng)前輸入的內(nèi)容來判斷是 $ 還是 : ,而且后面兩個(gè)觸發(fā)提示的符號(hào)同是 : ,無法區(qū)分,只能通過識(shí)別 : 的位置來判斷是提示 key 還是 value ,所以還要知道當(dāng)前輸入的 : 之前的內(nèi)容。

那么只有在 provideCompletionItems 這一步判斷,但是查遍了資料沒有發(fā)現(xiàn)這樣的參數(shù), provideCompletionItems 只有 model 、 positiontoken 這幾個(gè)參數(shù),后來發(fā)現(xiàn) model 中的 getLineContent 方法可以獲取指定行的所有內(nèi)容,而 position 可以獲取當(dāng)前輸入行的行數(shù)和列數(shù),于是就有了以下解決方法:

this.monaco.languages.registerCompletionItemProvider(item, {
 provideCompletionItems (model, position) {
  // 獲取當(dāng)前行數(shù)
  const line = position.lineNumber
  
  // 獲取當(dāng)前列數(shù)
  const column = position.column
  
  // 獲取當(dāng)前輸入行的所有內(nèi)容
  const content = model.getLineContent(line)
  
  // 通過下標(biāo)來獲取當(dāng)前光標(biāo)后一個(gè)內(nèi)容,即為剛輸入的內(nèi)容
  const sym = content[column - 2]
  
  if (sym === '$') {
   return [{
    label: '${_DB',
    kind: this.monaco.languages.CompletionItemKind['Function'],
    insertText: '{_DB',
    detail: ''
   }];
  }
  
  return [{
   label: ':abb',
   kind: this.monaco.languages.CompletionItemKind['Function'],
   insertText: 'abb',
   detail: ''
  },
  {
   label: ':bc',
   kind: this.monaco.languages.CompletionItemKind['Function'],
   insertText: 'bc',
   detail: ''
  }];
 },
 triggerCharacters: ['$', ':']
});

能獲取光標(biāo)后的第一個(gè)內(nèi)容,后面的內(nèi)容就都能獲取啦,如果識(shí)別到前面的內(nèi)容是 ${_DB 就提示 key ,否則提示 value 。

最后總結(jié)下來就是一定要多看文檔,勤于測(cè)試就能解決問題啦~

總結(jié)

以上所述是小編給大家介紹的vue中實(shí)現(xiàn)Monaco Editor自定義提示功能 ,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)億速云網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI