This file is indexed.

/usr/share/games/kiki-the-nano-bot/py/edit.py is in kiki-the-nano-bot-data 1.0.2+dfsg1-6.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
if Controller.isDebugVersion(): print "[edit.py]"

execfile (kikipy_path + "buffer.py")
execfile (kikipy_path + "interpreter.py")
execfile (kikipy_path + "file.py")

# .................................................................................................................
#                                                   PythonConsole
# .................................................................................................................
 
class PythonConsole:
    """ kiki python console """

    # .............................................................................................................
    #                                                  INIT
    # .............................................................................................................
    def __init__(self, widget):
        """initializes the console with a widget"""
        self.widget      = widget
        self.view_rows   = widget.getTextRows()         # number of visible rows
        self.view_cols   = widget.getTextCols()         # number of visible columns
        self.offset      = 0                            # horizontal text offset
        self.line_offset = 0                            # vertical text offset
        self.inputMode   = ""                           # mode for user input requests
        self.buffer      = KikiPyInterpreter(self)      # currently displayed buffer
        self.buffers     = [self.buffer]                # list of loaded buffers
        self.viewBuffer(0)
    
    # .............................................................................................................
    def setSize (self, cols, rows):
        """callback from widget, if it's size changed""" 
        self.view_rows = rows
        self.view_cols = cols

    # .............................................................................................................
    def viewBuffer (self, index):
        """displays the file with index"""
        index = minmax(0, len(self.buffers)-1, index)
        self.buffer = self.buffers[index]
        self.buffer.activate()

    # .............................................................................................................
    def clearBuffer (self):
        """clears the buffer, if interpreter, resets cursor pos otherwise"""
        self.buffer.clear()

    # .............................................................................................................
    def closeBuffer (self):
        """closes the current buffer"""
        if self.buffer == self.buffers[0]:                      # current buffer is interpreter 
            self.viewBuffer(1)                                      # view next buffer
            return
        if not self.buffer.unchanged:                           # current buffer contains changes
            self.setStatus("!unsaved!")                             # warn
            return                                                  
        buffer_index = self.buffers.index(self.buffer)
        del self.buffers[buffer_index]                          # delete current buffer
        self.viewBuffer(buffer_index)                               # view next buffer

    # .............................................................................................................
    def openFile (self, file_path):
        """loads and displays a python file"""
        for buffer in self.buffers:
            if isinstance(buffer, KikiPyFile) and buffer.sameFile(file_path):
                self.viewBuffer(self.buffers.index(buffer))
                return
        file_buffer = KikiPyFile(self)
        if file_buffer.openFile(file_path):
            self.buffers.append(file_buffer)
            self.buffer = file_buffer
            self.viewBuffer(len(self.buffers)-1)
        else:
            del  file_buffer
        
    # .............................................................................................................
    #                                                  DISPLAY
    # .............................................................................................................
    
    def displayText (self):
        """display the text of current file or interpreter"""
        self.updateCursor ()
        pos = KikiPos()
        display_pos = KikiPos(-self.offset, 0)
        self.buffer.text_color.glColor()
    
        for lineIndex in range(self.line_offset, min(self.line_offset + self.view_rows, len(self.buffer.lines))):
            
            line = self.buffer.lines[lineIndex]
            if self.buffer.color_syntax:
                if lineIndex in self.buffer.color_line_cache:
                    matches = self.buffer.color_line_cache[lineIndex]
                else:
                    matches = []
            
                    for patternIndex in range(len(self.buffer.syntax_colors)):
                        matches.extend([(mo.span(), patternIndex) for mo in \
                                self.buffer.syntax_colors[patternIndex][0].finditer(line)])
                                
                    matches.sort(lambda a, b: a[0][0]-b[0][0] or b[0][1]-a[0][1])
                
                    self.buffer.color_line_cache[lineIndex] = matches
                            
                for match in matches:
                    if match[0][0] > pos.x:                         # match start > pos 
                        self.buffer.text_color.glColor()                # display default text
                        self.widget.displayStringAtPos(line[pos.x:match[0][0]], display_pos)
                        pos.x = match[0][0]
                        display_pos.x = pos.x-self.offset
                    if match[0][0] == pos.x:                        # match start == pos
                        self.buffer.syntax_colors[match[1]][1].glColor()       # display match
                        self.widget.displayStringAtPos(line[pos.x:match[0][1]], display_pos)
                        pos.x = match[0][1]
                        display_pos.x = pos.x-self.offset
        
                if pos.x < len(line):
                    self.buffer.text_color.glColor()
                self.widget.displayStringAtPos(line[pos.x:], display_pos)
            else:
                self.widget.displayStringAtPos(line[self.offset:], pos)
                
            pos.x  = 0
            display_pos.x = -self.offset
            pos.y += 1
            display_pos.y += 1
    
    # .............................................................................................................
    def updateCursor (self):
        """maps and sets the cursor and selection positions to window coordinates"""
        offsetPos = KikiPos(self.offset, self.line_offset)
        self.widget.cursorPos    = self.buffer.cursor - offsetPos
        self.widget.selectionPos = self.buffer.selection - offsetPos
    
    # .............................................................................................................
    def updateScrollBar (self):
        """notifies the python window about text changes for scrollbar updates"""
        kiki.Controller.python.setScrollBarUnits(self.line_offset, len(self.buffer.lines))
    
    # .............................................................................................................
    def setStatus (self, text):
        """displays text in the status line"""
        self.widget.getPythonWindow().setStatus(text)
    
    def setTitle (self, text):
        """displays text in the title line"""
        self.widget.getPythonWindow().setTitle(str(text))
        
    def setInput (self, text):
        """displays text in the input line"""
        self.widget.getPythonWindow().setInput(text)
    
    def hide (self):
        self.widget.getPythonWindow().setVisibility(0)
         
    # .............................................................................................................
    #                                                  SCROLLING
    # .............................................................................................................
    
    # .............................................................................................................
    def scrollToCursor (self):
        """scrolls to the cursor position"""
        if self.buffer.cursor.y < self.line_offset:                                   # cursor is above top line
            self.line_offset = max(0, self.buffer.cursor.y)
            self.updateScrollBar()
        elif self.buffer.cursor.y > self.line_offset + self.view_rows - 1:            # cursor is below bottom line 
            self.line_offset = min(len(self.buffer.lines) - self.view_rows + 1, \
                                    self.buffer.cursor.y - self.view_rows + 1)
            self.updateScrollBar()
            
        if self.buffer.cursor.x < self.offset:                                         # cursor is to the left
            self.offset = max(0, self.buffer.cursor.x)
        elif self.buffer.cursor.x > self.offset + self.view_cols - 1:                  # cursor is to the right  
            self.offset = min(len(self.buffer.lines[self.buffer.cursor.y]) - self.view_cols + 1, \
                                    self.buffer.cursor.x - self.view_cols + 1)
    
    def scrollRelative (self, value):
        """scrolls to relative text position value (should be in range [0,1])"""
        self.line_offset = int(max(0, value * (len(self.buffer.lines) - self.view_rows)))
    
    # .............................................................................................................
    def scrollRelY (self, y):
        self.line_offset = minmax(0, max(len(self.buffer.lines) - self.view_rows, 0), self.line_offset+y)
        self.buffer.setCursor(self.buffer.cursor.x, \
                                minmax(self.line_offset, self.line_offset+self.view_rows, self.buffer.cursor.y))
    
    # .............................................................................................................
    def scrollLineDown (self):
        self.scrollRelY(+1)
    
    # .............................................................................................................
    def scrollLineUp (self):
        self.scrollRelY(-1)
    
    # .............................................................................................................
    def scrollPageUp (self):
        self.scrollRelY(-self.view_rows);
    
    # .............................................................................................................
    def scrollPageDown (self):
        self.scrollRelY(self.view_rows);
    
    # .............................................................................................................
    def scrollToTop (self):
        self.scrollRelY(-self.line_offset);
    
    # .............................................................................................................
    def scrollToBottom (self):
        self.scrollRelY(len(self.buffer.lines));
            
    # .............................................................................................................
    #                                                  MOUSE INPUT
    # .............................................................................................................
    
    def picked (self, pos):
        """starts editing and sets the cursor at picked position"""
        newPos = self.convertFromWindowPos(pos)
        self.buffer.setCursor(newPos.x, newPos.y)

    # .............................................................................................................
    def doubleClicked (self):
        """selects to word boundaries to the left and the right of the cursor position"""
        self.buffer.handleDoubleClick()

    # .............................................................................................................
    def mouseMoved (self, pos):
        """updates the selection (and scrolls the widget, if neccessary (not implemented yet))"""    
        self.buffer.selection = self.convertFromWindowPos(pos)

    # .............................................................................................................
    def convertFromWindowPos (self, wpos):
        """returns the position wpos in window coordinates as a KikiPos in text coordiates"""
        return KikiPos(wpos[0] + self.offset, wpos[1] + self.line_offset)
    
    # .............................................................................................................
    #                                                          USER INPUT
    # .............................................................................................................
    def requestUserInput (self, mode):
        """paste selected characters"""
        self.input_mode = mode
        kiki.Controller.python.requestUserInput(mode)
    
    # .............................................................................................................
    def userInput (self, input):
        """handles the user input in from the input line"""
        if self.input_mode == "find":
            self.buffer.findAndGotoText (input)
        elif self.input_mode == "open":
            self.openFile(input)     
        elif self.input_mode == "goto":
            self.buffer.setCursor(0, int(input)-1)
    
    # .............................................................................................................
    #                                                  KEYBOARD INPUT
    # .............................................................................................................

    def handleKey (self, key, character):
        """handles a key press"""
        
        # ................................................... extract mod- and key name
        modName = ""
        keyName = key
        if key.find("_") <> -1:
            modName = key.split("_")[0]
            keyName = key.split("_")[1]

        # ................................................... ignore modifier keys
        if key == "SHIFT" or key == "CTRL" or key == "META" or key == "ALT": 
            return 1
            
        # ................................................... forward key to buffer
        if self.buffer.handleKeyModChar(keyName, modName, character):
            return 1

        # ................................................... control sequences
        if modName:
            # ..................................................................  META
            if modName == "META":                                             
                if keyName == "i":                                              # META_i
                    self.viewBuffer(0)                                              # go to interpreter
                    return 1
                elif keyName == "o":                                            # META_o
                    self.requestUserInput("open")                                   # open file
                    return 1
                elif keyName == "SPACE":                                        # META_SPACE
                    prev_index = self.buffers.index(self.buffer)-1
                    if prev_index < 0:
                        prev_index = len(self.buffers)-1
                    self.viewBuffer(prev_index)                                # previous buffer
                    return 1
            elif modName == "SHIFT+META":
                if keyName == "w":
                    self.closeBuffer()
                    return 1

# ................................................................................. setup python console

pythonConsole = PythonConsole(kiki.Controller.python.getPythonWidget())

kiki.Controller.python.setPosition((0,0))
kiki.Controller.python.setSize((1024,695))