Пример #1
0
    def get_path(self, event, for_context_menu=False):
        if self.view.file_name() is None:
            return
        pt = self.view.window_to_text((event["x"], event["y"]))
        if not 'string' in self.view.scope_name(pt):
            return

        line = self.view.line(pt)

        line.a = max(line.a, pt - 1024)
        line.b = min(line.b, pt + 1024)

        text = self.view.substr(line)

        it = FIND_PATH.finditer(text)

        for match in it:
            if match.start() <= (pt - line.a) and match.end() >= (pt - line.a):
                path = text[match.start():match.end()]
                if for_context_menu:
                    return os.path.dirname(
                        self.view.file_name()), ph.computer_friendly(path)
                return os.path.join(os.path.dirname(self.view.file_name()),
                                    ph.computer_friendly(path))
        return None
Пример #2
0
    def __get_completion_for(self, abspath, with_files, pick_first,
                             case_sensitive, can_add_slash):
        """Return a string and list: the prefix, and the list
        of available completion in the right order"""
        def sort_in_two_list(items, key):
            first, second = [], []
            for item in items:
                first_list, item = key(item)
                if first_list:
                    first.append(item)
                else:
                    second.append(item)
            return first, second

        abspath = ph.computer_friendly(abspath)

        if abspath.endswith(os.path.sep):
            prefix = ''
            load_items_from = abspath
        else:
            load_items_from = os.path.dirname(abspath)
            prefix = os.path.basename(abspath)

        items = sorted(os.listdir(load_items_from))
        items_with_right_prefix = []

        if not case_sensitive:
            prefix = prefix.lower()

        for i, item in enumerate(items):
            if not case_sensitive:
                item = item.lower()
            if item.startswith(prefix):
                # I add items[i] because it's case is never changed
                items_with_right_prefix.append([
                    items[i],
                    os.path.isdir(os.path.join(load_items_from, items[i]))
                ])

        folders, files = sort_in_two_list(items_with_right_prefix,
                                          lambda item: [item[1], item[0]])
        if can_add_slash:
            folders = [folder + '/' for folder in folders]
        if with_files:
            if pick_first == 'folders':
                return prefix, folders + files
            elif pick_first == 'files':
                return prefix, files + folders
            elif pick_first == 'alphabetic':
                return prefix, sorted(files + folders)
            else:
                sublime.error_message(
                    'The keyword {0!r} to define the order of completions is not valid. See the default settings.'
                    .format(pick_first))
                raise ValueError(
                    'The keyword {0!r} to define the order of completions is not valid. See the default settings.'
                    .format(pick_first))
        else:
            return prefix, folders
Пример #3
0
 def input_on_done(self, input_path):
     if self.log_in_status_bar:
         set_status(self.view, self.STATUS_KEY, '')
     # use the one returned by the on change function
     input_path = self.input_path
     computer_path = ph.computer_friendly(
         os.path.join(self.create_from, input_path))
     # open browser
     if self.enable_browser and os.path.isdir(computer_path):
         self.browser.path = computer_path
         return self.browsing_on_done()
     else:
         self.user_on_done(computer_path, input_path)
Пример #4
0
    def __init__(self, caption, initial_text, on_done, on_change, on_cancel,
                 create_from, with_files, pick_first, case_sensitive,
                 log_in_status_bar, log_template, enable_browser):

        self.user_on_done = on_done
        self.user_on_change = on_change
        self.user_on_cancel = on_cancel
        self.caption = caption
        self.initial_text = initial_text
        self.log_template = log_template
        self.enable_browser = enable_browser

        self.create_from = create_from
        if self.create_from:
            self.create_from = ph.computer_friendly(self.create_from)
            if not os.path.isdir(self.create_from):
                if os.path.exists(self.create_from):
                    sublime.error_message(
                        "This path exists, but doesn't seem to be a directory. Please report this (see link in the console)"
                    )
                    raise ValueError(
                        "This path exists, but doesn't seem to be a directory. Here's the path {0}. Please report this bug here: https://github.com/math2001/FileManager/issues"
                    )
                sublime.error_message(
                    'The path `create_from` should exists. {0!r} does not exists.'
                    .format(self.create_from))
                raise ValueError(
                    'The path create from does not exists ({0!r})'.format(
                        self.create_from))

        self.browser = StdClass('Browser')
        self.browser.path = self.create_from
        self.browser.items = []

        self.with_files = with_files
        self.pick_first = pick_first
        self.case_sensitive = case_sensitive

        self.path_to_create_choosed_from_browsing = False

        self.window = sublime.active_window()
        self.view = self.window.active_view()

        self.log_in_status_bar = log_in_status_bar

        self.create_input()
Пример #5
0
    def input_on_change(self, input_path):
        self.input_path = ph.user_friendly(input_path)
        # get changed inputs and create_from from the on_change user function
        if self.user_on_change:
            new_values = self.user_on_change(
                self.input_path, self.path_to_create_choosed_from_browsing)
            if new_values is not None:
                create_from, self.input_path = new_values
                self.create_from = ph.computer_friendly(create_from)

        def reset_settings():
            self.input.settings.erase('completions')
            self.input.settings.erase('completions_index')

        def replace_with_completion(completions, index, prefix=None):
            # replace the previous completion
            # with the new one (completions[index+1])
            region = [self.input.view.sel()[0].begin()]
            # -1 because of the \t
            region.append(
                region[0] -
                len(prefix if prefix is not None else completions[index]) - 1)
            index += 1
            self.input.settings.set('completions_index', index)
            # Running fm_edit_replace will trigger this function
            # and because it is not going to find any \t
            # it's going to erase the settings
            # Adding this will prevent this behaviour
            self.input.settings.set('just_completed', True)
            self.input.view.run_command('fm_edit_replace', {
                'region': region,
                'text': completions[index]
            })
            self.prev_input_path = self.input.view.substr(
                sublime.Region(0, self.input.view.size()))

        # log in the status bar
        if self.log_in_status_bar:
            path = os.path.normpath(
                os.path.join(self.create_from,
                             ph.computer_friendly(self.input_path)))
            if self.input_path != '' and self.input_path[-1] == '/':
                path += os.path.sep
            if self.log_in_status_bar == 'user':
                path = ph.user_friendly(path)
            set_status(self.view, self.STATUS_KEY,
                       self.log_template.format(path))

        if not hasattr(self.input, 'settings'):
            return

        completions = self.input.settings.get('completions', None)
        index = self.input.settings.get('completions_index', None)

        if completions is not None and index is not None:
            # check if the user typed something after the completion
            text = input_path
            if text[-1] == '\t':
                text = text[:-1]
            if not text.endswith(tuple(completions)):
                return reset_settings()
            if '\t' in input_path:

                # there is still some completions available
                if len(completions) - 1 > index:
                    return replace_with_completion(completions, index)
        if '\t' in input_path:
            before, after = self.input_path.split('\t')
            prefix, completions = self.__get_completion_for(
                abspath=ph.computer_friendly(
                    os.path.join(self.create_from, before)),
                with_files=self.with_files,
                pick_first=self.pick_first,
                case_sensitive=self.case_sensitive,
                can_add_slash=after == '' or after[0] != '/')
            if not completions:
                return

            self.input.settings.set('completions', completions)
            self.input.settings.set('completions_index', -1)

            replace_with_completion(completions, -1, prefix)