示例#1
0
class WebJumpPrompt(Prompt):
    label = "url/webjump:"
    complete_options = {"match": Prompt.SimpleMatch}
    history = PromptHistory()
    force_new_buffer = False
    keymap = WEBJUMP_PROMPT_KEYMAP

    def completer_model(self):
        data = []
        for name, w in WEBJUMPS.items():
            data.append((name, w.doc))

        for url, name in self.bookmarks:
            data.append((name, url))

        return PromptTableModel(data)

    def enable(self, minibuffer):
        self.bookmarks = app().bookmarks().list()
        Prompt.enable(self, minibuffer)
        self.new_buffer = PromptNewBuffer(self.ctx, self.force_new_buffer)
        self.new_buffer.enable(minibuffer)
        minibuffer.input().textEdited.connect(self._text_edited)
        minibuffer.input().installEventFilter(self)
        self._wc_model = QStringListModel()
        self._wb_model = minibuffer.input().completer_model()
        self._active_webjump = None
        self._completer = None
        self._popup_sel_model = None

    def eventFilter(self, obj, event):
        # call _text_edited on backspace release, as this is not reported by
        # the textEdited slot.
        if event.type() == QEvent.KeyRelease:
            if event.key() == Qt.Key_Backspace:
                self._text_edited(self.minibuffer.input().text())
        return Prompt.eventFilter(self, obj, event)

    def _set_active_webjump(self, wj):
        if self._active_webjump == wj:
            return

        if self._active_webjump:
            if self._completer:
                self._completer.completed.disconnect(self._got_completions)
                self._completer.abort()
                self._completer.deleteLater()
                self._completer = None

        m_input = self.minibuffer.input()
        if wj:
            self._completer = wj.complete_fn()
            self._completer.completed.connect(self._got_completions)
            # set matching strategy
            m_input.set_match(None)
            model = self._wc_model
        else:
            m_input.set_match(Prompt.SimpleMatch)
            model = self._wb_model

        self._active_webjump = wj
        if m_input.completer_model() != model:
            m_input.popup().hide()
            m_input.set_completer_model(model)
            if self._popup_sel_model:
                self._popup_sel_model.selectionChanged.disconnect(
                    self._popup_selection_changed)
                self._popup_sel_model = None
            if wj:
                m_input.popup().selectionModel()\
                               .selectionChanged.connect(
                                   self._popup_selection_changed
                               )

    def _popup_selection_changed(self, _sel, _desel):
        # try to abort any completion if the user select something in
        # the popup
        if self._completer:
            self._completer.abort()

    def _text_edited(self, text):
        # search for a matching webjump
        first_word = text.split(" ")[0].split("://")[0]
        if first_word in [w for w in WEBJUMPS if len(w) < len(text)]:
            self._set_active_webjump(WEBJUMPS[first_word])
            self.start_completion(self._active_webjump)
        else:
            # didn't find a webjump, go back to matching
            # webjump/bookmark/history
            self._set_active_webjump(None)

    def start_completion(self, webjump):
        text = self.minibuffer.input().text()
        prefix = webjump.name + ("://" if webjump.protocol else " ")
        self._completer.abort()
        self._completer.complete(text[len(prefix):])

    @Slot(list)
    def _got_completions(self, data):
        if self._active_webjump:
            self._wc_model.setStringList(data)
            text = self.minibuffer.input().text()
            prefix = self._active_webjump.name + \
                ("://" if self._active_webjump.protocol else " ")
            self.minibuffer.input().show_completions(text[len(prefix):])

    def close(self):
        Prompt.close(self)
        self.minibuffer.input().removeEventFilter(self)
        # not sure if those are required;
        self._wb_model.deleteLater()
        self._wc_model.deleteLater()

    def get_buffer(self):
        return self.new_buffer.get_buffer()

    def _on_completion_activated(self, index):
        super()._on_completion_activated(index)

        chosen_text = self.minibuffer.input().text()
        # if there is already an active webjump,
        if self._active_webjump:
            # add the selected completion after it
            if self._active_webjump.protocol:
                self.minibuffer.input().setText(self._active_webjump.name +
                                                "://" + chosen_text)
            else:
                self.minibuffer.input().setText(self._active_webjump.name +
                                                " " + chosen_text)

        # if we just chose a webjump
        # and not WEBJUMPS[chosen_text].protocol:
        elif chosen_text in WEBJUMPS:
            # add a space after the selection
            self.minibuffer.input().setText(chosen_text + (
                " " if not WEBJUMPS[chosen_text].protocol else "://"))
