Page MenuHomePhabricator

Highlighting of syntax errors, warnings, infos for Wikitext editor
Closed, ResolvedPublicFeature

Description

Feature summary (what you would like to be able to do and where):

This is part of T166098 that requests highlighting of syntax errors, warnings, infos for Wikitext editor. It will be implemented in CodeMirror 6. Further descriptions can be found in T166098.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

Change #1141443 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] DataScript/Hooks: add image keywords and language variants

https://gerrit.wikimedia.org/r/1141443

Change #1141443 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] DataScript/Hooks: add image keywords, functionHooks, language variants

https://gerrit.wikimedia.org/r/1141443

Change #1141495 had a related patch set uploaded (by Bhsd; author: Bhsd):

[mediawiki/extensions/CodeMirror@master] Wikitext linter: WikiParser-Node

https://gerrit.wikimedia.org/r/1141495

Change #1141512 had a related patch set uploaded (by Bhsd; author: Bhsd):

[mediawiki/extensions/CodeMirror@master] CodeMirrorLint: quick fix

https://gerrit.wikimedia.org/r/1141512

Change #1142691 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] CodeMirror: temporarily disable linting for wikitext

https://gerrit.wikimedia.org/r/1142691

Change #1142692 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@wmf/1.44.0-wmf.28] CodeMirror: temporarily disable linting for wikitext

https://gerrit.wikimedia.org/r/1142692

Change #1142692 abandoned by MusikAnimal:

[mediawiki/extensions/CodeMirror@wmf/1.44.0-wmf.28] CodeMirror: temporarily disable linting for wikitext

Reason:

going to revert responsible patch instead

https://gerrit.wikimedia.org/r/1142692

Change #1142704 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] Revert "JavaScript: ESLint 8.57.0"

https://gerrit.wikimedia.org/r/1142704

Change #1142691 abandoned by MusikAnimal:

[mediawiki/extensions/CodeMirror@master] CodeMirror: temporarily disable linting for wikitext

Reason:

see I0465bd8c32c50256515bd8e4e0984a32b2336aac

https://gerrit.wikimedia.org/r/1142691

Change #1142714 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@wmf/1.44.0-wmf.28] Revert "JavaScript: ESLint 8.57.0"

https://gerrit.wikimedia.org/r/1142714

Change #1142704 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] Revert "JavaScript: ESLint 8.57.0"

https://gerrit.wikimedia.org/r/1142704

Change #1142714 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@wmf/1.44.0-wmf.28] Revert "JavaScript: ESLint 8.57.0"

https://gerrit.wikimedia.org/r/1142714

