Philipp Hörist pushed to branch master at gajim / gajim

Commits:

8 changed files:

Changes:

  • data/gajim-remote.1
    ... ... @@ -53,8 +53,6 @@ Sends custom XML
    53 53
     Changes the priority of account or accounts
    
    54 54
     .Ss show_next_pending_event
    
    55 55
     Pops up a window with the next pending event
    
    56
    -.Ss toggle_ipython
    
    57
    -Shows or hides the ipython window
    
    58 56
     .Ss toggle_roster_appearance
    
    59 57
     Shows or hides the roster window
    
    60 58
     .Sh EXAMPLES
    

  • gajim/common/app.py
    ... ... @@ -75,7 +75,6 @@
    75 75
     connections: dict[str, types.Client] = {}
    
    76 76
     avatar_cache: dict[str, dict[str, Any]] = {}
    
    77 77
     bob_cache: dict[str, bytes] = {}
    
    78
    -ipython_window = None
    
    79 78
     app = None  # type: GajimApplication
    
    80 79
     window = None  # type: MainWindow
    
    81 80
     commands = None  # type: ChatCommands
    

  • gajim/data/other/shortcuts.json
    ... ... @@ -5,7 +5,6 @@
    5 5
         "app.plugins": ["<Primary>E"],
    
    6 6
         "app.xml-console": ["<Primary><Shift>X"],
    
    7 7
         "app.file-transfer": ["<Primary>T"],
    
    8
    -    "app.ipython": ["<Primary><Alt>I"],
    
    9 8
         "app.start-chat::": ["<Primary>N"],
    
    10 9
         "app.create-groupchat::": ["<Primary>G"],
    
    11 10
         "win.change-nickname": ["<Primary><Shift>N"],
    

  • gajim/dev/__init__.py deleted

  • gajim/dev/ipython_view.py deleted
    1
    -#!/usr/bin/python
    
    2
    -
    
    3
    -# Copyright (C) 2008-2014 Yann Leboulanger <asterix AT lagaule.org>
    
    4
    -#
    
    5
    -# This file is part of Gajim.
    
    6
    -#
    
    7
    -# Gajim is free software; you can redistribute it and/or modify
    
    8
    -# it under the terms of the GNU General Public License as published
    
    9
    -# by the Free Software Foundation; version 3 only.
    
    10
    -#
    
    11
    -# Gajim is distributed in the hope that it will be useful,
    
    12
    -# but WITHOUT ANY WARRANTY; without even the implied warranty of
    
    13
    -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    
    14
    -# GNU General Public License for more details.
    
    15
    -#
    
    16
    -# You should have received a copy of the GNU General Public License
    
    17
    -# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    18
    -#
    
    19
    -# Copyright (c) 2007, IBM Corporation
    
    20
    -# All rights reserved.
    
    21
    -
    
    22
    -# Redistribution and use in source and binary forms, with or without
    
    23
    -# modification, are permitted provided that the following conditions are met:
    
    24
    -
    
    25
    -# * Redistributions of source code must retain the above copyright notice,
    
    26
    -#   this list of conditions and the following disclaimer.
    
    27
    -# * Redistributions in binary form must reproduce the above copyright notice,
    
    28
    -#   this list of conditions and the following disclaimer in the documentation
    
    29
    -#   and/or other materials provided with the distribution.
    
    30
    -# * Neither the name of the IBM Corporation nor the names of its contributors
    
    31
    -#   may be used to endorse or promote products derived from this software
    
    32
    -#   without specific prior written permission.
    
    33
    -
    
    34
    -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    
    35
    -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    
    36
    -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    
    37
    -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    
    38
    -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    
    39
    -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    
    40
    -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    
    41
    -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    
    42
    -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    
    43
    -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    
    44
    -# POSSIBILITY OF SUCH DAMAGE.
    
    45
    -
    
    46
    -'''
    
    47
    -Provides IPython console widget
    
    48
    -
    
    49
    -@author: Eitan Isaacson
    
    50
    -@organization: IBM Corporation
    
    51
    -@copyright: Copyright (c) 2007 IBM Corporation
    
    52
    -@license: BSD
    
    53
    -
    
    54
    -All rights reserved. This program and the accompanying materials are made
    
    55
    -available under the terms of the BSD which accompanies this distribution, and
    
    56
    -is available at U{http://www.opensource.org/licenses/bsd-license.php}
    
    57
    -'''
    
    58
    -
    
    59
    -import re
    
    60
    -import sys
    
    61
    -import os
    
    62
    -from io import StringIO
    
    63
    -from functools import reduce
    
    64
    -
    
    65
    -from gi.repository import Gtk
    
    66
    -from gi.repository import Gdk
    
    67
    -from gi.repository import GObject
    
    68
    -from gi.repository import GLib
    
    69
    -from gi.repository import Pango
    
    70
    -
    
    71
    -from pygments.token import Token
    
    72
    -
    
    73
    -import IPython
    
    74
    -from IPython.core.displayhook import DisplayHook
    
    75
    -from IPython.core.display_trap import DisplayTrap
    
    76
    -
    
    77
    -
    
    78
    -class MyPromptDisplayHook(DisplayHook):
    
    79
    -    def __init__(self, shell, view):
    
    80
    -        DisplayHook.__init__(self, shell=shell)
    
    81
    -        self.view = view
    
    82
    -
    
    83
    -    def write_output_prompt(self):
    
    84
    -        tokens = self.shell.prompts.out_prompt_tokens()
    
    85
    -        self.view.write('\n')
    
    86
    -        self.view.write(tokens)
    
    87
    -
    
    88
    -
    
    89
    -class IterableIPShell:
    
    90
    -    '''
    
    91
    -    Create an IPython instance. Does not start a blocking event loop,
    
    92
    -    instead allow single iterations. This allows embedding in GTK
    
    93
    -    without blockage
    
    94
    -
    
    95
    -    @ivar IP: IPython instance.
    
    96
    -    @type IP: IPython.iplib.InteractiveShell
    
    97
    -    @ivar iter_more: Indicates if the line executed was a complete command,
    
    98
    -    or we should wait for more.
    
    99
    -    @type iter_more: integer
    
    100
    -    @ivar history_level: The place in history where we currently are
    
    101
    -    when pressing up/down.
    
    102
    -    @type history_level: integer
    
    103
    -    @ivar complete_sep: Separation delimiters for completion function.
    
    104
    -    @type complete_sep: _sre.SRE_Pattern
    
    105
    -    '''
    
    106
    -    def __init__(self, argv=None, user_ns=None, user_global_ns=None, cin=None,
    
    107
    -                 cout=None, cerr=None, input_func=None):
    
    108
    -        '''
    
    109
    -        @param argv: Command line options for IPython
    
    110
    -        @type argv: list
    
    111
    -        @param user_ns: User namespace.
    
    112
    -        @type user_ns: dictionary
    
    113
    -        @param user_global_ns: User global namespace.
    
    114
    -        @type user_global_ns: dictionary.
    
    115
    -        @param cin: Console standard input.
    
    116
    -        @type cin: IO stream
    
    117
    -        @param cout: Console standard output.
    
    118
    -        @type cout: IO stream
    
    119
    -        @param cerr: Console standard error.
    
    120
    -        @type cerr: IO stream
    
    121
    -        @param input_func: Replacement for builtin raw_input()
    
    122
    -        @type input_func: function
    
    123
    -        '''
    
    124
    -        if argv is None:
    
    125
    -            argv = []
    
    126
    -
    
    127
    -        io = IPython.utils.io
    
    128
    -        if input_func:
    
    129
    -            IPython.terminal.interactiveshell.raw_input_original = input_func
    
    130
    -
    
    131
    -        # This is to get rid of the blockage that occurs during
    
    132
    -        # IPython.Shell.InteractiveShell.user_setup()
    
    133
    -        io.raw_input = lambda x: None
    
    134
    -
    
    135
    -        os.environ['TERM'] = 'dumb'
    
    136
    -        excepthook = sys.excepthook
    
    137
    -
    
    138
    -        from traitlets.config.loader import Config
    
    139
    -
    
    140
    -        cfg = Config()
    
    141
    -        cfg.InteractiveShell.colors = 'Linux'
    
    142
    -
    
    143
    -        # InteractiveShell's __init__ gets a reference of stdout and stderr
    
    144
    -        # so we save the standard here to revert it after init
    
    145
    -        old_stdout, old_stderr = sys.stdout, sys.stderr
    
    146
    -        sys.stdout, sys.stderr = cout, cerr
    
    147
    -
    
    148
    -        # InteractiveShell inherits from SingletonConfigurable so use instance()
    
    149
    -        self.IP = IPython.terminal.embed.InteractiveShellEmbed.instance(
    
    150
    -            config=cfg, user_ns=user_ns, user_module=user_global_ns)
    
    151
    -
    
    152
    -        # Set back stdout and stderr to what it was before
    
    153
    -        sys.stdout, sys.stderr = old_stdout, old_stderr
    
    154
    -
    
    155
    -        self.IP.system = lambda cmd: self.shell(self.IP.var_expand(cmd),
    
    156
    -                                                header='IPython system call: ',
    
    157
    -                                                local_ns=user_ns)
    
    158
    -
    
    159
    -        self.IP.raw_input = input_func
    
    160
    -        sys.excepthook = excepthook
    
    161
    -        self.iter_more = 0
    
    162
    -        self.history_level = 0
    
    163
    -        self.complete_sep = re.compile(r'[\s\{\}\[\]\(\)]')
    
    164
    -        self.updateNamespace({'exit': lambda: None})
    
    165
    -        self.updateNamespace({'quit': lambda: None})
    
    166
    -
    
    167
    -        # Workaround for updating namespace with sys.modules
    
    168
    -        #
    
    169
    -        self.__update_namespace()
    
    170
    -        self.lines = []
    
    171
    -
    
    172
    -    def __update_namespace(self):
    
    173
    -        '''
    
    174
    -        Update self.IP namespace for autocompletion with sys.modules
    
    175
    -        '''
    
    176
    -        for k, v in sys.modules.items():
    
    177
    -            if '.' not in k:
    
    178
    -                self.IP.user_ns.update({k: v})
    
    179
    -
    
    180
    -    def execute(self):
    
    181
    -        '''
    
    182
    -        Execute the current line provided by the shell object
    
    183
    -        '''
    
    184
    -        self.history_level = 0
    
    185
    -        orig_stdout = sys.stdout
    
    186
    -        sys.stdout = IPython.utils.io.stdout
    
    187
    -
    
    188
    -        orig_stdin = sys.stdin
    
    189
    -        sys.stdin = IPython.utils.io.stdin
    
    190
    -        self.prompt = self.generatePrompt(self.iter_more)
    
    191
    -
    
    192
    -        self.IP.hooks.pre_prompt_hook()
    
    193
    -        if self.iter_more:
    
    194
    -            try:
    
    195
    -                self.prompt = self.generatePrompt(True)
    
    196
    -            except Exception:
    
    197
    -                self.IP.showtraceback()
    
    198
    -            if self.IP.autoindent:
    
    199
    -                self.IP.rl_do_indent = True
    
    200
    -
    
    201
    -        try:
    
    202
    -            self.IP.raw_input(self.prompt)
    
    203
    -        except KeyboardInterrupt:
    
    204
    -            self.IP.write('\nKeyboardInterrupt\n')
    
    205
    -            self.IP.input_splitter.reset()
    
    206
    -        except Exception:
    
    207
    -            self.IP.showtraceback()
    
    208
    -        else:
    
    209
    -            self.lines.append(self.IP.raw_input(self.prompt))
    
    210
    -            self.iter_more = self.IP.check_complete(
    
    211
    -                '\n'.join(self.lines))[0] == 'incomplete'
    
    212
    -
    
    213
    -            self.prompt = self.generatePrompt(self.iter_more)
    
    214
    -            if not self.iter_more:
    
    215
    -                source_raw = '\n'.join(self.lines)
    
    216
    -                self.lines = []
    
    217
    -
    
    218
    -                self.IP.run_cell(source_raw, store_history=True)
    
    219
    -                self.IP.rl_do_indent = False
    
    220
    -            else:
    
    221
    -                # TODO: Auto-indent
    
    222
    -                #
    
    223
    -                self.IP.rl_do_indent = True
    
    224
    -
    
    225
    -        sys.stdout = orig_stdout
    
    226
    -        sys.stdin = orig_stdin
    
    227
    -
    
    228
    -    def generatePrompt(self, is_continuation):
    
    229
    -        '''
    
    230
    -        Generate prompt depending on is_continuation value
    
    231
    -
    
    232
    -        @param is_continuation
    
    233
    -        @type is_continuation: boolean
    
    234
    -
    
    235
    -        @return: The prompt string representation
    
    236
    -        @rtype: string
    
    237
    -
    
    238
    -        '''
    
    239
    -        # TODO: Update to IPython 5.x and later
    
    240
    -        prompt = 'In [%d]: ' % self.IP.execution_count
    
    241
    -
    
    242
    -        return prompt
    
    243
    -
    
    244
    -    def historyBack(self):
    
    245
    -        '''
    
    246
    -        Provide one history command back
    
    247
    -
    
    248
    -        @return: The command string.
    
    249
    -        @rtype: string
    
    250
    -        '''
    
    251
    -        self.history_level -= 1
    
    252
    -        return self._getHistory()
    
    253
    -
    
    254
    -    def historyForward(self):
    
    255
    -        '''
    
    256
    -        Provide one history command forward
    
    257
    -
    
    258
    -        @return: The command string.
    
    259
    -        @rtype: string
    
    260
    -        '''
    
    261
    -        self.history_level += 1
    
    262
    -        return self._getHistory()
    
    263
    -
    
    264
    -    def _getHistory(self):
    
    265
    -        '''
    
    266
    -        Get the command string of the current history level
    
    267
    -
    
    268
    -        @return: Historic command string.
    
    269
    -        @rtype: string
    
    270
    -        '''
    
    271
    -        try:
    
    272
    -            rv = self.IP.user_ns['In'][self.history_level].strip('\n')
    
    273
    -        except IndexError:
    
    274
    -            self.history_level = 0
    
    275
    -            rv = ''
    
    276
    -        return rv
    
    277
    -
    
    278
    -    def updateNamespace(self, ns_dict):
    
    279
    -        '''
    
    280
    -        Add the current dictionary to the shell namespace
    
    281
    -
    
    282
    -        @param ns_dict: A dictionary of symbol-values.
    
    283
    -        @type ns_dict: dictionary
    
    284
    -        '''
    
    285
    -        self.IP.user_ns.update(ns_dict)
    
    286
    -
    
    287
    -    def complete(self, line):
    
    288
    -        '''
    
    289
    -        Returns an auto completed line and/or possibilities for completion
    
    290
    -
    
    291
    -        @param line: Given line so far.
    
    292
    -        @type line: string
    
    293
    -
    
    294
    -        @return: Line completed as for as possible,
    
    295
    -        and possible further completions.
    
    296
    -        @rtype: tuple
    
    297
    -        '''
    
    298
    -        split_line = self.complete_sep.split(line)
    
    299
    -        if split_line[-1]:
    
    300
    -            possibilities = self.IP.complete(split_line[-1])
    
    301
    -        else:
    
    302
    -            completed = line
    
    303
    -            possibilities = ['', []]
    
    304
    -        if possibilities:
    
    305
    -            def _commonPrefix(str1, str2):
    
    306
    -                '''
    
    307
    -                Reduction function. returns common prefix of two given strings.
    
    308
    -
    
    309
    -                @param str1: First string.
    
    310
    -                @type str1: string
    
    311
    -                @param str2: Second string
    
    312
    -                @type str2: string
    
    313
    -
    
    314
    -                @return: Common prefix to both strings.
    
    315
    -                @rtype: string
    
    316
    -                '''
    
    317
    -                for i in range(len(str1)):
    
    318
    -                    if not str2.startswith(str1[:i + 1]):
    
    319
    -                        return str1[:i]
    
    320
    -                return str1
    
    321
    -
    
    322
    -            if possibilities[1]:
    
    323
    -                common_prefix = \
    
    324
    -                    reduce(_commonPrefix, possibilities[1]) or line[-1]
    
    325
    -                completed = line[:-len(split_line[-1])] + common_prefix
    
    326
    -            else:
    
    327
    -                completed = line
    
    328
    -        else:
    
    329
    -            completed = line
    
    330
    -        return completed, possibilities[1]
    
    331
    -
    
    332
    -
    
    333
    -class ConsoleView(Gtk.TextView):
    
    334
    -    '''
    
    335
    -    Specialized text view for console-like workflow
    
    336
    -
    
    337
    -    @cvar ANSI_COLORS: Mapping of terminal colors to X11 names.
    
    338
    -    @type ANSI_COLORS: dictionary
    
    339
    -
    
    340
    -    @ivar text_buffer: Widget's text buffer.
    
    341
    -    @type text_buffer: Gtk.TextBuffer
    
    342
    -    @ivar color_pat: Regex of terminal color pattern
    
    343
    -    @type color_pat: _sre.SRE_Pattern
    
    344
    -    @ivar mark: Scroll mark for automatic scrolling on input.
    
    345
    -    @type mark: Gtk.TextMark
    
    346
    -    @ivar line_start: Start of command line mark.
    
    347
    -    @type line_start: Gtk.TextMark
    
    348
    -    '''
    
    349
    -
    
    350
    -    ANSI_COLORS = {'0;30': 'Black', '0;31': 'Red',
    
    351
    -                   '0;32': 'Green', '0;33': 'Brown',
    
    352
    -                   '0;34': 'Blue', '0;35': 'Purple',
    
    353
    -                   '0;36': 'Cyan', '0;37': 'LightGray',
    
    354
    -                   '1;30': 'DarkGray', '1;31': 'DarkRed',
    
    355
    -                   '1;32': 'SeaGreen', '1;33': 'Yellow',
    
    356
    -                   '1;34': 'LightBlue', '1;35': 'MediumPurple',
    
    357
    -                   '1;36': 'LightCyan', '1;37': 'White'}
    
    358
    -
    
    359
    -    def __init__(self):
    
    360
    -        '''
    
    361
    -        Initialize console view
    
    362
    -        '''
    
    363
    -        GObject.GObject.__init__(self)
    
    364
    -        self.override_font(Pango.FontDescription('Mono'))
    
    365
    -        self.set_cursor_visible(True)
    
    366
    -        self.text_buffer = self.get_buffer()
    
    367
    -        self.mark = self.text_buffer.create_mark(
    
    368
    -            'scroll_mark',
    
    369
    -            self.text_buffer.get_end_iter(),
    
    370
    -            False)
    
    371
    -        for code, color in self.ANSI_COLORS.items():
    
    372
    -            self.text_buffer.create_tag(code,
    
    373
    -                                        foreground=color,
    
    374
    -                                        weight=700)
    
    375
    -        self.text_buffer.create_tag('0')
    
    376
    -        self.text_buffer.create_tag('notouch', editable=False)
    
    377
    -        self.color_pat = re.compile(r'\x01?\x1b\[(.*?)m\x02?')
    
    378
    -
    
    379
    -        self.style_dict = {
    
    380
    -            Token.Prompt: '0;32',
    
    381
    -            Token.PromptNum: '1;32',
    
    382
    -            Token.OutPrompt: '0;31',
    
    383
    -            Token.OutPromptNum: '1;31',
    
    384
    -        }
    
    385
    -
    
    386
    -        self.line_start = \
    
    387
    -            self.text_buffer.create_mark('line_start',
    
    388
    -                                         self.text_buffer.get_end_iter(),
    
    389
    -                                         True)
    
    390
    -        self.connect('key-press-event', self.onKeyPress)
    
    391
    -
    
    392
    -    def write(self, text, editable=False):
    
    393
    -        if isinstance(text, str):
    
    394
    -            GLib.idle_add(self._write, text, editable)
    
    395
    -        else:
    
    396
    -            GLib.idle_add(self._write5, text, editable)
    
    397
    -
    
    398
    -    def _write5(self, text, editable=False):
    
    399
    -        '''
    
    400
    -        Write given text to buffer
    
    401
    -
    
    402
    -        @param text: Text to append.
    
    403
    -        @type text: list of (token: string)
    
    404
    -        @param editable: If true, added text is editable.
    
    405
    -        @type editable: boolean
    
    406
    -        '''
    
    407
    -        start_mark = self.text_buffer.create_mark(
    
    408
    -            None, self.text_buffer.get_end_iter(), True)
    
    409
    -
    
    410
    -        for token, segment in text:
    
    411
    -            tag = self.style_dict[token]
    
    412
    -            self.text_buffer.insert_with_tags_by_name(
    
    413
    -                self.text_buffer.get_end_iter(), segment, tag)
    
    414
    -        if not editable:
    
    415
    -            self.text_buffer.apply_tag_by_name(
    
    416
    -                'notouch',
    
    417
    -                self.text_buffer.get_iter_at_mark(start_mark),
    
    418
    -                self.text_buffer.get_end_iter())
    
    419
    -        self.text_buffer.delete_mark(start_mark)
    
    420
    -        self.scroll_mark_onscreen(self.mark)
    
    421
    -
    
    422
    -    def _write(self, text, editable=False):
    
    423
    -        '''
    
    424
    -        Write given text to buffer
    
    425
    -
    
    426
    -        @param text: Text to append.
    
    427
    -        @type text: string
    
    428
    -        @param editable: If true, added text is editable.
    
    429
    -        @type editable: boolean
    
    430
    -        '''
    
    431
    -        if isinstance(text, list):
    
    432
    -            self._write5(text, editable)
    
    433
    -            return
    
    434
    -        segments = self.color_pat.split(text)
    
    435
    -        segment = segments.pop(0)
    
    436
    -        start_mark = self.text_buffer.create_mark(
    
    437
    -            None, self.text_buffer.get_end_iter(), True)
    
    438
    -        self.text_buffer.insert(self.text_buffer.get_end_iter(), segment)
    
    439
    -
    
    440
    -        if segments:
    
    441
    -            ansi_tags = self.color_pat.findall(text)
    
    442
    -            for tag in ansi_tags:
    
    443
    -                i = segments.index(tag)
    
    444
    -                self.text_buffer.insert_with_tags_by_name(
    
    445
    -                    self.text_buffer.get_end_iter(), segments[i + 1], str(tag))
    
    446
    -                segments.pop(i)
    
    447
    -        if not editable:
    
    448
    -            self.text_buffer.apply_tag_by_name(
    
    449
    -                'notouch',
    
    450
    -                self.text_buffer.get_iter_at_mark(start_mark),
    
    451
    -                self.text_buffer.get_end_iter())
    
    452
    -
    
    453
    -        self.text_buffer.delete_mark(start_mark)
    
    454
    -        self.scroll_mark_onscreen(self.mark)
    
    455
    -
    
    456
    -    def showPrompt(self, prompt):
    
    457
    -        GLib.idle_add(self._showPrompt, prompt)
    
    458
    -
    
    459
    -    def _showPrompt(self, prompt):
    
    460
    -        '''
    
    461
    -        Print prompt at start of line
    
    462
    -
    
    463
    -        @param prompt: Prompt to print.
    
    464
    -        @type prompt: string
    
    465
    -        '''
    
    466
    -        self._write(prompt)
    
    467
    -        self.text_buffer.move_mark(self.line_start,
    
    468
    -                                   self.text_buffer.get_end_iter())
    
    469
    -
    
    470
    -    def changeLine(self, text):
    
    471
    -        GLib.idle_add(self._changeLine, text)
    
    472
    -
    
    473
    -    def _changeLine(self, text):
    
    474
    -        '''
    
    475
    -        Replace currently entered command line with given text
    
    476
    -
    
    477
    -        @param text: Text to use as replacement.
    
    478
    -        @type text: string
    
    479
    -        '''
    
    480
    -        iter_ = self.text_buffer.get_iter_at_mark(self.line_start)
    
    481
    -        iter_.forward_to_line_end()
    
    482
    -        self.text_buffer.delete(
    
    483
    -            self.text_buffer.get_iter_at_mark(self.line_start), iter_)
    
    484
    -        self._write(text, True)
    
    485
    -
    
    486
    -    def getCurrentLine(self):
    
    487
    -        '''
    
    488
    -        Get text in current command line
    
    489
    -
    
    490
    -        @return: Text of current command line.
    
    491
    -        @rtype: string
    
    492
    -        '''
    
    493
    -        rv = self.text_buffer.get_slice(
    
    494
    -            self.text_buffer.get_iter_at_mark(self.line_start),
    
    495
    -            self.text_buffer.get_end_iter(), False)
    
    496
    -        return rv
    
    497
    -
    
    498
    -    def showReturned(self, text):
    
    499
    -        GLib.idle_add(self._showReturned, text)
    
    500
    -
    
    501
    -    def _showReturned(self, text):
    
    502
    -        '''
    
    503
    -        Show returned text from last command and print new prompt
    
    504
    -
    
    505
    -        @param text: Text to show.
    
    506
    -        @type text: string
    
    507
    -        '''
    
    508
    -        iter_ = self.text_buffer.get_iter_at_mark(self.line_start)
    
    509
    -        iter_.forward_to_line_end()
    
    510
    -        self.text_buffer.apply_tag_by_name(
    
    511
    -            'notouch',
    
    512
    -            self.text_buffer.get_iter_at_mark(self.line_start),
    
    513
    -            iter_)
    
    514
    -        self._write('\n' + text)
    
    515
    -        if text:
    
    516
    -            self._write('\n')
    
    517
    -        self._showPrompt(self.prompt)
    
    518
    -        self.text_buffer.move_mark(
    
    519
    -            self.line_start, self.text_buffer.get_end_iter())
    
    520
    -        self.text_buffer.place_cursor(self.text_buffer.get_end_iter())
    
    521
    -
    
    522
    -        if self.IP.rl_do_indent:
    
    523
    -            indentation = self.IP.input_splitter.indent_spaces * ' '
    
    524
    -            self.text_buffer.insert_at_cursor(indentation)
    
    525
    -
    
    526
    -    def onKeyPress(self, _widget, event):
    
    527
    -        '''
    
    528
    -        Key press callback used for correcting behavior for console-like
    
    529
    -        interfaces. For example 'home' should go to prompt, not to beginning of
    
    530
    -        line
    
    531
    -
    
    532
    -        @param widget: Widget that key press occurred in.
    
    533
    -        @type widget: Gtk.Widget
    
    534
    -        @param event: Event object
    
    535
    -        @type event: Gdk.Event
    
    536
    -
    
    537
    -        @return: Return True if event should not trickle.
    
    538
    -        @rtype: boolean
    
    539
    -        '''
    
    540
    -        insert_mark = self.text_buffer.get_insert()
    
    541
    -        insert_iter = self.text_buffer.get_iter_at_mark(insert_mark)
    
    542
    -        selection_mark = self.text_buffer.get_selection_bound()
    
    543
    -        selection_iter = self.text_buffer.get_iter_at_mark(selection_mark)
    
    544
    -        start_iter = self.text_buffer.get_iter_at_mark(self.line_start)
    
    545
    -        if event.keyval == Gdk.KEY_Home:
    
    546
    -            if event.get_state() == 0:
    
    547
    -                self.text_buffer.place_cursor(start_iter)
    
    548
    -                return True
    
    549
    -            if event.get_state() == Gdk.ModifierType.SHIFT_MASK:
    
    550
    -                self.text_buffer.move_mark(insert_mark, start_iter)
    
    551
    -                return True
    
    552
    -
    
    553
    -        if event.keyval == Gdk.KEY_Left:
    
    554
    -            insert_iter.backward_cursor_position()
    
    555
    -            if not insert_iter.editable(True):
    
    556
    -                return True
    
    557
    -        elif not event.string:
    
    558
    -            pass
    
    559
    -        elif (start_iter.compare(insert_iter) <= 0 and
    
    560
    -                start_iter.compare(selection_iter) <= 0):
    
    561
    -            pass
    
    562
    -        elif (start_iter.compare(insert_iter) > 0 and
    
    563
    -                start_iter.compare(selection_iter) > 0):
    
    564
    -            self.text_buffer.place_cursor(start_iter)
    
    565
    -        elif insert_iter.compare(selection_iter) < 0:
    
    566
    -            self.text_buffer.move_mark(insert_mark, start_iter)
    
    567
    -        elif insert_iter.compare(selection_iter) > 0:
    
    568
    -            self.text_buffer.move_mark(selection_mark, start_iter)
    
    569
    -
    
    570
    -        return self.onKeyPressExtend(event)
    
    571
    -
    
    572
    -    def onKeyPressExtend(self, event):
    
    573
    -        '''
    
    574
    -        For some reason we can't extend onKeyPress directly (bug #500900)
    
    575
    -        '''
    
    576
    -
    
    577
    -
    
    578
    -class IPythonView(ConsoleView, IterableIPShell):
    
    579
    -    '''
    
    580
    -    Sub-class of both modified IPython shell and L{ConsoleView} this makes
    
    581
    -    a GTK IPython console.
    
    582
    -    '''
    
    583
    -    def __init__(self):
    
    584
    -        '''
    
    585
    -        Initialize. Redirect I/O to console
    
    586
    -        '''
    
    587
    -        ConsoleView.__init__(self)
    
    588
    -        self.cout = StringIO()
    
    589
    -        IterableIPShell.__init__(self, cout=self.cout, cerr=self.cout,
    
    590
    -                                 input_func=self.raw_input)
    
    591
    -
    
    592
    -        displayhook = MyPromptDisplayHook(shell=self.IP, view=self)
    
    593
    -        self.IP.displayhook = displayhook
    
    594
    -        self.IP.display_trap = DisplayTrap(hook=displayhook)
    
    595
    -
    
    596
    -        self.interrupt = False
    
    597
    -        self.execute()
    
    598
    -        self.prompt = self.generatePrompt(False)
    
    599
    -        self.cout.truncate(0)
    
    600
    -        self.showPrompt(self.prompt)
    
    601
    -
    
    602
    -    def prompt_for_code(self):
    
    603
    -        # IPython 5.0 calls prompt_for_code instead of raw_input
    
    604
    -        return self.raw_input(self)
    
    605
    -
    
    606
    -    def raw_input(self, _prompt=''):
    
    607
    -        '''
    
    608
    -        Custom raw_input() replacement. Gets current line from console buffer
    
    609
    -
    
    610
    -        @param prompt: Prompt to print. Here for compatibility as replacement.
    
    611
    -        @type prompt: string
    
    612
    -
    
    613
    -        @return: The current command line text.
    
    614
    -        @rtype: string
    
    615
    -        '''
    
    616
    -        if self.interrupt:
    
    617
    -            self.interrupt = False
    
    618
    -            raise KeyboardInterrupt
    
    619
    -        return self.getCurrentLine()
    
    620
    -
    
    621
    -    def onKeyPressExtend(self, event):
    
    622
    -        '''
    
    623
    -        Key press callback with plenty of shell goodness, like history,
    
    624
    -        autocompletions, etc
    
    625
    -
    
    626
    -        @param widget: Widget that key press occurred in.
    
    627
    -        @type widget: Gtk.Widget
    
    628
    -        @param event: Event object.
    
    629
    -        @type event: Gdk.Event
    
    630
    -
    
    631
    -        @return: True if event should not trickle.
    
    632
    -        @rtype: boolean
    
    633
    -        '''
    
    634
    -        if (event.get_state() & Gdk.ModifierType.CONTROL_MASK and
    
    635
    -                event.keyval == 99):
    
    636
    -            self.interrupt = True
    
    637
    -            self._processLine()
    
    638
    -            return True
    
    639
    -        if event.keyval == Gdk.KEY_Return:
    
    640
    -            self._processLine()
    
    641
    -            return True
    
    642
    -        if event.keyval == Gdk.KEY_Up:
    
    643
    -            self.changeLine(self.historyBack())
    
    644
    -            return True
    
    645
    -        if event.keyval == Gdk.KEY_Down:
    
    646
    -            self.changeLine(self.historyForward())
    
    647
    -            return True
    
    648
    -        if event.keyval == Gdk.KEY_Tab:
    
    649
    -            if not self.getCurrentLine().strip():
    
    650
    -                return False
    
    651
    -            completed, possibilities = self.complete(self.getCurrentLine())
    
    652
    -            if len(possibilities) > 1:
    
    653
    -                slice_ = self.getCurrentLine()
    
    654
    -                self.write('\n')
    
    655
    -                for symbol in possibilities:
    
    656
    -                    self.write(symbol + '\n')
    
    657
    -                self.showPrompt(self.prompt)
    
    658
    -            self.changeLine(completed or slice_)
    
    659
    -            return True
    
    660
    -
    
    661
    -    def _processLine(self):
    
    662
    -        '''
    
    663
    -        Process current command line
    
    664
    -        '''
    
    665
    -        self.history_pos = 0
    
    666
    -        self.execute()
    
    667
    -        rv = self.cout.getvalue()
    
    668
    -        if rv:
    
    669
    -            rv = rv.strip('\n')
    
    670
    -        self.showReturned(rv)
    
    671
    -        self.cout.truncate(0)
    
    672
    -        self.cout.seek(0)

  • gajim/gtk/application.py
    ... ... @@ -165,13 +165,6 @@ def __init__(self):
    165 165
                 GLib.OptionArg.NONE,
    
    166 166
                 _('Show all warnings'))
    
    167 167
     
    
    168
    -        self.add_main_option(
    
    169
    -            'ipython',
    
    170
    -            ord('i'),
    
    171
    -            GLib.OptionFlags.NONE,
    
    172
    -            GLib.OptionArg.NONE,
    
    173
    -            _('Open IPython shell'))
    
    174
    -
    
    175 168
             self.add_main_option(
    
    176 169
                 'gdebug',
    
    177 170
                 0,
    
    ... ... @@ -345,7 +338,6 @@ def _command_line(self,
    345 338
             options = command_line.get_options_dict()
    
    346 339
     
    
    347 340
             remote_commands = [
    
    348
    -            ('ipython', None),
    
    349 341
                 ('start-chat', GLib.Variant('s', '')),
    
    350 342
                 ('show', None)
    
    351 343
             ]
    
    ... ... @@ -417,7 +409,6 @@ def _connect_app_actions(self) -> None:
    417 409
                 ('join-support-chat', self._on_join_support_chat),
    
    418 410
                 ('about', self._on_about_action),
    
    419 411
                 ('faq', self._on_faq_action),
    
    420
    -            ('ipython', self._on_ipython_action),
    
    421 412
                 ('start-chat', self._on_new_chat_action),
    
    422 413
                 ('accounts', self._on_accounts_action),
    
    423 414
                 ('add-contact', self._on_add_contact_action),
    
    ... ... @@ -742,18 +733,6 @@ def _on_mark_as_read_action(self,
    742 733
     
    
    743 734
             app.window.mark_as_read(params.account, params.jid)
    
    744 735
     
    
    745
    -    @staticmethod
    
    746
    -    def _on_ipython_action(_action: Gio.SimpleAction,
    
    747
    -                           _param: Optional[GLib.Variant]) -> None:
    
    748
    -        '''
    
    749
    -        Show/hide the ipython window
    
    750
    -        '''
    
    751
    -        win = cast(Gtk.Window, app.ipython_window)
    
    752
    -        if win and win.is_visible():
    
    753
    -            win.present()
    
    754
    -        else:
    
    755
    -            app.interface.create_ipython_window()
    
    756
    -
    
    757 736
         @staticmethod
    
    758 737
         def _on_open_mail_action(_action: Gio.SimpleAction,
    
    759 738
                                  param: GLib.Variant) -> None:
    

  • gajim/gtk/const.py
    ... ... @@ -171,7 +171,6 @@ def __str__(self):
    171 171
         ('file-transfer', None),
    
    172 172
         ('forget-groupchat', 'a{sv}'),
    
    173 173
         ('groupchat-join', 'as'),
    
    174
    -    ('ipython', None),
    
    175 174
         ('join-support-chat', None),
    
    176 175
         ('manage-proxies', None),
    
    177 176
         ('open-link', 'as'),
    

  • gajim/gui_interface.py
    ... ... @@ -38,13 +38,11 @@
    38 38
     from typing import Optional
    
    39 39
     from typing import Union
    
    40 40
     
    
    41
    -import os
    
    42 41
     import sys
    
    43 42
     import time
    
    44 43
     import logging
    
    45 44
     from functools import partial
    
    46 45
     from threading import Thread
    
    47
    -from importlib.util import find_spec
    
    48 46
     
    
    49 47
     from gi.repository import Gtk
    
    50 48
     from gi.repository import GLib
    
    ... ... @@ -678,47 +676,6 @@ def save_avatar(self, data: bytes) -> Optional[str]:
    678 676
         def avatar_exists(self, filename: str) -> bool:
    
    679 677
             return app.app.avatar_storage.get_avatar_path(filename) is not None
    
    680 678
     
    
    681
    -    @staticmethod
    
    682
    -    def create_ipython_window() -> None:
    
    683
    -        # Check if IPython is installed
    
    684
    -        ipython = find_spec('IPython')
    
    685
    -        is_installed = ipython is not None
    
    686
    -        if not is_installed:
    
    687
    -            # Abort early to avoid tracebacks
    
    688
    -            print('IPython is not installed')
    
    689
    -            return
    
    690
    -        try:
    
    691
    -            from gajim.dev.ipython_view import IPythonView
    
    692
    -        except ImportError:
    
    693
    -            print('ipython_view not found')
    
    694
    -            return
    
    695
    -        from gi.repository import Pango
    
    696
    -
    
    697
    -        if os.name == 'nt':
    
    698
    -            font = 'Lucida Console 9'
    
    699
    -        else:
    
    700
    -            font = 'Luxi Mono 10'
    
    701
    -
    
    702
    -        window = Gtk.Window()
    
    703
    -        window.set_title(_('Gajim: IPython Console'))
    
    704
    -        window.set_size_request(750, 550)
    
    705
    -        window.set_resizable(True)
    
    706
    -        sw = Gtk.ScrolledWindow()
    
    707
    -        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
    
    708
    -        view = IPythonView()
    
    709
    -        view.override_font(Pango.FontDescription(font))
    
    710
    -        view.set_wrap_mode(Gtk.WrapMode.CHAR)
    
    711
    -        sw.add(view)
    
    712
    -        window.add(sw)
    
    713
    -        window.show_all()
    
    714
    -
    
    715
    -        def _on_delete(win, _event):
    
    716
    -            win.hide()
    
    717
    -            return True
    
    718
    -        window.connect('delete_event', _on_delete)
    
    719
    -        view.updateNamespace({'gajim': app})
    
    720
    -        app.ipython_window = window
    
    721
    -
    
    722 679
         def run(self, _application: Gtk.Application) -> None:
    
    723 680
             # Creating plugin manager
    
    724 681
             from gajim import plugins