示例#2
0
class WebJumpPrompt(Prompt):
    label = "url/webjump:"
    complete_options = {"match": Prompt.SimpleMatch}
    history = PromptHistory()
    keymap = WEBJUMP_KEYMAP
    default_input = "alternate"

    def completer_model(self):
        data = []
        for name, w in WEBJUMPS.items():
            data.append((name, w.doc))

        for url, name in self.bookmarks:
            data.append((name, url))

        return PromptTableModel(data)

    def enable(self, minibuffer):
        self.bookmarks = app().bookmarks().list()
        Prompt.enable(self, minibuffer)
        minibuffer.input().textEdited.connect(self._text_edited)
        minibuffer.input().installEventFilter(self)
        self._wc_model = QStringListModel()
        self._wb_model = minibuffer.input().completer_model()
        self._active_webjump = None
        self._completer = None
        self._popup_sel_model = None
        input = minibuffer.input()
        if self.default_input in ("current_url", "alternate"):
            url = current_buffer().url().toString()
            input.setText(url)
            input.setSelection(0, len(url))
            if self.default_input == "alternate":
                input.deselect()
        elif self.default_input == "default_webjump":
            wj = WEBJUMPS.get(webjump_default.value)
            if wj:
                input.setText(wj.name + ("://" if wj.protocol else " "))

    def eventFilter(self, obj, event):
        # call _text_edited on backspace release, as this is not reported by
        # the textEdited slot.
        if event.type() == QEvent.KeyRelease:
            if event.key() == Qt.Key_Backspace:
                self._text_edited(self.minibuffer.input().text())
        return Prompt.eventFilter(self, obj, event)

    def _set_active_webjump(self, wj):
        if self._active_webjump == wj:
            return

        if self._active_webjump:
            if self._completer:
                self._completer.completed.disconnect(self._got_completions)
                self._completer.abort()
                self._completer.deleteLater()
                self._completer = None

        m_input = self.minibuffer.input()
        if wj:
            self._completer = wj.complete_fn()
            self._completer.completed.connect(self._got_completions)
            # set matching strategy
            m_input.set_match(None)
            model = self._wc_model
        else:
            m_input.set_match(Prompt.SimpleMatch)
            model = self._wb_model

        self._active_webjump = wj
        if m_input.completer_model() != model:
            m_input.popup().hide()
            m_input.set_completer_model(model)
            if self._popup_sel_model:
                self._popup_sel_model.selectionChanged.disconnect(
                    self._popup_selection_changed)
                self._popup_sel_model = None
            if wj:
                m_input.popup().selectionModel()\
                               .selectionChanged.connect(
                                   self._popup_selection_changed
                )

    def _popup_selection_changed(self, _sel, _desel):
        # try to abort any completion if the user select something in
        # the popup
        if self._completer:
            self._completer.abort()

    def _text_edited(self, text):
        # search for a matching webjump
        first_word = text.split(" ")[0].split("://")[0]
        if first_word in [w for w in WEBJUMPS if len(w) < len(text)]:
            self._set_active_webjump(WEBJUMPS[first_word])
            self.start_completion(self._active_webjump)
        else:
            # didn't find a webjump, go back to matching
            # webjump/bookmark/history
            self._set_active_webjump(None)

    def start_completion(self, webjump):
        text = self.minibuffer.input().text()
        prefix = webjump.name + ("://" if webjump.protocol else " ")
        self._completer.abort()
        self._completer.complete(text[len(prefix):])

    @Slot(list)
    def _got_completions(self, data):
        if self._active_webjump:
            self._wc_model.setStringList(data)
            text = self.minibuffer.input().text()
            prefix = self._active_webjump.name + \
                ("://" if self._active_webjump.protocol else " ")
            self.minibuffer.input().show_completions(text[len(prefix):])

    def close(self):
        Prompt.close(self)
        self.minibuffer.input().removeEventFilter(self)
        # not sure if those are required;
        self._wb_model.deleteLater()
        self._wc_model.deleteLater()

    def _on_completion_activated(self, index):
        super()._on_completion_activated(index)

        chosen_text = self.minibuffer.input().text()
        # if there is already an active webjump,
        if self._active_webjump:
            # add the selected completion after it
            if self._active_webjump.protocol:
                self.minibuffer.input().setText(self._active_webjump.name +
                                                "://" + chosen_text)
            else:
                self.minibuffer.input().setText(self._active_webjump.name +
                                                " " + chosen_text)

        # if we just chose a webjump
        # and not WEBJUMPS[chosen_text].protocol:
        elif chosen_text in WEBJUMPS:
            # add a space after the selection
            self.minibuffer.input().setText(chosen_text + (
                " " if not WEBJUMPS[chosen_text].protocol else "://"))

    def value(self):
        value = super().value()
        if value is None:
            return

        # split webjumps and protocols between command and argument
        if re.match(r"^\S+://.*", value):
            args = value.split("://", 1)
        else:
            args = value.split(" ", 1)
        command = args[0]

        # Look for webjumps
        webjump = None
        if command in WEBJUMPS:
            webjump = WEBJUMPS[command]
        else:
            # Look for a incomplete webjump, accepting a candidate
            # if there is a single option
            candidates = [wj for wj in WEBJUMPS if wj.startswith(command)]
            if len(candidates) == 1:
                webjump = WEBJUMPS[candidates[0]]

        if webjump:
            if not webjump.allow_args:
                # send the url as is
                return webjump.url
            elif len(args) < 2:
                # send the url without a search string
                return webjump.url.replace("%s", "")

            else:
                # format the url as entered
                if webjump.protocol:
                    return value
                else:
                    return webjump.url.replace(
                        "%s", str(QUrl.toPercentEncoding(args[1]), "utf-8"))

        # Look for a bookmark
        bookmarks = {name: url for url, name in self.bookmarks}
        if value in bookmarks:
            return bookmarks[value]

        # Look for a incomplete bookmarks, accepting a candidate
        # if there is a single option
        candidates = [bm for bm in bookmarks if bm.startswith(command)]
        if len(candidates) == 1:
            return bookmarks[candidates[0]]

        # No webjump, no bookmark, look for a url
        if "://" not in value:
            url = QUrl.fromUserInput(value)
            if url.isValid():
                # default scheme is https for us
                if url.scheme() == "http":
                    url.setScheme("https")
                return url
        return value
