Example #1
0
    def run(self, module_name, lang):
        try:
            with open(op.module_filename(module_name, lang), 'x') as file:
                file.write('-----\n')
        except FileExistsError:
            sublime.error_message("Module file already exists")

        comm.op('addModule', {
            'module': module_name,
            'lang': lang
        })
        sublime.active_window().open_file(op.module_filename(module_name, lang))
Example #2
0
 def run(self, edit, module_name):
     comm.op('renameModule', {
         'module': op.view_module_name(self.view),
         'newName': module_name
     })
     new_file_name = op.module_filename(module_name, op.view_lang(self.view))
     os.rename(self.view.file_name(), new_file_name)
     self.view.retarget(new_file_name)
Example #3
0
 def _check_src_available(self, src_module, entry):
     """Check that we're not attempting to move an entry which is under edit"""
     src_view = self.window.find_open_file(op.module_filename(src_module))
     if src_view is not None and regedit.is_active_in(src_view):
         entry_obj = op.module_body(src_view).entry_by_name(entry)
         if entry_obj is None or entry_obj.is_under_edit():
             sublime.error_message(
                 "Source entry is under edit or not found")
             raise StopCommand
Example #4
0
    def run(self, edit):
        reg = single_selected_region(self.view)
        mtch = op.reference_at(self.view, reg)
        if mtch is None:
            star = None
            name = op.word_at(self.view, reg)
        else:
            star, name = mtch.group('star', 'name')

        res = comm.op('findReferences', {
            'module': op.view_module_name(self.view),
            'star': star,
            'name': name
        })
        if res is None:
            sublime.status_message("Unknown reference at point: \"{}\"".format(
                mtch.group()))
            return

        with active_view_preserved(self.view.window()):
            all_views = [
                self.view.window().open_file(op.module_filename(module_name))
                for module_name, entry_name in res
            ]

        def make_location(view, entry_defn_name, reg):
            row, col = view.rowcol(reg.begin())
            return (view.file_name(), "{}.{}".format(op.view_module_name(view),
                                                     entry_defn_name),
                    (row + 1, col + 1))

        def proceed():
            locations = []

            for view, (module_name, entry_name) in zip(all_views, res):
                # We also track to which definition occurences belong. We do this by
                # determining what is the key region with max index which is still fully
                # before the occurence region.
                regkeys = op.name_regions(view)
                k = 0
                entry_defn_name = "(unknown)"
                regs = view.find_all(r'(?<![\w$])\$\.{}\b'.format(entry_name))

                for reg in regs:
                    while k < len(regkeys) and regkeys[k].end() < reg.begin():
                        k += 1
                        entry_defn_name = view.substr(regkeys[k - 1])

                    locations.append(make_location(view, entry_defn_name, reg))

            navigate_to_symbol(sublime.active_window().active_view(), name,
                               locations)

        on_all_views_load(all_views, proceed)
Example #5
0
    def _check_anchor_available(self, dest_module, anchor):
        """Check that the anchor entry is not under edit (except definition editing).
        
        Other kinds of editing might fool the Sublime parser (e.g. ongoing renaming)
        """
        dest_view = self.window.find_open_file(op.module_filename(dest_module))
        if dest_view is not None and anchor is not None and \
                regedit.is_active_in(dest_view):
            mcont = op.module_body(dest_view)
            if anchor is True:
                entry_obj = mcont.entries[-1]
            elif anchor is False:
                entry_obj = mcont.entries[0]
            else:
                entry_obj = mcont.entry_by_name(anchor)

            if (entry_obj is None or entry_obj.is_under_edit()
                    and op.edit_cxt_for[dest_view].target != 'defn'):
                sublime.error_message(
                    "Anchor entry is under edit or not found")
                raise StopCommand
