Jump to content

Extension:CodeMirror

本頁使用了標題或全文手工轉換
From mediawiki.org
This page is a translated version of the page Extension:CodeMirror and the translation is 85% complete.
请勿与CodeEditor 混淆。
本頁面涵蓋了最新版本CodeMirror 6。 它計劃在MediaWiki 1.46 中取代掉CodeMirror 5。 想要了解如何切換到CodeMirror 6,請參閱遷移指南


MediaWiki扩展手册
CodeMirror
发行状态: 稳定版
实现 用户界面
描述 为编辑器提供语法高亮
作者
维护者 Community Tech
最新版本 6.0.0
兼容性政策 快照跟随MediaWiki发布。 master分支不向后兼容。
PHP 7.4+
  • $wgCodeMirrorV6
  • $wgCodeMirrorPrimaryPreferences
  • $wgCodeMirrorTitleCompletion
  • $wgCodeMirrorConflictingGadgets
  • $wgCodeMirrorEnabledModes
  • $wgCodeMirrorDefaultPreferences
  • $wgCodeMirrorLineNumberingNamespaces
许可协议 GNU通用公眾授權條款2.0或更新版本
下載
README
帮助 Help:Extension:CodeMirror/zh
前往translatewiki.net翻譯CodeMirror扩展
問題 开启的任务 · 报告错误


CodeMirror扩展提供一個獨立的編輯器,其使用CodeMirror函式库提供多種程式語言和標記語言(包括wikitext)的语法高亮。 它可以與其他的編輯器一起使用,例如WikiEditor 2017 wikitext編輯器 校对页面 ,以及更多。 有關用法和功能清單,請參閱Help:Extension:CodeMirror

2024~2025年,此擴充功能升級到新的主要版本,『CodeMirror 6,並隨之增加了許多新的功能

安裝

  • 下载文件,并解压CodeMirror文件夹到extensions/目录中。
    开发者和代码贡献人员应改从Git安装此扩展,输入:
    cd extensions/
    git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/CodeMirror
    
  • 請新增下列代码到您的LocalSettings.php 文件的底部:
    wfLoadExtension( 'CodeMirror' );
    
  • Configure as required.
  • Yes 完成 – 請导航至您的wiki上的Special:Version,以验证此扩展已成功安装。

配置

有關顏色和各種CodeMirror功能的自訂,請參閱Help:Extension:CodeMirror .

若要在預設情況下為所有使用者啟用CodeMirror,請將下列內容加入到你的LocalSettings.php 中:

# Enables use of CodeMirror by default but still allow users to disable it
$wgDefaultUserOptions[ 'usecodemirror' ] = true;
$wgCodeMirrorV6
控制著遷移至CodeMirror 6的臨時功能旗標(T259059)。
$wgCodeMirrorEnabledModes
控制著與Extension:CodeEditor 衝突的臨時功能旗號。 請參閱下方的用CodeMirror取代CodeEditor節以獲取更多資訊。
$wgCodeMirrorConflictingGadgets
小工具名稱的陣列,如果啟用,會阻止載入CodeMirror。預設的設定為wikEd
$wgCodeMirrorPrimaryPreferences
編輯器內的偏好設定 面板中的廣告選項。這些選項應具備明顯視覺效果或因普遍使用而值得提供更便捷的切換方式。「未」列於此處的偏好設定仍可在完整的偏好設定對話框中存取。
$wgCodeMirrorDefaultPreferences
控制著所有使用者預設啟用哪些功能 。 使用truefalse,來完整啟用或完全停用某項功能、或是來提供包含命名空間ID(整數)或內容模型(字串)的陣列。 例如,若要將自動完成功能僅限在JavaScript頁面和模板有效,您可以使用:
# Limit CodeMirror autocompletion to JavaScript pages and templates
$wgCodeMirrorDefaultPreferences[ 'autocomplete' ] = [ CONTENT_MODEL_JAVASCRIPT, NS_TEMPLATE ];
$wgCodeMirrorDefaultPreferences
功能 2017編輯器
兼容性
默认值
activeLine N false
autocomplete N true
autofocus Yes[1] true
bidiIsolation N false
bracketMatching Yes true
codeFolding N true
closeBrackets N true
highlightRefs Yes true
lineNumbering Yes true
lineWrapping Yes[2] true
lint N ['json','css','javascript','lua','vue']
openLinks N true
specialChars N true
whitespace N false

