-
-
Save UltraInstinct05/e5df44c6eb6b942aac0d659cfc0efdeb to your computer and use it in GitHub Desktop.
import os | |
import sublime | |
import sublime_plugin | |
def get_npm_scripts(chosen_directory): | |
""" Gets the list of npm scripts defined in the package.json | |
Args: | |
chosen_directory (str) : The absolute path of the chosen directory. | |
Returns: | |
npm_scripts (list) : The list of npm scripts defined in package.json | |
""" | |
package_json_path = os.path.join(chosen_directory, "package.json") | |
with open(package_json_path) as package_json: | |
json_data = sublime.decode_value(package_json.read()) | |
npm_scripts = [key for key in json_data["scripts"]] | |
return npm_scripts | |
class RunNpmScriptsCommand(sublime_plugin.WindowCommand): | |
""" Lists all npm projects & then lists all npm scripts. Selecting one of them executes the said npm script. | |
""" | |
def run(self, use_terminus=False): | |
"""Invoked when the command is run and shows a list of folders. | |
Args: | |
None | |
Returns: | |
None | |
""" | |
is_terminus = use_terminus | |
global is_terminus | |
npm_projects = [x for x in self.window.folders() if os.path.isfile(os.path.join(x, "package.json"))] | |
if len(npm_projects) == 0: | |
self.window.status_message("No folder in the side bar is an npm project") | |
return | |
elif len(npm_projects) == 1: | |
self.show_npm_scripts(npm_projects, 0) | |
return | |
self.window.show_quick_panel(npm_projects, lambda id: self.show_npm_scripts(npm_projects, id)) | |
def show_npm_scripts(self, npm_projects, id): | |
"""Shows the npm scripts defined in the package.json of the chosen directory. | |
Args: | |
npm_projects (list) : List of all folders in side bar that are npm projects. | |
id (int) : The id of the selected folder. | |
Returns: | |
None | |
""" | |
chosen_directory = npm_projects[id] | |
if id >= 0: | |
npm_scripts = get_npm_scripts(chosen_directory) | |
if len(npm_scripts) == 0: | |
self.window.status_message("No npm scripts in package.json") | |
else: | |
self.window.show_quick_panel(npm_scripts, lambda id: self.run_build_system(npm_scripts, chosen_directory, id)) | |
else: | |
self.window.status_message("No directory chosen") | |
def run_build_system(self, npm_scripts, chosen_directory, id): | |
"""Runs the exec command & passes it on some parameters for running the chosen npm script. | |
Args: | |
npm_scripts (list) : A list of npm scripts defined in the package.json of the chosen directory. | |
chosen_directory (str) : The absolute path of the selected directory | |
id (int) : The id of the npm script selected. | |
Returns: | |
None | |
""" | |
if id >= 0: | |
is_terminus_installed = "Terminus" in sublime.load_settings("Package Control.sublime-settings").get("installed_packages") | |
target = "terminus_exec" if (is_terminus and is_terminus_installed) else "exec" | |
self.window.run_command(target, { | |
"shell_cmd": "npm run {}".format(npm_scripts[id]), | |
"working_dir": chosen_directory | |
}) | |
else: | |
self.window.status_message("No npm script selected") |
Thanks for the fixes. :)
Personally, I would like to see the project before I run the said script(s)
For me it feels like redundant information as I know which project I have open so I know what to expect.
For point 4, I would like some more clarifications. Do you mean using the terminus_exec command
I meant to use terminus_exec so that the build results open in terminus view/panel.
BTW. I don't mind the status messages now but does it really make sense to show them when user explicitly cancels the command palette input?
I have now added the ability for users to use the terminus package. If the user has Terminus
installed and the setting use_terminus
is set to true
, then the script runs in a terminus panel. By default, the setting is set to false
and the plugin itself reverts to using exec
if you don't have Terminus
installed. Please have a look at the instructions for the updated information.
Just a suggestion: You could just allow specifying use_terminus
as command argument. Then there would be no need for handling settings.
Unless you plan to release it as a normal package, then setting would be more user friendly maybe.
@rchl, Yes, thanks for that idea. That is a more easier approach (Since there is only one setting at the moment). I have updated accordingly. Apologies for all these updates (read correcting my noob "mistakes" :)).
As of this moment, I have no plans to release it to PC, as this is a very simple plugin and the instructions should be clear even for those who have not used plugins before.
Globals are bad (global is_terminus
).
You should just pass the setting along the chain of execution.
Also, you should specify default value for the command argument (use_terminus=False
), otherwise it will crash when not specified.
@rchl Yes, I do know that globals are bad but I don't know if I can pass it down to the run_build_system
method in a "cleaner" way in the sense that the show_npm_scripts
method has nothing to do with use_terminus
but it still gets that value (Kind of like props in React, if you need to pass some piece of state to the last component in a list of components, then the intermediate components also get's the state even though that piece of state is of no use in those components). As for the other silly mistake, it's fixed. Thanks a lot !
I have updated the plugin to now show only the npm scripts in a panel if there is only one project in the sidebar that contains a package.json
so now there is no need of an intermediate panel that shows only one project in a panel.
Please feel free to report any issues.
Just a question,
If I have a script serve
which starts a server at localhost:3000
, for example.
How will I be able to stop the server?
@predragnikolic Right now I am not sure if there is a way I can handle that from the plugin itself (I'll look into it). As a workaround, you can define a keybinding as follows :-
{
"keys": ["ctrl+alt+6"],
"command": "exec",
"args": {
"kill": true,
},
}
which should kill the running server when the exec
command is running. If you are using terminus
however, this is not required as you can press ctrl + c in the terminus build panel and kill the server.
Thanks :-)
Points 1 & 2 should now be fixed. I've replaced all intrusive OS dialog messages with status messages in the status bar. About point 3, I guess it depends. Personally, I would like to see the project before I run the said script(s). For point 4, I would like some more clarifications. Do you mean using the
terminus_exec
command or do you want to actually run the chosen script in a terminus view/tab withterminus_open
command ? Thanks for the feedback as well.