Extension:CodeMirror
![]() Release status: stable |
|
---|---|
![]() |
|
Implementation | User interface |
Description | Provides syntax highlighting in editors |
Author(s) | |
Maintainer(s) | Community Tech |
Latest version | 6.0.0 |
Compatibility policy | Snapshots releases along with MediaWiki. Master is not backward compatible. |
PHP | 7.4+ |
License | GNU General Public License 2.0 or later |
Download | README |
Help | Help:Extension:CodeMirror |
|
|
Quarterly downloads | 288 (Ranked 13th) |
Public wikis using | 6,549 (Ranked 62nd) |
Translate the CodeMirror extension if it is available at translatewiki.net | |
Issues | Report a bug |
The CodeMirror extension provides CodeMirror library. For usage and a list of features, see Help:Extension:CodeMirror .
In 2024, the extension was upgraded to the new major version, CodeMirror 6, and with it many new features were added.
Usage
[edit]For usage of this extension, see Help:Extension:CodeMirror .
For the JavaScript documentation, see docs.wikimedia.org/CodeMirror.
Installation
[edit]- Download and move the extracted
CodeMirror
folder to yourextensions/
directory.
Developers and code contributors should install the extension from Git instead, using:cd extensions/
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/CodeMirror - Add the following code at the bottom of your LocalSettings.php file:
wfLoadExtension( 'CodeMirror' );
- Configure as required.
Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.
Configuration
[edit]To enable CodeMirror for all users by default, add the following to your LocalSettings.php :
# Enables use of CodeMirror by default but still allow users to disable it
$wgDefaultUserOptions[ 'usecodemirror' ] = true;
- $wgCodeMirrorV6
- Temporary feature flag to control the migration to CodeMirror 6 (T259059).
- $wgCodeMirrorConflictingGadgets
- An array of gadget names that, if enabled, will prevent CodeMirror from loading. Defaults to wikEd.
- $wgCodeMirrorDefaultPreferences
- Control which features are enabled by default for all users. Use
true
orfalse
to enable or disable a feature entirely, or provide an array containing namespace IDs (integers) or content models (strings). For example, to limit autocompletion to JavaScript pages or templates, you could use:$wgCodeMirrorDefaultPreferences[ 'autocomplete' ] = [ CONTENT_MODEL_JAVASCRIPT, NS_TEMPLATE ];
Feature | 2017 editor compatibility |
Default value |
---|---|---|
activeLine |
![]() |
false
|
bidiIsolation |
![]() |
false
|
bracketMatching |
![]() |
true
|
lineNumbering |
![]() |
true
|
lineWrapping |
![]() |
true
|
specialChars |
![]() |
true
|
codeFolding |
![]() |
true
|
autocomplete |
![]() |
true
|
openLinks |
![]() |
true
|
Differences from CodeMirror 5
[edit]New features
[edit]- No longer requires the use of WikiEditor .
- Significant performance improvements.
- Right-to-left support (T358804).
- Code folding (T30684).
- Autocompletion (T95100).
- Quickly open links with modifier key + click (T303392).
- Improved search panel (T371436).
- CodeMirror preferences (T359498).
- Syntax highlighting on read-only pages (T301615).
- Robust JavaScript API for integration with extensions, gadgets, and user scripts.
Deprecations and other changes
[edit]- The ResourceLoader modules are changing. See the migration guide .
- The
ext.CodeMirror.switch
hook has been deprecated. Useext.CodeMirror.toggle
instead. - The
.cm-mw-mnemonic
CSS class has been renamed to.cm-mw-html-entity
. - The
.cm-mw-template-name-mnemonic
class has been removed. Use.cm-mw-template-ground.cm-html-entity
instead. - The
.cm-mw-apostrophes-bold
and.cm-mw-apostrophes-italic
CSS classes have been removed. Use .cm-mw-apostrophes instead. - Line-level styling for
<nowiki>
,<pre>
, or any tag without an associated TagMode has been removed (T351686). - Mixed languages within wikitext are not yet supported (T357480). The only known usage of this with CodeMirror 5 is Extension:PhpTags .
- The browser's native search functionality (using Ctrl+F) has been replaced with search functionality built into CodeMirror. This is necessary to maintain performance (T303664).
Migration guide
[edit]MediaWiki version: | ≥ 1.43 |
This guide applies to MediaWiki 1.43 and later. All integrations should aim to be migrated by the release of MediaWiki 1.45 (release timeline ).
MediaWiki configuration
[edit]$wgCodeMirrorLineNumberingNamespaces
is deprecated. Configure$wgCodeMirrorDefaultPreferences
instead.
ResourceLoader modules
[edit]Ensure you're using the new .v6
modules .
Because CodeMirror 6 no longer relies on WikiEditor, there are some naming and behaviourial changes from the CodeMirror 5 counterparts:
Old module | New module (MW 1.43) | New module (MW 1.44+) | Description |
---|---|---|---|
ext.CodeMirror
|
ext.CodeMirror.v6.WikiEditor.init
|
ext.CodeMirror.init
|
CodeMirror integration for WikiEditor on #wpTextbox1 (the normal editing textarea) and only for wikitext.
|
N/A | ext.CodeMirror.v6.WikiEditor
|
ext.CodeMirror.WikiEditor
|
Exports the CodeMirrorWikiEditor class |
N/A | ext.CodeMirror.v6.init
|
ext.CodeMirror.init
|
CodeMirror for #wpTextbox1 and only for wikitext.
|
ext.CodeMirror.lib
|
ext.CodeMirror.v6.lib
|
ext.CodeMirror.lib
|
Exports CodeMirror internals. |
ext.CodeMirror.addons
|
N/A | N/A | This packaged the bracket matching feature in CodeMirror 5. Bracket matching is default behaviour in CodeMirror 6. |
ext.CodeMirror.mode.mediawiki
|
ext.CodeMirror.v6.mode.mediawiki
|
ext.CodeMirror.mode.mediawiki
|
The MediaWiki language mode. |
N/A | ext.CodeMirror.v6
|
ext.CodeMirror
|
Exports the CodeMirror class. |
ext.CodeMirror.visualEditor
|
ext.CodeMirror.visualEditor.init
|
ext.CodeMirror.init
|
Integration with the 2017 wikitext editor . |
ext.CodeMirror.lib.mode.php
|
N/A | N/A | CodeMirror 6 will not provide these modules. They are rarely used and have no corresponding content model in MediaWiki. If you want support for these languages, you'll need to install the bundle the code yourself. |
ext.CodeMirror.lib.mode.clike
| |||
ext.CodeMirror.lib.mode.htmlmixed
| |||
ext.CodeMirror.lib.mode.xml
| |||
ext.CodeMirror.lib.mode.javascript
|
TBD | ext.CodeMirror.lib.mode.javascript
|
These languages are planned to be supported in CodeMirror 6. |
ext.CodeMirror.lib.mode.css
|
ext.CodeMirror.lib.mode.css
| ||
N/A | ext.CodeMirror.lib.mode.lua
| ||
N/A | ext.CodeMirror.lib.mode.json
| ||
N/A | ext.CodeMirror.lib.mode.vue
|
With the release of MediaWiki 1.45, the old modules will be replaced with the news ones, and for some time the .v6
modules will be aliased before being removed entirely.
Gadgets and user scripts
[edit]The CodeMirror
global has been removed entirely.
For example, CodeMirror.fromTextArea( myTextarea )
will no longer work.
Instead, first load the desired ResourceLoader modules , instantiate a CodeMirror object, and call the initialize()
method.
If your script relies on the ext.CodeMirror.switch
hook to change the way it interacts with the editor, you'll need to use ext.CodeMirror.toggle
instead, or alternatively listen to an event.
See the JavaScript integration section for more information.
CSS
[edit]The .CodeMirror
element no longer exists. Use .cm-editor
instead for the entire CodeMirror DOM, or .cm-content
for the inner content (doesn't include the search panel, for example).
See deprecations and other changes to other CSS classes.
Integration
[edit]MediaWiki Extensions
[edit]Registering a new tag for MediaWiki
[edit]If you simply want CodeMirror to recognize a tag that is added by an extension, you can do so using the CodeMirrorTagModes
extension attribute . For example, to register the tag <foo>
as something containing wikitext, you would add the following to extension.json:
{
"attributes": {
"CodeMirror": {
"TagModes": [
"foo": "mediawiki"
]
}
}
}
CodeMirror will then highlight the content inside <foo>...</foo>
as wikitext.
Registering a tag so that CodeMirror treats the contents as something other than wikitext is currently not supported (T357480). If a tag is not registered, CodeMirror will highlight the contents as non-wikitext in the same way it highlights the contents of a <nowiki>...</nowiki>
tag.
Registering content models
[edit]CodeMirror's integration with WikiEditor currently works only with wikitext, but will eventually support other content types.
For the time being, if you need wikitext syntax highlighting on the main textarea (#wpTextbox1
) for a content model other than wikitext, you can use the CodeMirrorContentModels
extension attribute . For example, Extension:Proofread Page registers the proofread-page
content type:
{
"attributes": {
"CodeMirror": {
"ContentModels": [
"proofread-page"
]
}
}
}
PluginModules
[edit]CodeMirrorPluginModules
is an extension attribute that allows side-loading a module with CodeMirror.
This unconditionally loads the module whenever the ext.CodeMirror.v6
module is loaded.
If your plugin is only used in specific circumstances, consider having it check whether it is needed, and dynamically load the core code from a different module. This will avoid unnecessarily consuming end user bandwidth.
extension.json:
{
"attributes": {
"CodeMirror": {
"PluginModules": [
"ext.MyExtension.CodeMirror"
]
}
}
}
ext.MyExtension.CodeMirror.js:
/ Only load in the template namespace
if ( mw.config.get( 'wgNamespaceNumber' ) === 10 ) {
return mw.loader.using( 'ext.MyExtension.CodeMirror.core' );
}
return Promise.resolve();
JavaScript
[edit]The CodeMirror editor is not an actual toggled off.
For detecting changes to the document, using an event or a hook is likely the simplest. For reading and making changes, jQuery.textSelection may be convenient.
For more complex integrations or those who need better preformance, you can add your own extension to a new or an existing CodeMirror instance.
Using jQuery.textSelection
[edit]If you simply want to fetch or make changes to the document text, jQuery.textSelection is the easiest and most reliable means to do so. Usage of jQuery.textSelection on the textarea is bubbled up to CodeMirror, so you don't need to have any knowledge of whether CodeMirror is enabled:
const $textarea = $( '#wpTextbox1' )
const content = $textarea.textSelection( 'getContents' );
/ Append "Foobar" to the content.
$textarea.textSelection( 'setContents', content + '\nFoobar' );
Using jQuery's .val() on #wpTextbox1 can be used,[2] however this isn't recommended and may not work in all editors, such as the 2017 wikitext editor .
Using ResourceLoader
[edit]The CodeMirror extension provides a number of ResourceLoader modules for use by user scripts, gadgets, and extensions. To make use of CodeMirror, you'll need at minimum the ext.CodeMirror.v6
module, along with the desired language. For MediaWiki wikitext, you'd use ext.CodeMirror.v6.mode.mediawiki
.
Here is an example of how to apply wikitext syntax highlighting to any arbitrary textarea, using the default set of features:
mw.loader.using( [ 'ext.CodeMirror.v6', 'ext.CodeMirror.v6.mode.mediawiki' ] ).then( ( require ) => {
const CodeMirror = require( 'ext.CodeMirror.v6' );
const mediawikiLang = require( 'ext.CodeMirror.v6.mode.mediawiki' );
const cm = new CodeMirror( myTextarea, mediawikiLang() );
cm.initialize();
} );
If you also want WikiEditor:
mw.loader.using( [
'ext.wikiEditor',
'ext.CodeMirror.v6.WikiEditor',
'ext.CodeMirror.v6.mode.mediawiki'
] ).then( ( require ) => {
const textarea = document.getElementById( 'wpTextbox1' );
mw.addWikiEditor( $( textarea ) );
const CodeMirrorWikiEditor = require( 'ext.CodeMirror.v6.WikiEditor' );
const mediawikiLang = require( 'ext.CodeMirror.v6.mode.mediawiki' );
const cmWe = new CodeMirrorWikiEditor( textarea, mediawikiLang() );
cmWe.initialize();
} );
Module | Description |
---|---|
ext.CodeMirror.v6.lib
|
The core CodeMirror library. You shouldn't need to require this directly unless you need access to the upstream CodeMirror API. |
ext.CodeMirror.v6
|
The basic CodeMirror integration for MediaWiki editors. This module exports the CodeMirror class. |
ext.CodeMirror.v6.mode.mediawiki
|
The MediaWiki language mode. Use this in conjunction with the ext.CodeMirror.v6 module.
|
ext.CodeMirror.v6.init (internal) |
The main entrypoint for action=edit requests. Not intended for external use. |
ext.CodeMirror.v6.WikiEditor
|
CodeMirror integration for WikiEditor. This module exports the CodeMirrorWikiEditor class. |
ext.CodeMirror.visualEditor.init
|
CodeMirror integration with the 2017 wikitext editor , and only for wikitext. |
Using hooks
[edit]You can also integrate with CodeMirror by using frontend hooks. These allow you to run code just before or after CodeMirror has loaded, or react to changes to the document.
Hook | Description |
---|---|
ext.CodeMirror.initialize
|
Called just before CodeMirror is initialized. This can be used to manipulate the DOM to suit CodeMirror (i.e. if you manipulate WikiEditor's DOM, you may need this).
Parameters
|
ext.CodeMirror.ready
|
Called just after CodeMirror is initialized.
Parameters
|
ext.CodeMirror.toggle
|
Called when CodeMirror is toggled on or off.
Parameters
|
ext.CodeMirror.destroy
|
Called just after CodeMirror is destroyed and the original textarea is restored.
Parameters
|
ext.CodeMirror.input
|
Called when document changes are made in CodeMirror. Note that the textarea may not be updated yet.
Parameters
|
ext.CodeMirror.preferences.ready
|
Fired just before CodeMirrorPreferences has been instantiated.
Paramaters
|
ext.CodeMirror.preferences.apply
|
Fired when a CodeMirror preference is enabled or initially applied.
Parameters
|
ext.CodeMirror.preferences.change
|
Fired when a CodeMirror preference is enabled or disabled by the user.
Paramaters
|
ext.CodeMirror.preferences.display (internal) |
Fired when the preferences panel is constructed, just before it is displayed.
Parameters
|
ext.CodeMirror.keymap (internal) |
Fired when the keyboard shortcut help dialog is opened. |
ext.CodeMirror.search (internal) |
Fired when the search panel is opened. |
Using events
[edit]The following 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
[edit]You can import the ext.CodeMirror.v6.lib
module to get access to the upstream Extension when instantiating a CodeMirror
or CodeMirrorWikiEditor
instance.
For example, to provide your own Extension that reacts to changes made in CodeMirror:
mw.loader.using( [ 'ext.CodeMirror.v6', 'ext.CodeMirror.v6.mode.mediawiki' ] ).then( ( require ) => {
const CodeMirror = require( 'ext.CodeMirror.v6' );
const mediawikiLang = 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, mediawikiLang() );
cm.initialize( [ cm.defaultExtensions, myExtension ] );
} );
Or if you need to interact with an existng 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() );
} );
See also
[edit]- User:Remember the dot/Syntax highlighter
- Extension:VisualEditor
- Extension:WikiEditor
- Extension:CodeEditor
- c:Category:MediaWiki extension CodeMirror
Notes
[edit]- ↑ Line wrapping cannot be disabled in the 2017 editor.
- ↑ phab:T384556
![]() | This extension is included in the following wiki farms/hosts and/or packages: This is not an authoritative list. Some wiki farms/hosts and/or packages may contain this extension even if they are not listed here. Always check with your wiki farms/hosts or bundle to confirm. |
- Stable extensions
- User interface extensions
- GPL licensed extensions
- Extensions in Wikimedia version control
- EditPage::showEditForm:initial extensions
- EditPage::showReadOnlyForm:initial extensions
- GetBetaFeaturePreferences extensions
- GetPreferences extensions
- UploadForm:initial extensions
- All extensions
- Extensions used on Wikimedia
- Extensions included in Canasta
- Extensions included in Fandom
- Extensions included in Miraheze
- Extensions included in MyWikis
- Extensions included in ProWiki
- Extensions included in Telepedia
- Extensions included in wiki.gg
- Extensions included in WikiForge
- Syntax highlighting extensions