admin管理员组

文章数量:1406944

I'm using the latest version of Codemirror. From my package.json:

"codemirror": "^6.0.1",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-sql": "^6.8.0",

And I'm setting a font installed on my system locally:

    cfg.push(EditorView.theme({
      '& .cm-content': {
        fontSize: fontSize,
        fontFamily: fontFamily, // <-- This gets set to "CaskaydiaCove Nerd Font Mono"
      },
      '.cm-gutters': {
        fontSize: fontSize,
      },
    }));

In the editor, I can confirm my font gets loaded. However, when I enter the text:

=== != ?= <- >=

I don't see any of the coding font ligatures. I can run the same code on JSFiddle:

<html lang="en">
<head>
  <style>
    .lig-support {
      font-family: "CaskaydiaCove Nerd Font Mono";
      font-size: 19pt;
    }
  </style>
</head>
<body bgcolor="white">
  <div class="lig-support" contenteditable="true">
    <span>
      === != ?= <- >=
    </span>
  </div>
</body>
</html>

I'm using the latest version of Codemirror. From my package.json:

"codemirror": "^6.0.1",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-sql": "^6.8.0",

And I'm setting a font installed on my system locally:

    cfg.push(EditorView.theme({
      '& .cm-content': {
        fontSize: fontSize,
        fontFamily: fontFamily, // <-- This gets set to "CaskaydiaCove Nerd Font Mono"
      },
      '.cm-gutters': {
        fontSize: fontSize,
      },
    }));

In the editor, I can confirm my font gets loaded. However, when I enter the text:

=== != ?= <- >=

I don't see any of the coding font ligatures. I can run the same code on JSFiddle:

<html lang="en">
<head>
  <style>
    .lig-support {
      font-family: "CaskaydiaCove Nerd Font Mono";
      font-size: 19pt;
    }
  </style>
</head>
<body bgcolor="white">
  <div class="lig-support" contenteditable="true">
    <span>
      === != ?= <- >=
    </span>
  </div>
</body>
</html>

And I see all the ligatures correctly. This means something in Codemirror is disabling the ligatures, however I cannot see anything in the Chrome tools or computed styles that would indicate this nor can I find anything in the Codemirror source code that appears it would do this. I've tried on both Brave and Chrome browsers. Any ideas? Thanks!

Update: For those of you who don't happen to have this font installed, here's what it looks like on my machine with the StackOverflow preview:

Once again, the ligatures work in the StackOverflow preview and various HTML playgrounds, but do not work in Codemirror.

Share Improve this question edited Mar 12 at 22:27 Mike Christensen asked Mar 12 at 19:57 Mike ChristensenMike Christensen 91.4k51 gold badges219 silver badges348 bronze badges 13
  • How are they supposed to be rendered? Your code snipped is pretty much useless because the font family CaskaydiaCove Nerd Font Mono means nothing to us. You have to embed the font in CSS to show up. What looks strange is the text === != ?= <- >=. Do you understand that they are just 11 separate characters? Where are the boundaries between the ligatures? – Sergey A Kryukov Commented Mar 12 at 20:03
  • @SergeyAKryukov Sorry I was unclear. Obviously the end user would need the font installed to see the ligatures. I've attached a screen shot of what I see. My question is why the font works on Codemirror but the code ligatures do not render. – Mike Christensen Commented Mar 12 at 22:28
  • Thank you, I got the idea. This is not even close to ligature. Honestly, I have no idea how a font can recognize, say, 3 repeated code points such as ===. But apparently, you simply waste your time. Watch it: ≡ ≣ ≠ ?= ≤ ≥ ← ↑ → ↓ ↖ ↗. Isn't it better? – Sergey A Kryukov Commented Mar 12 at 23:06
  • I installed the font "CaskaydiaCove Nerd Font Mono" and tried this minimal demo. You can see in the output, the ligatures are rendered properly. Please share complete code to reproduce the issue. – Raghavendra N Commented Mar 30 at 12:04
  • 1 @Sergey A Kryukov: the point of ligatures is they only change the presentation of text by substituting certain character sequences with ligature glyphs (usually part of the text-shaping routine e.g harfbuzz) - the actual character/test data stays the same. So when copying the code you still get the same data. When you replace e.g => with a harcoded unicode arrow symbol you would obfuscate the code which is usually not desired for code examples – herrstrietzel Commented Mar 31 at 18:44
 |  Show 8 more comments