Example #6
0
    def run(self, src_module_entry, dest_module, anchor, before=None):
        src_module, entry = src_module_entry

        self._check_src_available(src_module, entry)
        self._check_anchor_available(dest_module, anchor)

        res = comm.op(
            'move', {
                'srcModule': src_module,
                'entry': entry,
                'destModule': dest_module,
                'anchor': anchor,
                'before': before
            })

        if not res['moved']:
            msg = ["Failed to move the entry because:\n"]

            if res['offendingRefs']:
                msg.append(
                    "the definition refers to names that could not be imported into "
                    "the destination module: {}".format(', '.join(
                        '$.' + r for r in res['offendingRefs'])))
            if res['blockingReferrers']:
                msg.append(
                    "these modules cannot star-import the entry from the destination "
                    "module: {}".format(', '.join(res['blockingReferrers'])))

            sublime.error_message('\n'.join(msg))
            return

        def process_source(view, edit):
            with regedit.region_editing_suppressed(view):
                entry_obj = op.module_body(view).entry_by_name(entry)
                view.erase(edit, entry_obj.reg_entry_nl)
                op.save_module(view)

        def process_destination(view, edit):
            with regedit.region_editing_suppressed(view):
                if anchor is None:
                    insert_at = op.reg_body(view).begin()
                else:
                    mcont = op.module_body(view)
                    if anchor is False:
                        insert_at = mcont.entries[0].reg_entry_nl.begin()
                    elif anchor is True:
                        insert_at = mcont.entries[-1].reg_entry_nl.end()
                    else:
                        entry_obj = op.module_body(view).entry_by_name(anchor)

                        if before:
                            insert_at = entry_obj.reg_entry_nl.begin()
                        else:
                            insert_at = entry_obj.reg_entry_nl.end()

                view.insert(edit, insert_at,
                            '{} ::= {}\n'.format(entry, res['newCode']))

                op.save_module(view)

        def process_other(view, module_data, edit):
            op.modify_module(view, edit, module_data)
            op.save_module(view)

        def proceed(src_view, dest_view, other_views):
            with exc_recorded() as exc_src:
                call_with_edit(src_view, partial(process_source, src_view))

            with exc_recorded() as exc_dest:
                call_with_edit(dest_view,
                               partial(process_destination, dest_view))

            exc_others = [exc_recorded() for view in other_views]

            for exc, view, module_data in zip(exc_others, other_views,
                                              res['modifiedModules']):
                with exc:
                    call_with_edit(view,
                                   partial(process_other, view, module_data))

            fmodules = {
                op.view_module_name(view)
                for exc, view in zip(exc_others, other_views) if exc
            }
            if exc_src:
                fmodules.add(op.view_module_name(src_view))
            if exc_dest:
                fmodules.add(op.view_module_name(dest_view))

            if fmodules:
                sublime.error_message(
                    "The following modules failed to update (you may consider refreshing "
                    "them from the image): {}".format(', '.join(fmodules)))

                if exc_src:
                    print("Source updating failed:")
                    traceback.print_exception(type(exc_src.exc), exc_src.exc,
                                              None)
                if exc_dest:
                    print("Dest updating failed:")
                    traceback.print_exception(type(exc_dest.exc), exc_dest.exc,
                                              None)
                for view, exc in zip(other_views, exc_others):
                    if not exc:
                        continue
                    print("Modified module \"{}\" updating failed:".format(
                        op.view_module_name(view)))
                    traceback.print_exception(type(exc.exc), exc.exc, None)
            elif res['danglingRefs']:
                sublime.message_dialog(
                    "These references appear to be dangling: {}".format(
                        ','.join('$.' + r for r in res['danglingRefs'])))
            else:
                sublime.status_message("Move succeeded!")

        with active_view_preserved(self.window):
            src_view = self.window.open_file(op.module_filename(src_module))
            dest_view = self.window.open_file(op.module_filename(dest_module))
            other_views = [
                self.window.open_file(op.module_filename(d['module']))
                for d in res['modifiedModules']
            ]

        on_all_views_load([src_view, dest_view] + other_views,
                          lambda: proceed(src_view, dest_view, other_views))