與 CodeMirror 5 的差異

新功能

各個廢棄以及其他的變更

  • 資源加载器模組正在變更。請參閱遷移指南
  • ext.CodeMirror.switch钩子已被廢棄。請改用ext.CodeMirror.toggle
  • .cm-mw-mnemonic CSS類別已更名為.cm-mw-html-entity
  • .cm-mw-template-name-mnemonic類別已移除。請改用.cm-mw-template-ground.cm-html-entity
  • .cm-mw-apostrophes-bold.cm-mw-apostrophes-italic CSS類別已移除。請改用.cm-mw-apostrophes
  • 針對<nowiki><pre>、或任何與TagMode 無關的標籤的單行等級設計已移除(T351686)。
  • wikitext內的混合語言目前尚未支援(T357480)。
  • 瀏覽器的原生搜尋功能(使用 Ctrl+F)已被CodeMirror內建的搜尋功能取代。這是維持效能所必需的 (T303664)。

遷移指南

MediaWiki版本:
1.44

本指南適用於MediaWiki 1.45版及後續版本。所有整合功能應以在MediaWiki 1.46版(發行時程表 )發行時完成遷移為目標。

MediaWiki的組態

  • $wgCodeMirrorLineNumberingNamespaces 已被廢棄。請改設定$wgCodeMirrorDefaultPreferences

资源加载模組

請確保您是在使用新版的 .v6 模組 。 由於 CodeMirror 6 不再依賴 WikiEditor,因此相較於 CodeMirror 5 的對應功能,存在以下命名與行為上的變更:

為簡化起見,部份模組名稱並未顯示前綴ext.CodeMirror;使用時請將『…』替換為實際參數。