3 Answers 3

Reset to default 1 +500

By default codemirror should enable – or at least not disable – these code specific ligatures like in "CaskaydiaCove Nerd Font Mono".

On the other hand it's safe to say that codemirror doesn't really prioritize legacy compatibility and may use different CSS class name schemes depending on the used version.

Recommendations

  1. test your codemirror setup with the most minimal settings - e.g using a default theme with a manually defined font-family in CSS. If a this basic setup shows the ligatures correctly - there might be something wrong with a custom template
  2. Inspect your rendering in the browser via devtools and check the computed styles: These will tell you whether the rendered font is the defined family or a stytem default. Ideally, the codemirror elements have some explicit CSS rules enabling ligatures such as: font-variant-ligatures: contextual; or font-variant-ligatures: normal;
  3. Don't rely on locally installed fonts and prefer font loading via CSS @font-face. Local/system fonts can introduce weird cross-browser inconsistencies as some browser may block local fonts completely or choose another style/weight with the same internal font name
  4. letter-spacing will also disable any ligatures so make sure letter-spacing is set to zero or normal: letter-spacing: 0

const { basicSetup } = CM["codemirror"];
const { EditorView, keymap, lineNumbers } = CM["@codemirror/view"];
const { EditorState } = CM["@codemirror/state"];
const { javascript } = CM["@codemirror/lang-javascript"];
//const { defaultKeymap } = CM["@codemirror/commands"];

//let mode = legacyMode({ mode: javascript({ indentUnit: 4 }, {}) });

let state = EditorState.create({
    doc: `const test = (e)=>{
    let test = 1
    if(test===0 || test <=-2){
        console.log('test')
        }
    }`,
    extensions: [
        lineNumbers(),
        javascript(),
        basicSetup
    ]
});

let view = new EditorView({state});
document.querySelector("#editor").append(view.dom);

let view2 = new EditorView({state});
document.querySelector("#editor2").append(view2.dom);

let view3 = new EditorView({state});
document.querySelector("#editor3").append(view3.dom);

let view4 = new EditorView({state});
document.querySelector("#editor4").append(view4.dom);
@import 'https://fonts.googleapis/css2?family=Fira+Code:[email protected]';


@font-face {
    font-family: "CaskaydiaCove Nerd Font Mono";
    font-weight: 400;
    src: url("https://www.programmingfonts./fonts/resources/cascadia-code/cascadia-code.woff2")
        format("woff2");
}

.cm-content {
    font-family: "CaskaydiaCove Nerd Font Mono";
    font-variant-ligatures: contextual;
}

.fira *{
   font-family: 'Fira Code',monospace
}

.letter-spacing {
    letter-spacing: 0.001em;
}

.no-lig *{
    /*
    font-variant-ligatures: contextual;
    font-variant-ligatures: normal;
    */
    font-variant-ligatures: none;

}
<script src="https://codemirror/codemirror.js"></script>

<h3>Default: ligatures enabled</h3>
<div id="editor"></div>

<h3>Default: ligatures disabled due to custom letter spacing</h3>
<div id="editor2" class="letter-spacing"></div>

<h3>Default: ligatures disabled due to custom CSS rule</h3>
<div id="editor3" class="no-lig"></div>

<h3>Default: ligatures enabled - fira code</h3>
<div id="editor4" class="fira"></div>

You should also try to use a CDN hosted font like "Fira Code" from google fonts to make sure it's not some bundling relative path issue.

I used this code and it showed me ligatures

.CodeMirror {
    font-family: 'Fira Code', monospace !important;
    font-size: 14px;
    height: 300px;
    border: 1px solid #ccc;
}

This is how I initialize it.

const editor = CodeMirror(document.getElementById('my-editor-container'), {
    mode: "javascript",
    lineNumbers: true,
    theme: "default"
});

Fira code is just another font with ligatures so if it works yours should work.

Result:




if it is still doesn't work for you for some reason try this.

.cm-content {
    font-feature-settings: "calt" 1, "liga" 1;
}

Enable Ligatures via CSS: Add the following CSS to your styles to enable ligatures within the CodeMirror editor:

.cm-content {
  font-variant-ligatures: normal;
}

本文标签: htmlLigatures does not show up in codemirror editor using font that supports themStack Overflow