~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/core/Mono.Texteditor/Mono.TextEditor.Vi/ViBuilders.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// ViBuilders.cs
 
3
//  
 
4
// Author:
 
5
//       Michael Hutchinson <mhutchinson@novell.com>
 
6
// 
 
7
// Copyright (c) 2010 Novell, Inc.
 
8
// 
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
// 
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
// 
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
 
 
27
using System;
 
28
using System.Linq;
 
29
using Gdk;
 
30
using System.Text;
 
31
 
 
32
namespace Mono.TextEditor.Vi
 
33
{
 
34
        class ViBuilders
 
35
        {
 
36
                public static bool Mark (ViBuilderContext ctx)
 
37
                {
 
38
                        char c = ctx.LastKey.Char;
 
39
                        if (!char.IsLetterOrDigit (c)) {
 
40
                                ctx.SetError ("Invalid Mark");
 
41
                                return true;
 
42
                        }
 
43
                        
 
44
                        ctx.RunAction ((ViEditor ed) => {
 
45
                                ViMark mark;
 
46
                                if (!ed.Marks.TryGetValue (c, out mark))
 
47
                                        ed.Marks [c] = mark = new ViMark (c);
 
48
                                mark.SaveMark (ed.Data);
 
49
                        });
 
50
                        return true;
 
51
                }
 
52
                
 
53
                public static ViBuilder InsertBuilder (ViBuilder preInsertActions)
 
54
                {       
 
55
                        var lastInserted = new StringBuilder ();
 
56
                        bool inUndoTx = false;
 
57
                        return (ViBuilderContext ctx) => {
 
58
                                var l = ctx.LastKey;
 
59
                                bool noModifiers = l.Modifiers == ModifierType.None;
 
60
                                
 
61
                                ctx.Message = ctx.Mode == ViEditorMode.Replace? "-- REPLACE --" : "-- INSERT --";
 
62
                                
 
63
                                if ((noModifiers && l.Key == Key.Escape) || (l.Char == 'c' && (l.Modifiers & ModifierType.ControlMask) != 0)) {
 
64
                                        ctx.RunAction ((ViEditor ed) => {
 
65
                                                if (inUndoTx)
 
66
                                                {
 
67
                                                        ed.Document.EndAtomicUndo ();
 
68
                                                        inUndoTx = false;
 
69
                                                }
 
70
                                                ed.LastInsertedText = lastInserted.ToString ();
 
71
                                                ed.SetMode (ViEditorMode.Normal);
 
72
                                        });
 
73
                                        return true;
 
74
                                }
 
75
                                
 
76
                                //keypad motions etc
 
77
                                if (preInsertActions (ctx)) {
 
78
                                        if (inUndoTx)
 
79
                                                ctx.RunAction ( (ed) => ed.Document.EndAtomicUndo () );
 
80
                                        inUndoTx = false;
 
81
                                        ctx.SuppressCompleted ();
 
82
                                        lastInserted.Length = 0;
 
83
                                        return true;
 
84
                                }
 
85
                                
 
86
                                if (l.Char != '\0' && noModifiers) {
 
87
                                        if (!inUndoTx)
 
88
                                                ctx.RunAction ( (ed) => ed.Document.BeginAtomicUndo () );
 
89
                                        inUndoTx = true;
 
90
                                        ctx.SuppressCompleted ();
 
91
                                        lastInserted.Append (l.Char);
 
92
                                        ctx.InsertChar (l.Char);
 
93
                                        return true;
 
94
                                }
 
95
                                
 
96
                                return false;
 
97
                        };
 
98
                }
 
99
                
 
100
                public static bool GoToMark (ViBuilderContext ctx)
 
101
                {
 
102
                        char c = ctx.LastKey.Char;
 
103
                        if (!char.IsLetterOrDigit (c)) {
 
104
                                ctx.SetError ("Invalid Mark");
 
105
                                return true;
 
106
                        }
 
107
                        
 
108
                        ctx.RunAction ((ViEditor ed) => {
 
109
                                ViMark mark;
 
110
                                if (ed.Marks.TryGetValue (c, out mark))
 
111
                                        mark.LoadMark (ed.Data);
 
112
                                else
 
113
                                        ed.Reset ("Unknown Mark");
 
114
                        });
 
115
                        return true;
 
116
                }
 
117
                
 
118
                
 
119
                public static bool ReplaceChar (ViBuilderContext ctx)
 
120
                {
 
121
                        if (ctx.LastKey.Char != '\0')
 
122
                                ctx.RunAction ((ViEditor ed) => ed.Data.Replace (ed.Data.Caret.Offset, 1, ctx.LastKey.Char.ToString ()));
 
123
                        else
 
124
                                ctx.SetError ("Expecting a character");
 
125
                        return true;
 
126
                }
 
127
                
 
128
                static void StartRegisterBuilder (ViBuilderContext ctx, ViBuilder nextBuilder)
 
129
                {
 
130
                        if (ctx.Register != '\0') {
 
131
                                ctx.SetError ("Register already set");
 
132
                                return;
 
133
                        }
 
134
                        ctx.Builder = (ViBuilderContext x) => {
 
135
                                char c = x.LastKey.Char;
 
136
                                if (!ViEditor.IsValidRegister (c)) {
 
137
                                        x.SetError ("Invalid register");
 
138
                                        return true;
 
139
                                }
 
140
                                x.Register = c;
 
141
                                x.Builder = nextBuilder;
 
142
                                return true;
 
143
                        };
 
144
                }
 
145
                
 
146
                static void StartMultiplierBuilder (ViBuilderContext ctx, ViBuilder nextBuilder)
 
147
                {
 
148
                        int factor = 1;
 
149
                        int multiplier = 0;
 
150
                        ctx.Builder = (ViBuilderContext x) => {
 
151
                                int c = (int)x.LastKey.Char;
 
152
                                if (c >= (int)'0' && c <= (int)'9') {
 
153
                                        int d = c - (int)'0';
 
154
                                        multiplier = multiplier * factor + d;
 
155
                                        factor *= 10;
 
156
                                        return true;
 
157
                                } else {
 
158
                                        ctx.Multiplier *= multiplier;
 
159
                                        ctx.Builder = nextBuilder;
 
160
                                        return ctx.Builder (ctx);
 
161
                                }
 
162
                        };
 
163
                        ctx.Builder (ctx);
 
164
                }
 
165
                
 
166
                public static ViBuilder MultiplierBuilder (ViBuilder nextBuilder)
 
167
                {
 
168
                        return (ViBuilderContext ctx) => {
 
169
                                var k = ctx.LastKey;
 
170
                                if (char.IsDigit (k.Char)) {
 
171
                                        ViBuilders.StartMultiplierBuilder (ctx, nextBuilder);
 
172
                                        return true;
 
173
                                } else {
 
174
                                        ctx.Builder = nextBuilder;
 
175
                                        return ctx.Builder (ctx);
 
176
                                }
 
177
                        };
 
178
                }
 
179
                
 
180
                public static ViBuilder RegisterBuilder (ViBuilder nextBuilder)
 
181
                {
 
182
                        return (ViBuilderContext ctx) => {
 
183
                                var k = ctx.LastKey;
 
184
                                if (k.Char == '"') {
 
185
                                        ViBuilders.StartRegisterBuilder (ctx, nextBuilder);
 
186
                                        return true;
 
187
                                } else {
 
188
                                        ctx.Builder = nextBuilder;
 
189
                                        return ctx.Builder (ctx);
 
190
                                }
 
191
                        };
 
192
                }
 
193
                
 
194
                public static ViBuilder First (params ViBuilder[] builders)
 
195
                {
 
196
                        return (ViBuilderContext ctx) => builders.Any (b => b (ctx));
 
197
                }
 
198
        }
 
199
}