舊模組 新模組(MW 1.44) 新模組(MW 1.45) 新模組(MW 1.46以上) 描述
ext.CodeMirror ….v6.WikiEditor.init ….v6.init ….init 為WikiEditor整合 CodeMirror 功能(在 #wpTextbox1 處的標準的文字輸入區域)。
N/A ….v6.WikiEditor ….v6.WikiEditor ….WikiEditor 匯出CodeMirrorWikiEditor類別
N/A ….v6.init ….v6.init ….init CodeMirror用於#wpTextbox1及其它受支援頁面。
….lib ….v6.init ….v6.init ….lib 匯出CodeMirror的內部元件。
….addons N/A N/A N/A 這包裝了CodeMirror 5中的括弧匹配功能。在CodeMirror 6中,括號匹配是預設行為。
….mode.mediawiki ….v6.mode.mediawiki ….v6.mode.mediawiki ….mode.mediawiki MediaWiki語言模式。
N/A ext.CodeMirror.v6 ext.CodeMirror.v6 ext.CodeMirror 匯出CodeMirror類別。
….visualEditor ….visualEditor.init ….visualEditor.init ….init 整合2017 wikitext編輯器
….lib.mode.php N/A N/A CodeMirror 6最終將提供部份或全部這些模式,但它們不會以獨立模組的形式提供。
….lib.mode.clike
….lib.mode.htmlmixed
….lib.mode.xml
….lib.mode.javascript ….v6.mode.javascript ….v6.modes ….modes 這些語言在CodeMirror 6中有支援。
….lib.mode.css ….v6.mode.css
N/A ….v6.mode.lua
N/A ….v6.mode.json
N/A ….v6.mode.vue

隨著 MediaWiki 1.46 的發佈,舊版模組將被新版模組取代,而 .v6 模組在完全移除前,將有一段時間維持別名狀態。

小工具與使用者腳本

CodeMirror的全域功能已完全取消。 舉例來說,CodeMirror.fromTextArea( myTextarea )將不再有用。 取而代之的是,請先載入所需的资源加载模組 ,實例化物件CodeMirror、然後呼叫方法initialize()

若您的腳本依賴勾點ext.CodeMirror.switch來改變其與編輯器的互動方式,則需改用ext.CodeMirror.toggle、或改為監聽事件。 請參閱JavaScript整合部份以獲取更多資訊。

CSS

元素.CodeMirror已不復存在。請改用.cm-editor以應對CodeMirror DOM,或使用.cm-content以應對內部的內容(例如不包含搜尋面板)。

請參見過時功能及其他變更 以了解其他的CSS類別。

整合

MediaWiki扩展

用CodeMirror取代CodeEditor

MediaWiki版本:
1.44

自 MediaWiki 1.44 起,CodeMirror 支援 Lua、JavaScript、CSS、JSON、及Vue語言的語法高亮功能。此功能可作為 Extension:CodeEditor 的替代方案。

請注意,並非所有與 CodeEditor 整合的擴充功能都已更新到能支援CodeMirror。若您正在使用這些擴充功能,建議您保留CodeEditor在維基上的安裝:

自 MediaWiki 1.45 起,為使此設定生效,您需相應調整 $wgCodeMirrorEnabledModes 變數,同時針對已安裝的相關擴充功能調整 *UseCodeEditor*UseCodeMirror 變數:

// Desired modes that should use CodeMirror (mediawiki, i.e. wikitext, is enabled by default)
$wgCodeMirrorEnabledModes['javascript'] = true;
$wgCodeMirrorEnabledModes['json'] = true;
$wgCodeMirrorEnabledModes['css'] = true;
$wgCodeMirrorEnabledModes['lua'] = true;
$wgCodeMirrorEnabledModes['vue'] = true;

// If you're also using CodeEditor, disable the same modes there:
$wgCodeEditorEnabledModes['javascript'] = false;
$wgCodeEditorEnabledModes['json'] = false;
$wgCodeEditorEnabledModes['css'] = false;
$wgCodeEditorEnabledModes['lua'] = false;
$wgCodeEditorEnabledModes['vue'] = false;

// Gadgets (for editing Gadget definition JSON pages)
$wgGadgetsDefinitionsUseCodeEditor = false;
$wgGadgetsDefinitionsUseCodeMirror = true;

// JsonConfig
$wgJsonConfigUseCodeEditor = false;
$wgJsonConfigUseCodeMirror = true;

// Scribunto (for editing Module pages that use the "lua" mode)
$wgScribuntoUseCodeEditor = false;
$wgScribuntoUseCodeMirror = true;

// TemplateStyles
$wgTemplateStylesUseCodeEditor = false;
$wgTemplateStylesUseCodeMirror = true;

// UploadWizard (for editing Campaign JSON pages)
$wgUploadWizardUseCodeEditor = false;
$wgUploadWizardUseCodeMirror = true;

為MediaWiki註冊一個新標籤

若您僅需讓CodeMirror識別由擴充套件新增的標籤 ,可透過CodeMirrorTagModes擴充功能屬性 來達成。 例如,欲將標籤‎<foo>註冊為包含維基文本格式之標籤,請於extension.json中新增以下內容:

{
	"attributes": {
		"CodeMirror": {
			"TagModes": [
				"foo": "mediawiki"
			]
		}
	}
}

CodeMirror 隨後將把 ‎<foo>...‎</foo> 內的內容標示為維基文本。

註冊一個標籤使得CodeMirror將內容視為非維基文本,目前尚不支援(T357480)。若未註冊該標籤,CodeMirror 將以與標示 ‎<nowiki>...‎</nowiki> 標籤內容相同的方式,將內容標示為非維基文本。

PHP钩子

MediaWiki版本:
1.44

自MediaWiki 1.44起,在PHP中與CodeMirror整合的首選方式是實作這個CodeMirrorGetModeHook介面:

class CodeMirrorHooks implements CodeMirrorGetModeHook {
	public function onCodeMirrorGetMode(Title $title, ?string &$mode, string $model ): bool {
		// Logic to determine if CodeMirror should be used
		if ( $title->hasContentModel( 'JsonLikeContentModel' ) ) {
			$mode = 'json';
			return false;
		}

		return true;
	}
}

在extension.json中註冊钩子:

"Hooks": {
	"CodeMirrorGetMode": "codemirror"
},
"HookHandlers": {
	"codemirror": {
		"class": "MediaWiki\\Extension\\MyExtension\\CodeMirrorHooks"
	}
}

插件模組

CodeMirrorPluginModules 是一個擴充功能屬性 ,可讓CodeMirror旁載一個模組。 此設定會在每次載入 ext.CodeMirror.v6 模組時,無條件地載入該模組。

extension.json:

{
	"attributes": {
		"CodeMirror": {
			"PluginModules": [
				"ext.MyExtension.CodeMirror"
			]
		}
	}
}


JavaScript

CodeMirror編輯器並非真正的文字輸入區域,而是一個可編輯內容。開發人員通常需確保程式碼能同時支援這兩種情境,因為CodeMirror可被關閉

要偵測文件的變更,使用事件鉤子可能是最簡單的方法。若需讀取與修改變更d 內容,jQuery.textSelection可能較為便利。

若需更複雜的整合方案,或追求更優異的效能表現,您可為新建立或現有的 CodeMirror 實例新增自訂的擴充功能

使用jQuery.textSelection

若您僅需擷取或修改文件的文字內容,jQuery.textSelection便是最簡易且最可靠的方法。 在文字輸入區使用jQuery.textSelection會向上冒泡至CodeMirror,因此您無需知道CodeMirror是否已啟用:

const $textarea = $( '#wpTextbox1' )
const content = $textarea.textSelection( 'getContents' );
// Append "Foobar" to the content.
$textarea.textSelection( 'setContents', content + '\nFoobar' );
  1. wpTextbox1上的jQuery的.val()函式「可」被使用,[3]但不建議如此操作,且可能無法在所有編輯器(例如 2017 wikitext編輯器 )中正常運作。

運用资源加载模組

CodeMirror擴充功能提供多個 资源加载器 模組,給使用者腳本、小工具、及擴充功能使用。若要運用 CodeMirror,您至少需要有ext.CodeMirror.v6模組、搭配你所需的「模式」。

模式可從资源加载模組中解壓縮,其使用與模式名稱相同的匯出方法。 對於 MediaWiki 維基文本,您應該會使用 ext.CodeMirror.v6.mode.mediawiki;而對於 JavaScript、JSON、CSS、Vue、和Lua,則應該會使用 ext.CodeMirror.v6.modes

const require = await mw.loader.using( [ 'ext.CodeMirror.v6', 'ext.CodeMirror.v6.mode.mediawiki' ] );
const CodeMirror = require( 'ext.CodeMirror.v6' );
const { mediawiki } = require( 'ext.CodeMirror.v6.mode.mediawiki' );
const cm = new CodeMirror( myTextarea, mediawiki() );
cm.initialize();

若您也想要WikiEditor:

const require = await mw.loader.using( [
	'ext.wikiEditor',
	'ext.CodeMirror.v6.WikiEditor',
	'ext.CodeMirror.v6.mode.mediawiki'
] );
const textarea = document.getElementById( 'wpTextbox1' );
mw.addWikiEditor( $( textarea ) );
const CodeMirrorWikiEditor = require( 'ext.CodeMirror.v6.WikiEditor' );
const { mediawiki } = require( 'ext.CodeMirror.v6.mode.mediawiki' );
const cmWe = new CodeMirrorWikiEditor( textarea, mediawiki() );
cmWe.mode = 'mediawiki';
cmWe.initialize();

請建立一個新的JavaScript實例:

const require = await mw.loader.using( [ 'ext.CodeMirror.v6', 'ext.CodeMirror.v6.modes' ] );
const CodeMirror = require( 'ext.CodeMirror.v6' );
const { javascript } = require( 'ext.CodeMirror.v6.modes' );
const cm = new CodeMirror( myTextarea, javascript() );
cm.initialize();
资源加载模組
模組 描述
ext.CodeMirror.v6.lib 核心 CodeMirror 函式庫,你不會直接需要此函式庫,除非您需要存取上游的CodeMirror API
ext.CodeMirror.v6 MediaWiki編輯器的基礎的CodeMirror整合模組。此模組是匯出CodeMirror類別。
ext.CodeMirror.v6.WikiEditor WikiEditor的CodeMirror整合模組。此模組是匯出CodeMirrorWikiEditor類別。
ext.CodeMirror.v6.mode.mediawiki 導出用於高亮顯示MediaWiki wiki文字的 mediawiki 模式。
ext.CodeMirror.v6.modes 包含有javascriptjsoncssvue、及lua模式。
ext.CodeMirror.v6.init
(內部的)
action=edit 请求的主要入口点。不用于外部用途。
ext.CodeMirror.visualEditor.init
(內部的)
CodeMirror與2017 wikitext編輯器 的整合功能,僅限於維基文本格式。

使用钩子

您也可以使用前端的钩子與CodeMirror整合。這些钩子允許您在CodeMirror載入之前或之後執行程式碼,或對文件的變更做出反應。

前端的钩子
钩子 描述
ext.CodeMirror.initialize 請在 CodeMirror 初始化之前調用。此方法可用於操作DOM以配合CodeMirror的需求。(例如:若您操作WikiEditor的DOM,可能需要使用此方法)。

参数

  • (HTMLTextAreaElement) 當前的「編輯器」,最可能是#wpTextbox1.
  • (ve.ui.Surface) 若適用的話,它是CodeMirror所綁定的視覺編輯器表面。
ext.CodeMirror.ready 在CodeMirror 始化完成後立即呼叫的。

参数

ext.CodeMirror.toggle 當CodeMirror被開啟或關閉時被呼叫的。

参数

  • (boolean) CodeMirror 是否已啟用。
  • (CodeMirror) CodeMirror 實例。
  • (HTMLTextAreaElement) The original textarea.
ext.CodeMirror.destroy 在CodeMirror被摧毀且原始文字輸入區域恢復後立即被呼叫的。

参数

  • (HTMLTextAreaElement) 原始的文字輸入區。
ext.CodeMirror.input 當 CodeMirror 中的文件內容發生變更時被呼叫的。請注意,此時文字輸入區可能尚未更新。

参数

ext.CodeMirror.preferences.ready CodeMirrorPreferences 實例化之前被觸發的。

参数

ext.CodeMirror.preferences.apply CodeMirror的偏好設定被啟用或初始套用時被觸發的。

参数

ext.CodeMirror.preferences.apply Fired when a CodeMirror preference is changed or initially applied in an editing session.

参数

  • (string) 偏好設定的名稱。
  • (boolean) The new value of the preference.
ext.CodeMirror.preferences.display
(內部的)
Fired when the preferences panel is constructed, just before it is displayed.

参数

  • (HTMLDivElement) 偏好設定的面板容器。
ext.CodeMirror.gotoLine
(內部的)
Fired when the go-to line panel is opened or closed.
ext.CodeMirror.keymap
(內部的)
Fired when the keyboard shortcut help dialog is opened.
ext.CodeMirror.search
(內部的)
Fired when the search panel is opened or closed.


Using events

The following events are bubbled to the textarea for developer convenience:

Using these events, you can integrate with CodeMirror using the same code as the original textarea:

myTextarea.addEventListener( 'keyup', ( event ) => {
	console.log( event.key );
} );

Extending CodeMirror

You can import the ext.CodeMirror.v6.lib module to get access to the upstream CodeMirror API. With this you can provide your own Extension when instantiating a CodeMirror or CodeMirrorWikiEditor instance.

For example, to provide your own Extension that reacts to changes made in CodeMirror:

const require = await mw.loader.using( [ 'ext.CodeMirror.v6', 'ext.CodeMirror.v6.mode.mediawiki' ] );
const CodeMirror = require( 'ext.CodeMirror.v6' );
const { mediawiki } = require( 'ext.CodeMirror.v6.mode.mediawiki' );
// ext.CodeMirror.v6.lib is a dependency of ext.CodeMirror.v6, so it's already loaded at this point.
const { EditorView } = require( 'ext.CodeMirror.v6.lib' );
const myExtension = EditorView.updateListener.of( ( /** @type {ViewUpdate} */ update ) => {
	if ( update.docChanged ) {
	    // do something
	    console.log( update.changes );
	}
} );
const cm = new CodeMirror( myTextarea, mediawiki() );
cm.initialize( [ cm.defaultExtensions, myExtension ] );

Or if you need to interact with an existing CodeMirror instance:

// Ensure CodeMirror is initialized first
mw.hook( 'ext.CodeMirror.ready' ).add( ( cm ) => {
	const { EditorView } = require( 'ext.CodeMirror.v6.lib' );
	const myExtension = EditorView.updateListener.of( ( /** @type {ViewUpdate} */ update ) => {
		if ( update.docChanged ) {
		    // do something
		    console.log( update.changes );
		}
	} );
	cm.applyExtension( myExtension );
} );

Another means of listening to changes is using the ext.CodeMirror.input hook :

mw.hook( 'ext.CodeMirror.input' ).add( ( update ) => {
	// Print the ChangeSet to the console
	console.log( update.changes.toJSON() );
} );

参见

注释

  1. 在2017編輯器中,焦點始終被安置於編輯器之上。
  2. 在2017編輯器中,無法停用換行功能。
  3. phab:T384556
  4. This event is not fired for wikitext (T401271)