Build System build options panel in Sublime Text 2. (or how the bike was invented)

    Idea and implementation: we press a shortcut in SublimeText2, we get a panel with a list of build options, automatically generated by the file selected by the Build System, select the desired option and observe how the project assembly process is directly displayed in the Sublime Text 2 interface.

    I must say right away that here I share my invaluable experience in joint development of the ProjectBuild plugin for Sublime Text 2, because as a result, only experience was obtained, since, as it turned out, there was no need to implement this plugin, and the whole process turned out to be a bicycle invention. Sadly, the experience is still priceless. The narrative will be such that the "bike" will be said only at the end.

    Introduction


    The result of the previously written article “Automating the assembly of a project in Sublime Text 2 using Ant” was the ability to call in Sublime Text 2 various build variants of the selected Build System (using Ant as an example) using the assigned keyboard shortcuts for them. (now I would also use the word “tuning” in the topic of that post)

    What I did not like about this approach:
    1. Different Build Systems could have completely different names for their variants, and keyboard shortcuts were already clearly tied to specific variant names, which might not have been in another Build System. My assumption was that most developers do not often have to switch between multiple Build Systems, and most developers work with one Build System. And if the developer wants, he will change the keyboard shortcuts again. But you must admit, this is a little annoying. And this must be remembered. And in continuation, also
    2. You need to remember all the keyboard shortcuts you have assigned. It is clear that there are basic “F7”, “Ctrl + B”, “Ctrl + Shift + B” - but for each of your options there will be one more combination. This means that you need to either redefine the key combination that already exists, or find an unused one that would be convenient for both the fingers and the brain. I tried to find convenient unoccupied ones, but settled on redefinition. And this is also depressing, since it can potentially deprive you of the original capabilities of these combinations when redefined. And also to limit in the future when you need new keyboard shortcuts for new plug-ins, and convenient ones are already used for calls of different build-options.


    And then I tried the ProjectBuild plugin for Sublime Text 2 from snegovikufa unsubscribed to me in the comments. What I really, really liked was the drop-down panel with a list of commands. By selecting an item from the list, it was possible to run the appropriate command. All the settings for this plugin were stored in a separate file, access to which was from the menu of Sublime Text 2 itself, where you could list the list of names and their corresponding commands. Simply put, this plugin could be configured to run a “third-party program” directly from the Sublime Text 2 interface. And in particular, it could be used to run Ant with names of necessary targets. I screwed ProjectBuild on my AntProjectBuilder.sublime-build. So this solved the second problem. We assign one keyboard shortcut (yes even “Ctrl + Shift + B”), it forms the ProjectBuild plugin panel in the Sublime Text 2 interface,

    But the plug-in worked in such a way that while calling a “third-party program”, although it did not block the interface of Sublime Text 2 itself, it did not leave any traces of the success or failure of the call. For example, my command line was called, Ant worked out in it, and it disappeared. There were no traces left in the console of Sublime Text 2 itself. And this was achieved only with locking the Sublime Text 2 interface. That is, they called the command, the Sublime Text 2 interface paused, and after working out this process, it spat out all its output to the Sublime Text 2 console. We could not observe the whole process “along the way”.

    And with this use, when ProjectBuild should implement the functionality of the Sublime Text 2 build mechanism, the first problem was not solved - explicitly specifying options, and there was also unnecessary configuration. I had to configure ProjectBuild in order to create a list of options for the panel, although this list of options is already directly in the "* .sublime-build" file of the selected Build System. I contacted snegovikufa , he quickly put me in the know how to work with GitHub, and I started to change the plugin.

    Offtopic about the process of modifying the ProjectBuild plugin


    Github

    I was very pleased with this system of "code accounting" (of course I exaggerate), I had never worked with git before, but it took less than half an hour to figure it out, especially since there is an exhaustive manual on git for Linux as well and for Windows users on GitHub itself. I wrote a working code, snegovikufa qualitatively reworked it for Python notation, and so on, correcting each other and cheating, I got the result, the licked working result is now in the dev thread Thing! My first impression, collaborative development and git (GitHub in particular) are made for each other.

    Sublime Text 2 API and Python

    There are official and unofficial documentation. At first it seemed that the API capabilities in Sublime Text 2 is not so great , and but they were enough. What was missing was implemented in Python. As said earlier, I do not know Python, but for the development of plug-conceived functionality are great and the x knowledge and did not need to. And snegovikufa quickly corrected potentially incomprehensible moments for third parties. The only thing I wanted to find for the sake of interest, but could not, was a list of all the possible keys and Settings values ​​that Sublime Text 2 had by default, although it might have been poorly searched.

    According to the "* .sublime-workspace" file format, the documentation says that this is the JSON format, but it was found out that an error may occur when json-parsing this file. The fact is that the json key in its data may be empty, but this was ignored by the ProjectBuild plugin like this:

    ... json.load (f, strict = False)
    

    Even with Sublime Text 2, a variable with "$ project_path" may be involved in the "* .sublime-build" file, and I don’t understand why the developers of Sublime Text 2 did not provide for its (and others) use in the paths of keyboard shortcuts, where For example, third-party sublime programs are called. Maybe this is for security reasons, so that some plug-in for the worked out combination of keys doesn’t rest something “for itself” from the project, but still.

    Plugin Summary Code

    Spoiler
    import sublime
    import sublime_plugin
    import json
    import sys
    import os
    classProjectBuildCommand(sublime_plugin.TextCommand) :defrun(self, edit = None) :# Save file if dirtyif self.view.is_dirty () :
                self.view.run_command ('save')
            ############################################## Определяем файл .sublime-workspace# он должен быть размещен в одной из корневых директорий# проекта и должен быть единственным#
            workspace_file = None
            root_folders = self.view.window ().folders ()
            for dir_ in root_folders :
                for dir_item in os.listdir (dir_) :
                    if dir_item.endswith ('.sublime-workspace') :
                        if workspace_file == None :
                            workspace_file = os.path.join (os.path.normpath(dir_), dir_item)
                        else :
                            self.showError (
                                'Must be only one ".sublime-workspace" file in project root folder.\n''Plugin found %s and %s files.' %
                                (workspace_file, os.path.join (dir_, dir_item)))
                            returnif workspace_file == None :
                self.showError (
                    'There are no ".sublime-workspace" file in any root folder of project.')
                return
            self.debug(workspace_file)
            ########################################################################################### Получаем относительный путь до файла текущей Build System#with open (workspace_file) as f :
                try:
                    workspace_json_data = json.load (f, strict = False)
                except Exception, e:
                    self.showError (
                        'File .sublime-workspace is empty or has incorrect json data')
                    returnifnot'build_system'in workspace_json_data :
                self.showError (
                    'There are no "build_system" value in %s file.\n''Choose Build System and save project.' % workspace_file)
                return
            build_filename = workspace_json_data['build_system']
            self.debug(build_filename)
            ########################################################################################### Определяем наличие файла текущей Build System# по полному пути до него# 
            build_filename_fullpath = os.path.normpath( os.path.join(os.path.dirname(sublime.packages_path()),build_filename))
            ifnot(os.path.isfile(build_filename_fullpath)):
                self.showError (
                    'Plugin could not find Build System file: "%s".' %
                    build_filename_fullpath)
                return
            self.debug(build_filename_fullpath)
            ########################################################################################### Загружаем JSON данные#with open (build_filename_fullpath) as f :
                try:
                    json_data = json.load (f)
                except Exception, e:
                    self.showError (
                        'File %s is empty or has incorrect json data' %
                        build_filename_fullpath)
                    return########################################################################################### Формируем словарь build-вариантов текущей Build System#
            build_variants = []
            if"cmd"in json_data:
                build_variants.append (['Default', " ".join (json_data["cmd"])])
            for variant in json_data.get ("variants", {}) :
                build_variants.append (
                    [variant['name'], " ".join (variant['cmd'])])
            ########################################################################################### Демонстрируем панель вариантов.#defrun(selected) :if (selected >= 0) :
                    self.execute_variant (build_variants[selected][0])
            names = [name for name, args in build_variants]
            self.view.window ().show_quick_panel (names, run)
            #############################################defexecute_variant(self, variant_name) :
            self.view.window ().run_command ("build", {"variant": variant_name})
        defshowError(self, err) :# демонстрируем сообщение об ошибке через Sublime API # иногда не срабатывало, хотя оно и должно было появляться
            sublime.error_message ('ProjectBuild:\n\n%s' % err)
        defdebug(self, message) :# change True to False or vice versaif (False): print message
    

    findings


    Now ProjectBuild does not need a config. You just need to choose the necessary Build System (standard system or your own, like my "AntProjectBuilder.sublime-build"). Save the project in Sublime Text 2 so that in one of its root folders lies the project manifest file "* .sublime-workspace". The ProjectBuild plugin monitors the existence of this file and its uniqueness, since information about the current Build System is taken from it. When changing the Build System in Sublime Text 2, remember to save the project so that the above file is updated. We press the keyboard shortcut assigned to ProjectBuild and see a panel with a list of build options. The list is generated automatically according to the description of the options of the Build System selected in Sublime Text 2 existing in the "* .sublime-build" file.

    https://habrastorage.org/getpro/habr/post_images/d57/17b/7cd/d5717b7cd5bc02bb9b1ae0ab8d212503.png

    The problems indicated at the very beginning of the article were successfully resolved: one shortcut was used and it works with the build mechanism of Sublime Text 2 itself and in its interface without tight binding and explicit naming of called build variants.

    The plugin has room for improvement, for example, platform-specific options that can be specified in the Build System file are now ignored, but for me personally, it’s quite enough for now, and I need exactly what it implements now.

    In fact, it is difficult to say whose contribution is greater, and is it important if, as a result, the ProjectBuild plugin became what it probably should have been. And it’s a sin to hide, I feel an indescribable sense of pride that there wasn’t such a thing in the interface and functionality of Sublime Text 2, but now there is one, and that it was partially written by me. (here I didn’t yet know about the “bicycle”, oh, woe is me, woe)

    The previous version of ProjectBuild will most likely be converted into the OneHotkey plugin by grouping commands into one shortcut, not necessarily building commands, but just running third-party commands for Sublime Text 2 programs, etc. and the configuration file that ProjectBuild used to have and it turned out to be superfluous for it is already useful there, because it contained redundant information for the build mechanism.

    Promised bike


    All the islands have long been open ... As it turned out, already in Sublime Text 2 there is already the ability to call up the options panel of the current Build System, you just need to add a keyboard shortcut:

    { "keys": ["f8"], "command": "show_overlay", "args": {"overlay": "command_palette", "text": "Build: "} }
    

    https://habrastorage.org/getpro/habr/post_images/323/c2e/2a8/323c2e2a8b882b9c2e2677b19284dd15.png

    And this panel, it would not be sad to talk about it, is more convenient, since it does not attach you to the "* .sublime-workspace" file and shows the assigned keyboard shortcuts for each option, if any. However, it does not support their sorting, and the plugin can be finalized for ordering options (although maybe again I don’t know what).

    https://habrastorage.org/getpro/habr/post_images/8f7/d2a/255/8f7d2a255758a04f201d9f8a6c3e5a93.png

    Probably all you can squeeze out of all this is to go back to OneHotkey.

    Thanks for attention.

    Also popular now: