~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to wxPython/wx/tools/Editra/src/ed_keyh.py

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
###############################################################################
 
2
# Name: ed_keyh.py                                                            #
 
3
# Purpose: Editra's Vi Emulation Key Handler                                  #
 
4
# Author: Cody Precord <cprecord@editra.org>                                  #
 
5
# Copyright: (c) 2008 Cody Precord <staff@editra.org>                         #
 
6
# License: wxWindows License                                                  #
 
7
###############################################################################
 
8
 
 
9
"""
 
10
KeyHandler interface for implementing extended key action handling in Editra's
 
11
main text editting buffer.
 
12
 
 
13
@summary: Custom keyhandler interface
 
14
 
 
15
"""
 
16
 
 
17
__author__ = "Cody Precord <cprecord@editra.org>"
 
18
__svnid__ = "$Id: ed_keyh.py 70747 2012-02-29 01:33:35Z CJP $"
 
19
__revision__ = "$Revision: 70747 $"
 
20
 
 
21
#-------------------------------------------------------------------------#
 
22
# Imports
 
23
import re
 
24
import wx
 
25
import wx.stc
 
26
 
 
27
# Editra Libraries
 
28
import ed_event
 
29
import ed_glob
 
30
import ed_basestc
 
31
import ed_stc
 
32
import string
 
33
import ed_vim
 
34
 
 
35
#-------------------------------------------------------------------------#
 
36
# Use this base class to derive any new keyhandlers from. The keyhandler is
 
37
# called upon by the active buffer when ever a key press event happens. The
 
38
# handler then has the responsibility of deciding what to do with the key.
 
39
#
 
40
class KeyHandler(object):
 
41
    """KeyHandler base class"""
 
42
    def __init__(self, stc):
 
43
        super(KeyHandler, self).__init__()
 
44
 
 
45
        # Attributes
 
46
        self.stc = stc
 
47
        self._blockmode = False
 
48
 
 
49
    STC = property(lambda self: self.stc)
 
50
    BlockMode = property(lambda self: self._blockmode,
 
51
                         lambda self,m:setattr(self,'_blockmode', m))
 
52
 
 
53
    def ClearMode(self):
 
54
        """Clear any key input modes to normal input mode"""
 
55
        evt = ed_event.StatusEvent(ed_event.edEVT_STATUS, self.stc.Id,
 
56
                                   '', ed_glob.SB_BUFF)
 
57
        wx.PostEvent(self.stc.TopLevelParent, evt)
 
58
 
 
59
    def GetHandlerName(self):
 
60
        """Get the name of this handler
 
61
        @return: string
 
62
 
 
63
        """
 
64
        return u'NULL'
 
65
 
 
66
    def PreProcessKey(self, key_code, ctrldown=False,
 
67
                      cmddown=False, shiftdown=False, altdown=False):
 
68
        """Pre process any keys before they get to the char handler
 
69
        @param key_code: Raw keycode
 
70
        @keyword ctrldown: Is the control key down
 
71
        @keyword cmddown: Is the Command key down (Mac osx)
 
72
        @keyword shiftdown: Is the Shift key down
 
73
        @keyword altdown: Is the Alt key down
 
74
        @return: bool
 
75
 
 
76
        """
 
77
        return False
 
78
 
 
79
    def ProcessKey(self, key_code, ctrldown=False,
 
80
                   cmddown=False, shiftdown=False, altdown=False):
 
81
        """Process the key and return True if it was processed and
 
82
        false if it was not. The key is recieved at EVT_CHAR.
 
83
        @param key_code: Raw keycode
 
84
        @keyword ctrldown: Is the control key down
 
85
        @keyword cmddown: Is the Command key down (Mac osx)
 
86
        @keyword shiftdown: Is the Shift key down
 
87
        @keyword altdown: Is the Alt key down
 
88
        @return: bool
 
89
 
 
90
        """
 
91
        return False
 
92
 
 
93
#-------------------------------------------------------------------------#
 
94
 
 
95
class ViKeyHandler(KeyHandler):
 
