# How to display a literal ampersand ('&') in Action name?

**URL:** <https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052>\
**Category:** IntelliJ Platform\
**Created:** [April 13, 2026, 3:41pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052 "2026-04-13T15:41:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tadeuszkarpinski](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/tadeuszkarpinski/32/2756_2.png) [@tadeuszkarpinski](https://platform.jetbrains.com/u/tadeuszkarpinski)\
**Post date:** [April 13, 2026, 3:41pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/1 "2026-04-13T15:41:09Z")

</div>

Hello,

I’m struggling with a seemingly simple task: I want to display a single ampersand character (`&`) in my action’s text.

**What I’ve tried:**

- `text="Project &amp; Non-Project Modules"` → Result: The “N” is underlined as a mnemonic.
- `text="Project &amp;&amp; Non-Project Modules"` → Result: No mnemonic and no (`&`).
- `text="Project &#38;&#38; Non-Project Modules"` → Result: Same as above.

I have defined my action in `plugin.xml` as follows:

```auto
<action id="pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules"
        class="pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules"
        text="Project &amp;&amp; Non-Project Modules">
    <keyboard-shortcut
            keymap="$default"
            first-keystroke="alt B"
            second-keystroke="N"/>
</action>

```

 ![image](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/2X/1/17b40644d6a8860d3ad7b532933b1c0b4dc866ea.png)

---

<div class="post-metadata">

**Author:** ![abrooksv](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/abrooksv/32/924_2.png) [@abrooksv](https://platform.jetbrains.com/u/abrooksv)\
**Post date:** [April 13, 2026, 5:55pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/2 "2026-04-13T17:55:56Z")

</div>

You need to say `&&`, see

> <https://github.com/JetBrains/intellij-community/blob/6642f7dd342f7036f9c885e804ad291f741f9103/platform/util/src/com/intellij/openapi/util/text/StringUtil.java#L2178>

Example in properties file:

> <https://github.com/JetBrains/intellij-community/blob/1e05f4447723efe125034ffad6a3764387893163/platform/jewel/int-ui/int-ui-standalone-tests/src/test/resources/messages/TestBundle.properties#L4-L5>

---

<div class="post-metadata">

**Author:** ![tadeuszkarpinski](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/tadeuszkarpinski/32/2756_2.png) [@tadeuszkarpinski](https://platform.jetbrains.com/u/tadeuszkarpinski)\
**Post date:** [April 13, 2026, 6:07pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/3 "2026-04-13T18:07:12Z")

</div>

Thank you for your reply.

When I use `&&` in **plugin.xml** :

```auto
<action id="pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules"
        class="pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules"
        text="Project && Non-Project Modules">
    <keyboard-shortcut
            keymap="$default"
            first-keystroke="alt B"
            second-keystroke="N"/>
</action>

```

Then I get:

```auto
The entity name must immediately follow the '&' in the entity reference.

```

And when I use it in **bundle.properties** :

```auto
action.pl.atingo.bts.actions.OdooModuleTestWithRemoveDB.description=Project && Non-Project Modules

```

Then I get:

```auto
com.intellij.diagnostic.PluginException: Empty menu item text for OdooModuleTestProjectNonProjectModules@popup (pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules). The default action text must be specified in plugin.xml or its class constructor [Plugin: pl.atingo.bts]

```

---

<div class="post-metadata">

**Author:** ![abrooksv](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/abrooksv/32/924_2.png) [@abrooksv](https://platform.jetbrains.com/u/abrooksv)\
**Post date:** [April 13, 2026, 6:19pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/4 "2026-04-13T18:19:03Z")

</div>

> [@tadeuszkarpinski](#):
>
> `pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules`

Looks like you have a typo in the properties file example

your ID is `pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules` but you registered it with the ID `pl.atingo.bts.actions.OdooModuleTestWithRemoveDB`

---

<div class="post-metadata">

**Author:** ![tadeuszkarpinski](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/tadeuszkarpinski/32/2756_2.png) [@tadeuszkarpinski](https://platform.jetbrains.com/u/tadeuszkarpinski)\
**Post date:** [April 14, 2026, 8:27am UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/5 "2026-04-14T08:27:01Z")

</div>

My apologies, I completely messed up the examples in my previous post. I’ve been testing so many different configurations that I got lost in my own snippets. Let’s clear this up:

- **The `plugin.xml` issue:** When I try to use `&&` directly in the `text` attribute like this: `text="Project && Non-Project Modules"` I get the expected XML error: `The entity name must immediately follow the '&' in the entity reference.` This is clear, as XML requires entities.
- **The `bundle.properties` issue (with the correct ID this time):** When I use the correct action ID in my properties file: `action.pl.atingo.bts.actions.OdooModuleTestProjectNonProjectModules.text=Project && Non-Project Modules`, the action loads correctly, but the `&` character **is simply not displayed**.

 ![example](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/2X/3/3a8bd67c1ff0aec9bc01a0b69f27ae11bdce764d.png)

---

<div class="post-metadata">

**Author:** ![abrooksv](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/abrooksv/32/924_2.png) [@abrooksv](https://platform.jetbrains.com/u/abrooksv)\
**Post date:** [April 14, 2026, 4:51pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/6 "2026-04-14T16:51:09Z")

</div>

Interesting, wonder if its a bug…?

It works with && only if its done through the AnAction constructor

```auto
AnAction("Foo && Bar") {

```

![Screenshot 2026-04-14 at 9.50.07 AM](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/optimized/2X/4/4aeecc56a5a0fe14ac402ff616537105e43f47ca_2_690x60.png)

---

<div class="post-metadata">

**Author:** ![abrooksv](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/abrooksv/32/924_2.png) [@abrooksv](https://platform.jetbrains.com/u/abrooksv)\
**Post date:** [April 14, 2026, 5:44pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/7 "2026-04-14T17:44:24Z")

</div>

I got curious so I debugged this:

When using ActionStub (defining it in the properties file), the text is loaded via

> <https://github.com/JetBrains/intellij-community/blob/d73ad7b71dc7807cbf9869949603a9c26c43b3db/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.kt#L1687>

Which has to go through Java’s Message format and this util:

> <https://github.com/JetBrains/intellij-community/blob/188b7ef96f72c032b7ee232ba6f5ec3dac9448f8/platform/util/src/com/intellij/BundleBase.kt#L144>

So in order to get it formatted correct from the resource bundle PoV it would need to be:  
`action.foo.bar.text=Foo \\& Bar`

 ![Screenshot 2026-04-14 at 10.33.15 AM](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/2X/c/c9377a2dac5af32be69370b6f576fa7f68770317.png)

But the format is then passed to Presentation.setText supplier, which wants it in `&&` format.

So we have to triple escape this for all the layers:

`& -> &&` for `com.intellij.openapi.util.text.TextWithMnemonic#parse`  
`&& -> \&\&` for `com.intellij.BundleBase#replaceMnemonicAmpersand`  
`\&\& -> \\&\\&` for Java MessageFormat

leading us to

```auto
action.foo.bar.text=Foo \\&\\& Bar

```

 ![Screenshot 2026-04-14 at 10.44.07 AM](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/2X/2/24bf2bdaa2571385cd83d44ed357044caca8240c.png)

 ![Screenshot 2026-04-14 at 10.43.06 AM](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/2X/4/474acb2b4363aa50b4b423da933be3b55c367406.png)

---

<div class="post-metadata">

**Author:** ![tadeuszkarpinski](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/tadeuszkarpinski/32/2756_2.png) [@tadeuszkarpinski](https://platform.jetbrains.com/u/tadeuszkarpinski)\
**Post date:** [April 14, 2026, 7:57pm UTC](https://platform.jetbrains.com/t/how-to-display-a-literal-ampersand-in-action-name/4052/8 "2026-04-14T19:57:49Z")

</div>

That’s it! `\\&\\&` did the trick

Thank you so much for digging into the code and debugging this.

Cheers!

 ![super](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/2X/9/94fbe07731227db7788b0d028ada4797decced27.png)
