"Correct" way of programmatically changing theme?


#1

I’m authoring specs that involve changing themes to test motif-sensitive enhancements. Currently, I’m doing this:

Promise.all([
	atom.packages.activatePackage "atom-light-ui"
	atom.packages.activatePackage "atom-light-syntax"
]).then ->
	{body}         = document
	themeClasses   = /(?:^|\s+)theme-.+-(?:ui|syntax)\b/g
	className      = body.className.replace themeClasses, ""
	body.className = className + " theme-#{name}-ui theme-#{name}-syntax"
	atom.themes.emitter.emit "did-change-active-themes"

Which is working most of the time. Sometimes the wrong theme is activated, which leads me to believe I’m doing this wrong (note: atom.themes.activateThemes doesn’t appear to do anything when I run it in devtools).


#2

I think your code is lacking the change in the config object:

atom.config.set('core.themes', ['atom-light-ui', 'atom-light-syntax'])

Activating a theme doesn’t automatically make it the current theme.


#3

How does activating a theme differ from activating the theme’s package?


#4

Hmm, interesting, I made a few more tests to make sure I wasn’t saying BS here.

So:

Activating a theme package seems to properly enable the theme, ex. running atom.packages.activatePackage('test-syntax') in the console will properly modify the theme of active editors.

But:

  • The corresponding setting isn’t updated. So the change won’t be persisted. And UI themes like one-dark won’t update their stylesheet (which is derived from the syntax theme).
  • If I try to activate another theme package after that, the change isn’t effective. Like if there could be only one active theme at once.

Here’s a gif that demonstrates the issue:


#5

If I try to activate another theme package after that, the change isn’t effective. Like if there could be only one active theme at once

Aye, one of the things I noted was a weird “stickiness” after changing a theme. Possibly the theme has to be disabled before switching to another?


#6

Edit: Had a suggestion but nvm. Abe’s config.set seems to be all one would need. That said, not sure why activatePackage doesn’t work.


#7

That’s what I concluded, looking at the settings view code I found that it’s the only operation that is performed by the view when you pick a theme from the selects. I guess there’s a listener somewhere that take care of disabling and activating the package based on your preferences.


#8

Okay, weird… the callback passed to atom.themes.onDidChangeActiveThemes isn’t firing when I change themes with atom.config.set …. Bear in mind it works fine in the devtools, just not in spec mode. :S

The specs are here if you’d like a look.


#9

@Alhadis I tried cloning the repo and running the specs in v2 branch, but I fear I’m missing something out because it seems I’m not running the specs using the custom test runner specified in the package.json (it runs with jasmine and not mocha+chai which obviously won’t work). Any clue?


#10

@Abe You won’t be able to run the repo until the Atom team finally merge several important pull requests. These address shortcomings in the File-Icons API that need to be fixed before v2 can be released.

(No idea why it’s taking so excruciatingly long, but it’s straining my patience)


#11

You’ll also need to run apm install and restart Atom before the custom test-runner can be used.

And by “restart”, I actually mean quit and reopen the entire program. Reloading the workspace’s window won’t work because Atom caches package.json files at startup. I learned that the hard way, heh.

ANYWAY. I managed to work around the issue. =) There was a race condition with refreshing the icon tree that I resolved by adding a proper callback, rather than delaying execution by an arbitrary amount of time. So, all’s good! For now.