96
    """Defines a key handler for Vi emulation
 
97
    @summary: Handles key presses according to Vi emulation.
 
98
 
 
99
    """
 
100
 
 
101
    # Vi Mode declarations
 
102
    NORMAL, \
 
103
    INSERT, \
 
104
    VISUAL, \
 
105
        = range(3)
 
106
 
 
107
    def __init__(self, stc, use_normal_default=False):
 
108
        super(ViKeyHandler, self).__init__(stc)
 
109
 
 
110
        # Attributes
 
111
        self.mode = 0
 
112
        self.last = u''
 
113
        self.last_find = u''
 
114
        self.commander = ed_vim.EditraCommander(self)
 
115
        self.buffer = u''
 
116
 
 
117
        # Insert mode by default
 
118
        if use_normal_default:
 
119
            self.NormalMode()
 
120
        else:
 
121
            self.InsertMode()
 
122
 
 
123
    def ClearMode(self):
 
124
        """Clear the mode back to default input mode"""
 
125
        # TODO:CJP when newer scintilla is available in 2.9 use
 
126
        #          blockcaret methods.
 
127
        self.STC.SetLineCaret()
 
128
        self.BlockMode = False
 
129
        self.last = self.cmdcache = u''
 
130
        super(ViKeyHandler, self).ClearMode()
 
131
 
 
132
    def GetHandlerName(self):
 
133
        """Get the name of this handler"""
 
134
        return u'VI'
 
135
 
 
136
    def _SetMode(self, newmode, msg):
 
137
        """Set the keyhandlers mode
 
138
        @param newmode: New mode name to change to
 
139
 
 
140
        """
 
141
        self.buffer = u'' # Clear buffer from last mode
 
142
        self.mode = newmode
 
143
        # Update status bar
 
144
        evt = ed_event.StatusEvent(ed_event.edEVT_STATUS, self.stc.GetId(),
 
145
                                   msg, ed_glob.SB_BUFF)
 
146
        wx.PostEvent(self.stc.GetTopLevelParent(), evt)
 
147
 
 
148
    def InsertMode(self):
 
149
        """Change to insert mode"""
 
150
        self.stc.SetLineCaret()
 
151
        self.stc.SetOvertype(False)
 
152
        self.BlockMode = False
 
153
        self._SetMode(ViKeyHandler.INSERT, u"INSERT")
 
154
 
 
155
    def ReplaceMode(self):
 
156
        """Change to replace mode
 
157
        This really just insert mode with overtype set to true
 
158
 
 
159
        """
 
160
        self.stc.SetLineCaret()
 
161
        self.stc.SetOvertype(True)
 
162
        self._SetMode(ViKeyHandler.INSERT, u"REPLACE")
 
163
 
 
164
    def NormalMode(self):
 
165
        """Change to normal (command) mode"""
 
166
        if self.IsInsertMode():
 
167
            self.commander.SetLastInsertedText(self.buffer)
 
168
 
 
169
        self.stc.SetOvertype(False)
 
170
        self.stc.SetBlockCaret()
 
171
        self.BlockMode = True
 
172
        self.commander.Deselect()
 
173
        self.commander.InsertRepetition()
 
174
        self._SetMode(ViKeyHandler.NORMAL, u'NORMAL')
 
175
 
 
176
    def VisualMode(self):
 
177
        """Change to visual (selection) mode"""
 
178
        self.stc.SetBlockCaret()
 
179
        self.BlockMode = True
 
180
        self.stc.SetOvertype(False)
 
181
        self._SetMode(ViKeyHandler.VISUAL, u'VISUAL')
 
182
        self.commander.StartSelection()
 
183
 
 
184
    def IsInsertMode(self):
 
185
        """Test if we are in insert mode"""
 
186
        return self.mode == ViKeyHandler.INSERT
 
187
 
 
188
    def IsNormalMode(self):
 
189
        """Test if we are in normal mode"""
 
190
        return self.mode == ViKeyHandler.NORMAL
 
191
 
 
192
    def IsVisualMode(self):
 
193
        """Test if we are in visual mode"""
 
194
        return self.mode == ViKeyHandler.VISUAL
 