Mentioned in SAL (#wikimedia-operations) [2025-05-06T23:52:33Z] <hmonroy@deploy1003> Started scap sync-world: Backport for [[gerrit:1142714|Revert "JavaScript: ESLint 8.57.0" (T381577)]]

Mentioned in SAL (#wikimedia-operations) [2025-05-07T00:21:08Z] <hmonroy@deploy1003> hmonroy, musikanimal: Backport for [[gerrit:1142714|Revert "JavaScript: ESLint 8.57.0" (T381577)]] synced to the testservers (https://wikitech.wikimedia.org/wiki/Mwdebug)

Mentioned in SAL (#wikimedia-operations) [2025-05-07T00:39:48Z] <hmonroy@deploy1003> Finished scap sync-world: Backport for [[gerrit:1142714|Revert "JavaScript: ESLint 8.57.0" (T381577)]] (duration: 47m 14s)

Test on Patch demo: Dog
The Wikitext linter is diabled by default, so the user needs to enable the linter from the preference panel first.

Change #1141512 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] CodeMirrorLint: quick fix

https://gerrit.wikimedia.org/r/1141512

Change #1141495 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] Wikitext linter: WikiParser-Node

https://gerrit.wikimedia.org/r/1141495

MusikAnimal subscribed.

This is exciting stuff! We should advertise it :) I'll get something written in Tech News today.

Linting hasn't been documented on the help page yet, so I will do that first.

Some comments about the translatable messages:

  • $1 parameters are not documented. Please add explicit documentation for every $1 parameter in every new message.
  • Several messages added here say "invalid" and others say "illegal". We usually use "invalid" and not "illegal". If there is no specific difference, "illegal" should be replaced with "invalid" for consistency. If there is a difference, it should be explained in qqq.
  • The messages codemirror-wikilint-illegal-module and codemirror-wikilint-missing-function mention "module". What kind of module it is? API, Scribunto, something else?
  • codemirror-wikilint-invalid-attribute is "containing invalid attribute". What kind of thing is containing an invalid attribute?
  • codemirror-wikilint-left-bracket is "left bracket". This has several issues: It will be unclear in the context of RTL languages, and also to people with Left-right confusion (15% of humanity according to some estimates). It should probably be replaced with "opening bracket" or "starting bracket". In addition, according to qqq, it's supposed to be a "quick-fix action", but it's unclear what the action is.
  • The messages with the text "horizontal-alignment" and "vertical-alignment" are cryptic. Are they really supposed to be translated? They look like CSS properties, but the qqq says "Diagnostic message for image vertical-alignment parameter". What exactly is the diagnostic message? What kind of problem does it describe?
  • codemirror-wikilint-open is "open". Its qqq is "Short label for a quick-fix action that converts a closing tag to an opening tag". If it's an action, it should describe the action more clearly; "open" is probably not the action.
  • codemirror-wikilint-prefix is "prefix". Its qqq is "Short label for a quick-fix action that adds a namespace prefix". If it's an action, it should describe the action more clearly; "prefix" is probably not the action.
  • codemirror-wikilint-uppercase is "uppercase". Its qqq is "Short label for a quick-fix action that converts the text to uppercase". The action should be described more clearly. For example, "convert to uppercase" (if it's correct).
  • codemirror-wikilint-useless-attribute is "useless attribute". Its qqq is probably wrong: "Diagnostic message for useless attribute of". Please fix the qqq.

Thanks! :)

@Amire80 Thanks for your comments!

  • $1 parameters are not documented. Please add explicit documentation for every $1 parameter in every new message.

What documentation do you mean here? qqq?

  • Several messages added here say "invalid" and others say "illegal". We usually use "invalid" and not "illegal". If there is no specific difference, "illegal" should be replaced with "invalid" for consistency. If there is a difference, it should be explained in qqq.

I can change the "illegal" to "invalid" in message values but not the keys. The linter has been around for years before being adapted in the CodeMirror extension, so for backward compatibility reasons the keys should remain the same.

  • The messages codemirror-wikilint-illegal-module and codemirror-wikilint-missing-function mention "module". What kind of module it is? API, Scribunto, something else?

I can clarify it in qqq. It means Scribunto modules.

  • codemirror-wikilint-invalid-attribute is "containing invalid attribute". What kind of thing is containing an invalid attribute?

It means that some of the attribute names within the marked range contain invalid characters (/[^\w:.-]/).

  • codemirror-wikilint-left-bracket is "left bracket". This has several issues: It will be unclear in the context of RTL languages, and also to people with Left-right confusion (15% of humanity according to some estimates). It should probably be replaced with "opening bracket" or "starting bracket". In addition, according to qqq, it's supposed to be a "quick-fix action", but it's unclear what the action is.

"Opening bracket" looks great! Action is a CodeMirror terminology. Do you have any suggestions?

  • The messages with the text "horizontal-alignment" and "vertical-alignment" are cryptic. Are they really supposed to be translated? They look like CSS properties, but the qqq says "Diagnostic message for image vertical-alignment parameter". What exactly is the diagnostic message? What kind of problem does it describe?

For example, [[file:a|left|right]] has an horizontal-alignment issue.

  • codemirror-wikilint-open is "open". Its qqq is "Short label for a quick-fix action that converts a closing tag to an opening tag". If it's an action, it should describe the action more clearly; "open" is probably not the action.
  • codemirror-wikilint-prefix is "prefix". Its qqq is "Short label for a quick-fix action that adds a namespace prefix". If it's an action, it should describe the action more clearly; "prefix" is probably not the action.
  • codemirror-wikilint-uppercase is "uppercase". Its qqq is "Short label for a quick-fix action that converts the text to uppercase". The action should be described more clearly. For example, "convert to uppercase" (if it's correct).

The messages for CodeMirror actions will appear as a button text, so I think they should not be too long. "Convert to uppercase" may seem to me a little too long, for example.

  • codemirror-wikilint-useless-attribute is "useless attribute". Its qqq is probably wrong: "Diagnostic message for useless attribute of". Please fix the qqq.

I will correct this in qqq.

r1184397 cannot be automatically merged. Maybe I need to avoid XML-like tags?

r1184397 cannot be automatically merged. Maybe I need to avoid XML-like tags?

Yes. For security reasons, some translations that include < and > are flagged for manual review. Some tags are allowed, but not the ones that you had here. See T358384 for more info if you're curious.

The best solution is to replace them with $1, $2, etc. parameters. This would give the best experience to translators. In messages that have <$1>, put the < and > signs into the $1. In messages that have parts like <imagemap>, put that whole string into a $1 parameter and explain it in qqq.

(It's also possible to replace them with &lt; and &gt; in messages, but this would give the translators a worse experience.)

@Amire80 Thanks for your comments!

  • $1 parameters are not documented. Please add explicit documentation for every $1 parameter in every new message.

What documentation do you mean here? qqq?

Yes, in qqq.

  • Several messages added here say "invalid" and others say "illegal". We usually use "invalid" and not "illegal". If there is no specific difference, "illegal" should be replaced with "invalid" for consistency. If there is a difference, it should be explained in qqq.

I can change the "illegal" to "invalid" in message values but not the keys. The linter has been around for years before being adapted in the CodeMirror extension, so for backward compatibility reasons the keys should remain the same.

There's no need to change the message keys. It's enough to change the English message text.

  • The messages codemirror-wikilint-illegal-module and codemirror-wikilint-missing-function mention "module". What kind of module it is? API, Scribunto, something else?

I can clarify it in qqq. It means Scribunto modules.

Thanks. Clarifying in qqq is the best solution.

  • codemirror-wikilint-invalid-attribute is "containing invalid attribute". What kind of thing is containing an invalid attribute?

It means that some of the attribute names within the marked range contain invalid characters (/[^\w:.-]/).

So does it mean, for example, that it could say something like: "This <span> element contains an invalid attribute"?

  • codemirror-wikilint-left-bracket is "left bracket". This has several issues: It will be unclear in the context of RTL languages, and also to people with Left-right confusion (15% of humanity according to some estimates). It should probably be replaced with "opening bracket" or "starting bracket". In addition, according to qqq, it's supposed to be a "quick-fix action", but it's unclear what the action is.

"Opening bracket" looks great! Action is a CodeMirror terminology. Do you have any suggestions?

Most likely, the string should include a verb that describes the action, such as "insert", "remove", "replace", etc. I'm not sure what does this action do. It should probably be something like "Insert an opening bracket", "Replace with opening bracket", etc.

  • The messages with the text "horizontal-alignment" and "vertical-alignment" are cryptic. Are they really supposed to be translated? They look like CSS properties, but the qqq says "Diagnostic message for image vertical-alignment parameter". What exactly is the diagnostic message? What kind of problem does it describe?

For example, [[file:a|left|right]] has an horizontal-alignment issue.

OK, so it should probably be a full sentence, for example: "This file has a horizontal alignment issue". (If you write a full sentence, you don't need -.)

  • codemirror-wikilint-open is "open". Its qqq is "Short label for a quick-fix action that converts a closing tag to an opening tag". If it's an action, it should describe the action more clearly; "open" is probably not the action.
  • codemirror-wikilint-prefix is "prefix". Its qqq is "Short label for a quick-fix action that adds a namespace prefix". If it's an action, it should describe the action more clearly; "prefix" is probably not the action.
  • codemirror-wikilint-uppercase is "uppercase". Its qqq is "Short label for a quick-fix action that converts the text to uppercase". The action should be described more clearly. For example, "convert to uppercase" (if it's correct).

The messages for CodeMirror actions will appear as a button text, so I think they should not be too long. "Convert to uppercase" may seem to me a little too long, for example.

OK, I understand, but just "uppercase" doesn't sound like an action. An action should be a verb, not an adjective. "Convert to uppercase" doesn't sound too long to me. Perhaps real designers can give suggestions? I am a localization specialist, and not so much a design specialist :)

Can you perhaps add a screenshot here?

  • codemirror-wikilint-useless-attribute is "useless attribute". Its qqq is probably wrong: "Diagnostic message for useless attribute of". Please fix the qqq.

I will correct this in qqq.

Thanks.

Change #1184637 had a related patch set uploaded (by Bhsd; author: Bhsd):

[mediawiki/extensions/CodeMirror@master] i18n: WikiLint diagnostic messages

https://gerrit.wikimedia.org/r/1184637

  • $1 parameters are not documented. Please add explicit documentation for every $1 parameter in every new message.

Done.

  • Several messages added here say "invalid" and others say "illegal". We usually use "invalid" and not "illegal". If there is no specific difference, "illegal" should be replaced with "invalid" for consistency. If there is a difference, it should be explained in qqq.

Done.

  • The messages codemirror-wikilint-illegal-module and codemirror-wikilint-missing-function mention "module". What kind of module it is? API, Scribunto, something else?

I can clarify it in qqq. It means Scribunto modules.

Done.

  • codemirror-wikilint-invalid-attribute is "containing invalid attribute". What kind of thing is containing an invalid attribute?

It means that some of the attribute names within the marked range contain invalid characters (/[^\w:.-]/).

So does it mean, for example, that it could say something like: "This <span> element contains an invalid attribute"?

Done.

  • codemirror-wikilint-left-bracket is "left bracket". This has several issues: It will be unclear in the context of RTL languages, and also to people with Left-right confusion (15% of humanity according to some estimates). It should probably be replaced with "opening bracket" or "starting bracket". In addition, according to qqq, it's supposed to be a "quick-fix action", but it's unclear what the action is.

"Opening bracket" looks great! Action is a CodeMirror terminology. Do you have any suggestions?

Most likely, the string should include a verb that describes the action, such as "insert", "remove", "replace", etc. I'm not sure what does this action do. It should probably be something like "Insert an opening bracket", "Replace with opening bracket", etc.

Done.

  • The messages with the text "horizontal-alignment" and "vertical-alignment" are cryptic. Are they really supposed to be translated? They look like CSS properties, but the qqq says "Diagnostic message for image vertical-alignment parameter". What exactly is the diagnostic message? What kind of problem does it describe?

For example, [[file:a|left|right]] has an horizontal-alignment issue.

OK, so it should probably be a full sentence, for example: "This file has a horizontal alignment issue". (If you write a full sentence, you don't need -.)

No, it cannot be a full sentence because it will be used as $1 in other messages, such as conflicting image $1 parameter.

  • codemirror-wikilint-open is "open". Its qqq is "Short label for a quick-fix action that converts a closing tag to an opening tag". If it's an action, it should describe the action more clearly; "open" is probably not the action.
  • codemirror-wikilint-prefix is "prefix". Its qqq is "Short label for a quick-fix action that adds a namespace prefix". If it's an action, it should describe the action more clearly; "prefix" is probably not the action.
  • codemirror-wikilint-uppercase is "uppercase". Its qqq is "Short label for a quick-fix action that converts the text to uppercase". The action should be described more clearly. For example, "convert to uppercase" (if it's correct).

The messages for CodeMirror actions will appear as a button text, so I think they should not be too long. "Convert to uppercase" may seem to me a little too long, for example.

OK, I understand, but just "uppercase" doesn't sound like an action. An action should be a verb, not an adjective. "Convert to uppercase" doesn't sound too long to me. Perhaps real designers can give suggestions? I am a localization specialist, and not so much a design specialist :)

Can you perhaps add a screenshot here?

Done. Here is a screenshot.

Screenshot 2025-09-04 at 2.04.36 PM.png (104×694 px, 17 KB)

  • codemirror-wikilint-useless-attribute is "useless attribute". Its qqq is probably wrong: "Diagnostic message for useless attribute of". Please fix the qqq.

Done.

Change #1184637 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] i18n: WikiLint diagnostic messages

https://gerrit.wikimedia.org/r/1184637

Change #1185050 had a related patch set uploaded (by MusikAnimal; author: MusikAnimal):

[mediawiki/extensions/CodeMirror@master] wikilint: revise to a relatively lax yet explorative rule config

https://gerrit.wikimedia.org/r/1185050

Change #1185050 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] wikilint: revise to a relatively lax yet explorative rule config

https://gerrit.wikimedia.org/r/1185050

Change #1187040 had a related patch set uploaded (by Bhsd; author: Bhsd):

[mediawiki/extensions/CodeMirror@master] wikilint: setLintConfig and missing messages

https://gerrit.wikimedia.org/r/1187040

Change #1187040 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] wikilint: setLintConfig and missing messages

https://gerrit.wikimedia.org/r/1187040

Can anyone please say more about the message codemirror-wikilint-unclosed? What can $1 be? Is it shown as characters or as words? If these are words, where do these words come from?

Can anyone please say more about the message codemirror-wikilint-unclosed? What can $1 be?

It can be any of the following: codemirror-wikilint-quotes, codemirror-wikilint-html-comment, codemirror-wikilint-table, <includeonly> or <noinclude>. It seems that some messages such as codemirror-wikilint-html-comment are missing. I will submit a patch to fix that soon.

Change #1187983 had a related patch set uploaded (by Bhsd; author: Bhsd):

[mediawiki/extensions/CodeMirror@master] wikilint: missing message

https://gerrit.wikimedia.org/r/1187983

What we're doing here is using "patchwork" / "lego" messages. For something like this, I don't think there's a way to avoid that, so we just need to be super clear which messages are used in other messages, and ideally document the possible values for $1. You can use translatewiki.net templates to make this a bit easier, in particular {{msg-mw}} which provides a link to another message so the translator can get the context. So in qqq.json, codemirror-wikilint-unclosed could be Diagnostic message for unclosed comment, quotation mark, etc.\n\n$1 may be one of: {{msg-mw|codemirror-wikilint-quotes}}, {{msg-mw|codemirror-wikilint-html-comment}}, …. Then similarly, the documentation for the lego messages such as codemirror-wikilint-quotes could be Diagnostic message for quotation marks. Used in the {{msg-mw|codemirror-wikilint-unclosed}} message.

I'm guessing that there are probably a lot of combinations of lego messages. Say codemirror-wikilint-quotes is used in multiple other messages. If that's the case, it would get messy trying to comprehensively document every combination, so I think just at least being clear which messages are not complete messages on their own is a good enough start. I.e. This message is supplied as a parameter to other messages such as {{msg-mw|codemirror-wikilint-unclosed}}.

@Amire80 to correct me where I'm wrong, but I think this is how it's generally done when we have to use lego messages.

This is not exactly what we call "lego". "Lego" is more like concatenating different parts of sentences under the assumption that the order of the words is the same in all languages. This is very bad and must never be done.

What is done here is much more reasonable, because the translator can put the $1 wherever necessary in the sentence. It is still a bit problematic, however, because in English and in some other languages, the translation of the word "unclosed" is always the same, but in many languages, the translation of "unclosed" depends on the value of $1.

The best solution would be to have a separate message for each of them.

If it's too complicated, then it's not a super-big deal. I can think of some translation tricks to make the word "unclosed" always the same.

In any case, adding a list of possible $1 values to the qqq is definitely necessary, and using the {{msg-mw}} template for it is the right thing to do.

Change #1187983 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] wikilint: missing message

https://gerrit.wikimedia.org/r/1187983

The best solution would be to have a separate message for each of them.

I will do it in the next release of wikiparser-node.

In any case, adding a list of possible $1 values to the qqq is definitely necessary, and using the {{msg-mw}} template for it is the right thing to do.

I will submit a patch soon.

Change #1187999 had a related patch set uploaded (by Bhsd; author: Bhsd):

[mediawiki/extensions/CodeMirror@master] wikilint: update qqq.json

https://gerrit.wikimedia.org/r/1187999

Change #1187999 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] wikilint: update qqq.json

https://gerrit.wikimedia.org/r/1187999

Change #1189963 had a related patch set uploaded (by Bhsd; author: Bhsd):

[mediawiki/extensions/CodeMirror@master] wikilint fix i18n messages and lint missing file extensions

https://gerrit.wikimedia.org/r/1189963

Change #1189963 merged by jenkins-bot:

[mediawiki/extensions/CodeMirror@master] wikilint: fix i18n messages and lint missing file extensions

https://gerrit.wikimedia.org/r/1189963

Bhsd moved this task from Feature requests to Done on the MediaWiki-extensions-CodeMirror board.

The basic objective of this task has been completed. Further discussion about the linter configuration can be continued in T394964. The Parsoid-based linting is a separate task (T394965).