"use babel";
import path from 'path';

function log(obj) {
  if ( atom.config.get('atom-hot-package-loader.outputLog') ) {
    console.log(obj);
  }
}

function unloadPackage(packageName) {
  return new Promise((resolve) => {
    let disposable = atom.packages.onDidUnloadPackage((pack) => {
      if (packageName === pack.name) {

        Object.keys(require.cache)
        .filter((p) => {
          return p.indexOf(pack.path + path.sep) === 0;
        })
        .forEach((p) => {
          delete require.cache[p];
        });
        delete atom.packages.loadedPackages[packageName];

        resolve(packageName);
        log('didunloadPackage');
        disposable.dispose();
      }
    });
    atom.packages.unloadPackage(packageName);
  });
}

function activatePackage(packageName) {
  return new Promise((resolve, reject) => {
    let disposable = atom.packages.onDidActivatePackage((pack) => {
      if (packageName === pack.name) {
        if (atom.packages.enablePackage(packageName)) {
          resolve();
        } else {
          log(`Can't loading ${packageName}`);
        }
        disposable.dispose();
      }
    });
    atom.packages.activatePackage(packageName);
  });
}

function deactivatePackage(packageName) {
  return new Promise((resolve) => {
    let disposable = atom.packages.onDidDeactivatePackage((pack) => {
      if (packageName === pack.name) {
        resolve();
        log('deactivatePackage');
        disposable.dispose();
      }
    });
    atom.packages.deactivatePackage(packageName);
  });
}

export default async function reloadPackage(packageName, reloadGrammars = false) {

	if (packageName === null) return;

  await deactivatePackage(packageName);

  if (!atom.packages.isPackageDisabled(packageName)) {
    atom.packages.disablePackage(packageName);
  }

  if (atom.packages.loadedPackages[packageName]) {
    await unloadPackage(packageName);
  }

	await activatePackage(packageName).then(() => {

    if (reloadGrammars) {
      atom.workspace.getTextEditors().forEach((editor) => {
        editor.reloadGrammar();
      });
    }

    log(`Reload ${packageName}.`);
  }).catch(() => {
    log(`Can't loading ${packageName}`);
  });
}

@@ -1538,16 +1538,518 @@
  %7D);%0A%7D%0A%0A
+function reloadGrammars(pack) %7B%0A  const %7Bgrammars%7D = pack;%0A  atom.workspace.getTextEditors().forEach((editor) =%3E %7B%0A    const %7BpackageName, path: grammarPath%7D = editor.getGrammar();%0A    if (packageName !== pack.name) return;%0A%0A    const grammarFilename = path.basename(grammarPath);%0A    const newGrammar = grammars.find((grammar) =%3E path.basename(grammar.path) === grammarFilename);%0A    if (newGrammar) %7B%0A      editor.setGrammar(newGrammar);%0A    %7D%0A    else %7B%0A      editor.reloadGrammar();%0A    %7D%0A  %7D);%0A%7D%0A%0A
 export d
@@ -2097,17 +2097,21 @@
 geName, 
-r
+needR
 eloadGra
@@ -2459,111 +2459,84 @@
 %3E %7B%0A
-%0A
     
-if (reloadGrammars) %7B%0A      atom.workspace.getTextEditors().forEach((editor) =%3E %7B%0A        editor.r
+const pack = atom.packages.getActivePackage(packageName);%0A%0A    if (needR
 eloa
@@ -2543,27 +2543,46 @@
 dGrammar
-();
+s) %7B
 %0A      
-%7D
+reloadGrammars(pack
 );%0A    %7D

Refresh grammars on editors based on grammar path. And skip editors, not affected by grammar.