Extension:CodeMirror
- 请勿与CodeEditor混淆。
发行状态: 稳定版 |
|
|---|---|
| 实现 | 用户界面 |
| 描述 | 为编辑器提供语法高亮 |
| 作者 | |
| 维护者 | Community Tech |
| 最新版本 | 6.0.0 |
| 兼容性政策 | 快照跟随MediaWiki发布。 master分支不向后兼容。 |
| PHP | 7.4+ |
|
|
| 许可协议 | GNU通用公眾授權條款2.0或更新版本 |
| 下載 | README |
| 帮助 | Help:Extension:CodeMirror/zh |
| 前往translatewiki.net翻譯CodeMirror扩展 | |
| 問題 | 开启的任务 · 报告错误 |
CodeMirror扩展提供一個獨立的編輯器,其使用CodeMirror函式库提供多種程式語言和標記語言(包括wikitext)的语法高亮。 它可以與其他的編輯器一起使用,例如WikiEditor、2017 wikitext編輯器、校对页面,以及更多。 有關用法和功能清單,請參閱Help:Extension:CodeMirror。
2024~2025年,此擴充功能升級到新的主要版本,『CodeMirror 6,並隨之增加了許多新的功能。
- 有關舊版本的資訊,請參閱Extension:CodeMirror/5。
- 有關說明文件,請參閱 Help:Extension:CodeMirror。
- 有關JavaScript的文件,請參閱 wmdoc:CodeMirror。
安裝
- 下载文件,并解压
CodeMirror文件夹到extensions/目录中。
开发者和代码贡献人员应改从Git安装此扩展,输入:cd extensions/ git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/CodeMirror
- 請新增下列代码到您的LocalSettings.php文件的底部:
wfLoadExtension( 'CodeMirror' );
- Configure as required.
完成 – 請导航至您的wiki上的Special:Version,以验证此扩展已成功安装。
配置
若要在預設情況下為所有使用者啟用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- 控制著所有使用者預設啟用哪些功能。 使用
true或false,來完整啟用或完全停用某項功能、或是來提供包含命名空間ID(整數)或內容模型(字串)的陣列。 例如,若要將自動完成功能僅限在JavaScript頁面和模板有效,您可以使用:
# Limit CodeMirror autocompletion to JavaScript pages and templates
$wgCodeMirrorDefaultPreferences[ 'autocomplete' ] = [ CONTENT_MODEL_JAVASCRIPT, NS_TEMPLATE ];
| 功能 | 2017編輯器 兼容性 |
默认值 |
|---|---|---|
activeLine |
| |
autocomplete |
| |
autofocus |
| |
bidiIsolation |
| |
bracketMatching |
| |
codeFolding |
| |
closeBrackets |
| |
highlightRefs |
| |
lineNumbering |
| |
lineWrapping |
| |
lint |
| |
openLinks |
| |
specialChars |
| |
whitespace |
|
與 CodeMirror 5 的差異
新功能
- 不再需要使用WikiEditor。
- 支援Scribunto、JavaScript、CSS、JSON、和Vue,可作為CodeEditor的替代。
- 效能大幅提升。
- 具有雙向文字隔離的由右至左文字的支援(T170001)。 (T358804)
- 代碼折疊。 (T30684)
- 自動完成。 (T95100)
- 程式碼格式檢查工具。 (T381577)
- 使用修改鍵+按一下即可快速開啟連結. (T303392)
- 改善搜尋面板。 (T371436)
- CodeMirror 偏好設定。 (T359498)
- 在讨论工具中的高亮顯示語法。 (T407918)
- 在唯讀頁面上高亮顯示語法。 (T301615)
- 在Special:ExpandTemplates中的高亮顯示語法。 (T384148)
- 強大的JavaScript API可整合擴充功能、小工具、使用者的腳本。
各個廢棄以及其他的變更
- 資源加载器模組正在變更。請參閱遷移指南。
ext.CodeMirror.switch钩子已被廢棄。請改用ext.CodeMirror.toggle。.cm-mw-mnemonicCSS類別已更名為.cm-mw-html-entity。.cm-mw-template-name-mnemonic類別已移除。請改用.cm-mw-template-ground.cm-html-entity。.cm-mw-apostrophes-bold和.cm-mw-apostrophes-italicCSS類別已移除。請改用.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在維基上的安裝:
- Extension:VisualEditor--使用CodeEditor模組為其他與VisualEditor整合的擴充功能提供語法高亮功能(T400014):
- Extension:AbuseFilter(滥用过滤器)--依賴CodeEditor為濫用過濾器語法提供語法高亮顯示功能(T399673)。
- Extension:WikiLambda--依賴於CodeEditor的
ext.wikilambda.app模組(T400015)。
自 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' );
- 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
|
包含有javascript、json、css、vue、及lua模式。
|
ext.CodeMirror.v6.init(內部的) |
action=edit 请求的主要入口点。不用于外部用途。 |
ext.CodeMirror.visualEditor.init(內部的) |
CodeMirror與2017 wikitext編輯器的整合功能,僅限於維基文本格式。 |
使用钩子
您也可以使用前端的钩子與CodeMirror整合。這些钩子允許您在CodeMirror載入之前或之後執行程式碼,或對文件的變更做出反應。
| 钩子 | 描述 |
|---|---|
ext.CodeMirror.initialize
|
請在 CodeMirror 初始化之前調用。此方法可用於操作DOM以配合CodeMirror的需求。(例如:若您操作WikiEditor的DOM,可能需要使用此方法)。
参数
|
ext.CodeMirror.ready
|
在CodeMirror 始化完成後立即呼叫的。
参数
|
ext.CodeMirror.toggle
|
當CodeMirror被開啟或關閉時被呼叫的。
参数
|
ext.CodeMirror.destroy
|
在CodeMirror被摧毀且原始文字輸入區域恢復後立即被呼叫的。
参数
|
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.
参数
|
ext.CodeMirror.preferences.display(內部的) |
Fired when the preferences panel is constructed, just before it is displayed.
参数
|
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
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() );
} );
参见
- User:Remember the dot/Syntax highlighter
- Extension:VisualEditor
- Extension:WikiEditor
- Extension:CodeEditor
- c:Category:MediaWiki extension CodeMirror
注释
| 此扩展用于一个或多个维基媒体项目。 这可能意味着扩展足够稳定、运作足够良好,可以用在这样的高流量的网站上。 请在维基媒体的CommonSettings.php和InitialiseSettings.php配置文件中查找此扩展的名称以查看哪些网站安装了该扩展。 特定wiki上的已安装的扩展的完整列表位于Special:Version页面。 |
| 此扩展在以下wiki农场/托管网站和/或软件包中提供: |
- Stable extensions/zh
- User interface extensions/zh
- EditPage::showEditForm:initial extensions/zh
- EditPage::showReadOnlyForm:initial extensions/zh
- GetBetaFeaturePreferences extensions/zh
- GetPreferences extensions/zh
- PreferencesFormPreSave extensions/zh
- SpecialPageBeforeExecute extensions/zh
- UploadForm:initial extensions/zh
- GPL licensed extensions/zh
- Extensions in Wikimedia version control/zh
- All extensions/zh
- Pages using deprecated NoteTA template
- Extensions used on Wikimedia/zh
- Extensions included in Canasta/zh
- Extensions included in Fandom/zh
- Extensions included in Miraheze/zh
- Extensions included in MyWikis/zh
- Extensions included in ProWiki/zh
- Extensions included in Telepedia/zh
- Extensions included in wiki.gg/zh
- Syntax highlighting extensions/zh
