How Atom Activate (start) / Deactivation (stop) a package


#1

Hello.

The package.json file represents the definition of the package and the resources used. This definition file states how the package is activated for use, but there is no definition for halting its use?



Two of keys in package.json define what ‘starts’ the package:

  • activationCommands
  • activationHooks

Those are linked to the function call activate (state) {}.



I have the following for a grammar package I am modifying:

"activationHooks": "scl-language:grammar-used"

./lib/main.js looks like follows (for testing):

'use babel';

import {CompositeDisposable, Disposable} from 'atom';

export default {
  
  subscriptions: null,
  
  activate (state) {
    console.log('start')
  },
  
  deactivate() {
    console.log('stop')
  }
};

The code will write to the developer’s console as soon as a file is opened that contains the grammar. That part is working as intended. The code remains loaded in memory even after all sessions of the grammar has been closed. The deactivate is only triggered just before the Atom application is closed.

Is there a deactivationHooks key or something like it. I am hoping to add the functionality to unload the memory of the package as soon as there are no more need for it. That is when all SCL-language grammar files are closed.

The next issue is to ensure that the activation phase is executed for each session being opened.

Any constructive ideas - please?


#2

It’s not documented as a public function, but atom.packages does give you the ability to deactivate a specific package.


#3

Thank you for your reply.

The result from the command in the developer’s console:

-> atom.packages.deactivatePackage("language-scl")

    SCL -> stop                                     main.js:18 

<- Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}

That part looks good.

BUT opening my grammar package does not activate when opening a file that contains the grammar. language-scl cannot even be seen on the available grammar list. Restarting Atom with the file still open, will have the system respond in the console:

    SCL -> start                                   

So… is it possible to unload the memory of a package (or most of it) and still have it enable itself with the intended activation procedure?

~


#4

A ‘fun’ fact…
(ignore the deactivation for a moment)

Inside my language grammar’s package.json file is the key entry -

"activationHooks": "scl-language:grammar-used"

The language grammar is not listed as an active grammar until the grammar is needed.

Procedure used for testing if my grammar package was loaded->

  1. Close all text editors

  2. Close the Atom application

  3. Reopen the Atom application

  4. Open the developer’s console and execute:

-> atom.packages.isPackageActive("language-scl")
<- false
  1. Also execute (below) to double check all active packages.
x = atom.packages.getActivePackages();
for (let n =0; n < x.length; ++n){
  console.log(x[n].name);
}
  1. Open a file that uses the grammar.

  2. Execute in the console:

-> atom.packages.isPackageActive("language-scl")
<- true
  1. Double check in named list:
x = atom.packages.getActivePackages();
for (let n =0; n < x.length; ++n){
  console.log(x[n].name);
}


Conclusion


It is recommended to have the key entry in a language grammar’s package.json file -

"activationHooks": "scl-language:grammar-used"

This ensures the grammar package is not loaded into active memory until being used for the first time. That would mean that grammars that are never used, does not need to be disabled to better memory usage.

… should this be a tip?
…or did I miss something?


#5

I don’t think the gains are as big as you imagine. Regardless of hooks, the grammars will all be read into Atom (can check with atom.grammars.grammars.map(g => g.name || g.id)).

When active, the “active package” is mostly just the generic package object with some metadata and null as the mainModule (of course, this is different if the package actually has a main module and such).


#6

That may or may not be the case.

I am thinking of a package like python-indent that should be bound to one grammar. Yet it starts up as the Atom application does. Code is bound to the event of “executing” the newline action. The linked code in turn will check if the grammar is actually Python.

Having several packages subscribing to all sorts of events even if these are not active, does not seem the most effective way to do things. It adds up - I would imagine. Packages subscribing to events that happen too regularly cripples the whole application - ironically even if it is not even used.




Now let us assume my worries are much-to-do-with-nothing.

So let us say for academical purposes I want to streamline my own works. Having package loaded into memory only when needed - Please how do I do that?


#7

That package isn’t a shining example of laziness. It doesn’t have activation hooks, doesn’t watch for when a python grammar gets activated, and doesn’t disable itself when the grammar changes.

But that kind of thing is on the package author to implement. And even if Atom made everything easy, chances are packages like that still wouldn’t use it. Especially seeing as activation hooks are already offered, but it doesn’t use them.


#8

My intention with this conversation is not to dictate how things should be done.

I am asking for help. I would like to have the package I am working on, to activate when it is needed and deactivate when it is not needed. The intent is to reduce the CPU/memory footprint as much as is practical.

Call it is a journey of academical discovery.

For my case atom.packages.deactivatePackage("language-scl") removes the chance to re-activate the package. How to get the package in the same “prepared” state without being “activated” as with Atom start-up?


#9

First, you’d need to decide what makes it deactivate. Is it when all the files using some grammar are closed? What if the user is constantly closing and opening only a single file of that kind? Fully deactivating a package and reactivating several times could be relatively expensive, especially if it’s using other modules.

The way I handle this with my packages, is have a “editor manager” that hooks into new editor and grammar change events, adding or removing my stuff as desired. The package itself is always active from when it’s first enabled, but the “heavy stuff” is only active on editors with the right grammar.

I dont follow; how much do you want loaded? The grammar itself will always be loaded, and you don’t want to change that.


#10

For a language package, that’s not necessary. Your language-scl.cson file will be converted and read in mere processor cycles because computers are ridiculously fast at processing plain characters. No computationally expensive work happens until you open a file with the language in question and Atom starts highlighting.


#11

Perhaps it will help if I try explaining in a picture