示例#3
0
class WebJumpPrompt(Prompt):
    label = "url/webjump:"
    complete_options = {
        "autocomplete": True,
    }
    history = PromptHistory()

    ask_completions = Signal(object, str, str)
    force_new_buffer = False

    def completer_model(self):
        data = []
        for name, w in WEBJUMPS.items():
            if w.allow_args:
                name = name
            data.append((name, w.doc))
        return PromptTableModel(data)

    def enable(self, minibuffer):
        Prompt.enable(self, minibuffer)
        self.new_buffer = PromptNewBuffer(self.force_new_buffer)
        self.new_buffer.enable(minibuffer)
        minibuffer.input().textEdited.connect(self._text_edited)
        self._wc_model = QStringListModel()
        self._wb_model = minibuffer.input().completer_model()
        self._cthread = QThread(app())
        self._creceiver = CompletionReceiver()
        self._creceiver.moveToThread(self._cthread)
        self._completion_timer = 0
        self._active_webjump = None
        self._cthread.finished.connect(self._cthread.deleteLater)
        self.ask_completions.connect(self._creceiver.get_completions)
        self._creceiver.got_completions.connect(self._got_completions)
        self._cthread.start()

    def _text_edited(self, text):
        model = self._wb_model
        for name, w in WEBJUMPS.items():
            if w.allow_args and w.complete_fn:
                name = name
                if text.startswith(name):
                    model = self._wc_model
                    self._active_webjump = (w, name)
                    if self._completion_timer != 0:
                        self.killTimer(self._completion_timer)
                    self._completion_timer = self.startTimer(10)
                    break
        if self.minibuffer.input().completer_model() != model:
            self.minibuffer.input().popup().hide()
            self.minibuffer.input().set_completer_model(model)

    def timerEvent(self, _):
        text = self.minibuffer.input().text()
        w, name = self._active_webjump
        self.ask_completions.emit(w, name, text[len(name):])
        self.killTimer(self._completion_timer)
        self._completion_timer = 0

    @Slot(list)
    def _got_completions(self, data):
        self._wc_model.setStringList(data)
        self.minibuffer.input().show_completions()

    def close(self):
        Prompt.close(self)
        self._cthread.quit()
        # not sure if those are required;
        self._wb_model.deleteLater()
        self._wc_model.deleteLater()

    def get_buffer(self):
        return self.new_buffer.get_buffer()