195
 
 
196
    def PreProcessKey(self, key_code, ctrldown=False,
 
197
                      cmddown=False, shiftdown=False, altdown=False):
 
198
        """Pre process any keys before they get to the char handler
 
199
        @param key_code: Raw keycode
 
200
        @keyword ctrldown: Is the control key down
 
201
        @keyword cmddown: Is the Command key down (Mac osx)
 
202
        @keyword shiftdown: Is the Shift key down
 
203
        @keyword altdown: Is the Alt key down
 
204
        @return: bool
 
205
 
 
206
        """
 
207
        if not shiftdown and key_code == wx.WXK_ESCAPE:
 
208
            # If Vi emulation is active go into Normal mode and
 
209
            # pass the key event to the char handler by not processing
 
210
            # the key.
 
211
            self.NormalMode()
 
212
            return False
 
213
        elif (ctrldown or cmddown) and key_code == ord('['):
 
214
            self.NormalMode()
 
215
            return True
 
216
        elif key_code in (wx.WXK_RETURN, wx.WXK_BACK,
 
217
                          wx.WXK_RIGHT, wx.WXK_LEFT) and \
 
218
             not self.IsInsertMode():
 
219
            # swallow enter key in normal and visual modes
 
220
            # HACK: we have to do it form here because ProcessKey
 
221
            #       is only called on Char events, not Key events,
 
222
            #       and the Enter key does not generate a Char event.
 
223
            self.ProcessKey(key_code)
 
224
            return True
 
225
        else:
 
226
            return False
 
227
 
 
228
    def ProcessKey(self, key_code, ctrldown=False,
 
229
                   cmddown=False, shiftdown=False, altdown=False):
 
230
        """Processes keys and decided whether to interpret them as vim commands
 
231
        or normal insert text
 
232
 
 
233
        @param key_code: Raw key code
 
234
        @keyword cmddown: Command/Ctrl key is down
 
235
        @keyword shiftdown: Shift Key is down
 
236
        @keyword altdown : Alt key is down
 
237
 
 
238
        """
 
239
        if ctrldown or cmddown or altdown:
 
240
            return False
 
241
 
 
242
        # Mode may change after processing the key, so we need to remember
 
243
        # whether this was a command or not
 
244
        f_cmd = self.IsNormalMode() or self.IsVisualMode()
 
245
 
 
246
        self._ProcessKey(key_code)
 
247
 
 
248
        # Update status bar
 
249
        if self.IsNormalMode():
 
250
            if self.stc.GetTopLevelParent():
 
251
                evt = ed_event.StatusEvent(ed_event.edEVT_STATUS,
 
252
                                           self.stc.GetId(),
 
253
                                           u"NORMAL %s" % self.buffer,
 
254
                                           ed_glob.SB_BUFF)
 
255
                wx.PostEvent(self.stc.GetTopLevelParent(), evt)
 
256
 
 
257
        if f_cmd:
 
258
            return True
 
259
        else:
 
260
            # If we're in insert mode we must return False
 
261
            # so the text gets inserted into the editor
 
262
            return False
 
263
 
 
264
    def _ProcessKey(self, key_code):
 
265
        """The real processing of keys"""
 
266
        char = unichr(key_code)
 
267
        if self.IsNormalMode() or self.IsVisualMode():
 
268
            self.buffer += char
 
269
            if ed_vim.Parse(self.buffer, self.commander):
 
270
                # command was handled (or invalid) so clear buffer
 
271
                self.buffer = u''
 
272
 
 
273
            if self.IsVisualMode():
 
274
                self.commander.ExtendSelection()
 
275
 
 
276
        elif self.IsInsertMode():
 
277
            self.buffer += char
 
278
 
 
279
    def InsertText(self, pos, text):
 
280
        """Insert text and store it in the buffer if we're in insert mode
 
281
        i.e. as if it was typed in
 
282
 
 
283
        """
 
284
        self.stc.InsertText(pos, text)
 
285
        if self.IsInsertMode():
 
286
            self.buffer += text
 
 
b'\\ No newline at end of file'