How can I specify a different font family for different sources?


#1

I’ve got the following in my config:

"*":
  editor:
    fontFamily: "Monoid, Hasklig, Source Code Pro, Monaco, Fira Code, Fira Mono, PT Mono, Andale Mono, Menlo, monospace"
".source.gfm":
  editor:
    fontFamily: "-apple-system, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans"
    showInvisibles: true
    softWrap: true

However it seems fontFamily is not supported for language scoped configurations, as indicated by http://blog.atom.io/2014/10/31/language-scoped-config.html because showInvisibles and softWrap work fine, but fontFamily doesn’t.

Can scoped fontFamily support be added?


#2

There are ways that you can use your styles.less to do this kind of thing, but they can cause problems with Atom’s editor rendering system last I checked. Adding this capability isn’t high on our priority list right now.


#3

I accomplished this by adding a fontFamilyDefault key to my config.cson and adding the following to init.coffee:

# Set font based on active scope
atom.workspace.onDidChangeActivePaneItem (editor) ->
  return unless editor = atom.workspace.getActiveTextEditor()

  fontFamilyDefault = atom.config.get('editor.fontFamilyDefault')
  atom.config.set('editor.fontFamily', fontFamilyDefault)
  fontFamilyForScope = atom.config.get('editor.fontFamily', scope: editor.getRootScopeDescriptor())

  if fontFamilyForScope != fontFamilyDefault
    scope = editor.getRootScopeDescriptor()
    atom.config.set('editor.fontFamily', fontFamilyForScope)

Relevant config.cson entries:

"*":
  editor:
    fontFamily: "Anonymous Pro"
    fontFamilyDefault: "Anonymous Pro"
".perl.source":
  editor:
    fontFamily: "Times New Roman"

#4

@DamnedScholar I wonder if that could become a plugin, @leedohm would the above solution be suitable for a pull request?


#5

Considering the scope of the solution, the most time-intensive part would be publishing it. However, I would consider it bad form to publish a package that requires a user edit to config.cson in order to function. The package should handle that on its own and it can’t because there’s no way to tell the difference between a config value being changed via Settings and one being changed programmatically. The package would have to have its own interface for picking fonts (which could make it easier for novice users to define fonts for different scopes).

would the above solution be suitable for a pull request?

My solution is a kludge based on lack of support. A pull request would look rather different and it wouldn’t even need to mess with changing the universal font.


#6

We wouldn’t accept it as-is (the redundant editor.fontFamilyDefault would be the issue there), but I can check with the dev team and see if it would be acceptable.


#7

For this functionality to be integrated into Atom, the renderer, when choosing how to style the content of the TextBuffer, would have to look at the source config and give that fontFamily setting priority over the one under "*". I’m sure that’s also pretty easy to do, but I haven’t looked at it.


#10

@leedohm, did you end up speaking to the dev team about this? DamnedScholar provided a nice description of how this could be implemented, although it’s unclear to me if this ever made it to a Github Issue:

For this functionality to be integrated into Atom, the renderer, when choosing how to style the content of the TextBuffer, would have to look at the source config and give that fontFamily setting priority over the one under “*”. I’m sure that’s also pretty easy to do, but I haven’t looked at it.

I’ve adapted @DamnedScholar’s code to add support for scope-specific font size as well.

In config.cson:

"*":
  editor:
    fontFamily: "Menlo, Consolas, 'DejaVu Sans Mono', monospace;"
    fontFamilyDefault: "Menlo, Consolas, 'DejaVu Sans Mono', monospace;"
    fontSize: 14
    fontSizeDefault: 14
".gfm.source":
  editor:
    fontFamily: "Avenir Next"
    fontSize: 18

In init.coffee:

# Set font based on active scope
atom.workspace.onDidChangeActivePaneItem (editor) ->
  return unless editor = atom.workspace.getActiveTextEditor()

  # Configure font family
  fontFamilyDefault = atom.config.get('editor.fontFamilyDefault')
  atom.config.set('editor.fontFamily', fontFamilyDefault)
  fontFamilyForScope = atom.config.get('editor.fontFamily', scope: editor.getRootScopeDescriptor())

  if fontFamilyForScope != fontFamilyDefault
    scope = editor.getRootScopeDescriptor()
    atom.config.set('editor.fontFamily', fontFamilyForScope)

  # Configure font scope
  fontSizeDefault = atom.config.get('editor.fontSizeDefault')
  atom.config.set('editor.fontSize', fontSizeDefault)
  fontSizeForScope = atom.config.get('editor.fontSize', scope: editor.getRootScopeDescriptor())

  if fontSizeForScope != fontSizeDefault
    scope = editor.getRootScopeDescriptor()
    atom.config.set('editor.fontSize', fontSizeForScope)

PS: Apologies for the deleted posts above (which are set to disappear in 24 hours). Being new to this forum and unable to edit my posts for formatting errors is a challenging combination.


#11

Thank’you @michaelstepner for the new code. I was using a more naive way which was giving me rendering problems when using different sizes, now this works perfectly.

In my opinion, you should also add a setting for line-height: different fonts often work best with different line-heights.


#12

Sounds like a good idea to me, though I’ve been happy with having the same line height across all my scopes/fonts. Everyone might have a different set of font parameters they’ll want to tweak to get things looking just right for them, and I believe all of the font parameters should be configurable as scope-specific parameters.

Relatedly, it seems that the lineHeight parameter isn’t documented in the Flight Manual’s Basic Customization page. I’ve submitted a PR to add it.


#13

@michaelstepner Bug report: if you have a window open with a non-markdown file, and then you open a new window (from another directory) with a markdown file, the font changes for the non-markdown file too.


#14

Same trouble @hugo ! Any recommendation?


#15

https://img.clipartfest.com/76f760d37c54a5901e2befa6f4c59b2f_questions-question-mark-clip-question-mark-clipart-transparent-background_2400-2400.png


#16

I can replicate this issue too. Good catch @hugo. I’m not entirely surprised… the code posted above that makes this work is a rough hack.

Really, what ought to happen is that scope-specific font options should be supported in code Atom the same way scope-specific tabLength is supported. Someone should open an issue on Github to propose this change.

@leedohm, you mentioned above (8 months ago) that you would “check with the dev team and see if it would be acceptable.” Could you let us know if you spoke to the devs about this, and if you remember how that conversation went? I think scope-specific font options make a lot of sense, and this thread suggests there’s a fair amount of interest in them. I don’t have the skills to create a PR for this, but I’d be happy to open an issue.


#17

Someone should open an issue on Github to propose this change.

I’ve just done so:

https://github.com/atom/atom/issues/16232