5
// Michael Hutchinson <mhutchinson@novell.com>
7
// Copyright (c) 2010 Novell, Inc.
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:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
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
32
namespace Mono.TextEditor.Vi
36
public static bool Mark (ViBuilderContext ctx)
38
char c = ctx.LastKey.Char;
39
if (!char.IsLetterOrDigit (c)) {
40
ctx.SetError ("Invalid Mark");
44
ctx.RunAction ((ViEditor ed) => {
46
if (!ed.Marks.TryGetValue (c, out mark))
47
ed.Marks [c] = mark = new ViMark (c);
48
mark.SaveMark (ed.Data);
53
public static ViBuilder InsertBuilder (ViBuilder preInsertActions)
55
var lastInserted = new StringBuilder ();
56
bool inUndoTx = false;
57
return (ViBuilderContext ctx) => {
59
bool noModifiers = l.Modifiers == ModifierType.None;
61
ctx.Message = ctx.Mode == ViEditorMode.Replace? "-- REPLACE --" : "-- INSERT --";
63
if ((noModifiers && l.Key == Key.Escape) || (l.Char == 'c' && (l.Modifiers & ModifierType.ControlMask) != 0)) {
64
ctx.RunAction ((ViEditor ed) => {
67
ed.Document.EndAtomicUndo ();
70
ed.LastInsertedText = lastInserted.ToString ();
71
ed.SetMode (ViEditorMode.Normal);
77
if (preInsertActions (ctx)) {
79
ctx.RunAction ( (ed) => ed.Document.EndAtomicUndo () );
81
ctx.SuppressCompleted ();
82
lastInserted.Length = 0;
86
if (l.Char != '\0' && noModifiers) {
88
ctx.RunAction ( (ed) => ed.Document.BeginAtomicUndo () );
90
ctx.SuppressCompleted ();
91
lastInserted.Append (l.Char);
92
ctx.InsertChar (l.Char);
100
public static bool GoToMark (ViBuilderContext ctx)
102
char c = ctx.LastKey.Char;
103
if (!char.IsLetterOrDigit (c)) {
104
ctx.SetError ("Invalid Mark");
108
ctx.RunAction ((ViEditor ed) => {
110
if (ed.Marks.TryGetValue (c, out mark))
111
mark.LoadMark (ed.Data);
113
ed.Reset ("Unknown Mark");
119
public static bool ReplaceChar (ViBuilderContext ctx)
121
if (ctx.LastKey.Char != '\0')
122
ctx.RunAction ((ViEditor ed) => ed.Data.Replace (ed.Data.Caret.Offset, 1, ctx.LastKey.Char.ToString ()));
124
ctx.SetError ("Expecting a character");
128
static void StartRegisterBuilder (ViBuilderContext ctx, ViBuilder nextBuilder)
130
if (ctx.Register != '\0') {
131
ctx.SetError ("Register already set");
134
ctx.Builder = (ViBuilderContext x) => {
135
char c = x.LastKey.Char;
136
if (!ViEditor.IsValidRegister (c)) {
137
x.SetError ("Invalid register");
141
x.Builder = nextBuilder;
146
static void StartMultiplierBuilder (ViBuilderContext ctx, ViBuilder nextBuilder)
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;
158
ctx.Multiplier *= multiplier;
159
ctx.Builder = nextBuilder;
160
return ctx.Builder (ctx);
166
public static ViBuilder MultiplierBuilder (ViBuilder nextBuilder)
168
return (ViBuilderContext ctx) => {
170
if (char.IsDigit (k.Char)) {
171
ViBuilders.StartMultiplierBuilder (ctx, nextBuilder);
174
ctx.Builder = nextBuilder;
175
return ctx.Builder (ctx);
180
public static ViBuilder RegisterBuilder (ViBuilder nextBuilder)
182
return (ViBuilderContext ctx) => {
185
ViBuilders.StartRegisterBuilder (ctx, nextBuilder);
188
ctx.Builder = nextBuilder;
189
return ctx.Builder (ctx);
194
public static ViBuilder First (params ViBuilder[] builders)
196
return (ViBuilderContext ctx) => builders.Any (b => b (ctx));