Code Coverage Statistics for Source File

C:\Users\Marcus\Documents\MyCode\2007\SharpSelectWord\SharpSelectWord\Src\SingleWordSelection.cs

Sequence Point Coverage
100,0%
96 of 96
Branch Coverage
N/A
0 of 0
Lines
252
Highlight: Uncovered Code Covered Code
L V Source
1
// SharpSelectWord is a addin to SharpDevelop that can select text.
2
// Copyright (C) 2007  Marcus Holmgren
3
// 
4
// This library is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU Lesser General Public
6
// License as published by the Free Software Foundation; either
7
// version 2.1 of the License, or (at your option) any later version.
8
// 
9
// This library is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
// Lesser General Public License for more details.
13
// 
14
// You should have received a copy of the GNU Lesser General Public
15
// License along with this library; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
19
using System;
20
using ICSharpCode.TextEditor;
21
using ICSharpCode.TextEditor.Document;
22
23
namespace MarcusHolmgren.SharpDevelop.SelectWord
24
{
25
    /// <summary>
26
    /// Purpose of the SingleWordSelection class is to select the first word positioned closest to the current cursor position.
27
    /// </summary>
28
    public sealed class SingleWordSelection : ISelection
29
    {
30
        private readonly IDocument itsDocument;
31
        private TextLocation itsStartPosition;
32
        private TextLocation itsEndPosition;
33
        private int itsOffset;
34
        private int itsEndOffset;
35
        private string itsSelectedText;
36
37
        /// <summary>
38
        /// Initialize a new instance of the SingleWordSelection class.
39
        /// </summary>
40
        /// <param name="document">IDocument object.</param>
41
        /// <param name="offset">Current position for the cursor.</param>
42
        /// <exception cref="ArgumentNullException">If parameter document is not provided an ArgumentNullException is throw.</exception>
43
28
        public SingleWordSelection(IDocument document, int offset)
44
        {
45
28
            if (document == null)
46
1
                throw new ArgumentNullException("document");
47
48
27
            itsDocument = document;
49
50
27
            if (offset < 0) itsOffset = 0;
51
23
            else if (offset >= document.TextLength) itsOffset = document.TextLength - 1;
52
17
            else itsOffset = offset;
53
54
27
            itsEndOffset = itsOffset;
55
56
27
            FindSelection();
57
        }
58
59
60
        public bool ContainsOffset(int offset)
61
        {
62
14
            return itsOffset != offset;
63
14
        }
64
65
        public TextLocation StartPosition
66
        {
67
48
            get { return itsStartPosition; }
68
23
            set { itsStartPosition = value; }
69
        }
70
71
        public TextLocation EndPosition
72
        {
73
44
            get { return itsEndPosition; }
74
23
            set { itsEndPosition = value; }
75
        }
76
77
        public int Offset
78
        {
79
135
            get { return itsOffset; }
80
        }
81
82
        public int EndOffset
83
        {
84
49
            get { return itsEndOffset; }
85
        }
86
87
        public int Length
88
        {
89
13
            get { return IsEmpty ? 0 : SelectedText.Length; }
90
        }
91
92
        public bool IsRectangularSelection
93
        {
94
13
            get { return false; }
95
        }
96
97
        public bool IsEmpty
98
        {
99
27
            get { return  string.IsNullOrEmpty(itsSelectedText) ? true : false; }
100
        }
101
102
        public string SelectedText
103
        {
104
39
            get{ return itsSelectedText; }
105
        }
106
107
108
        public bool ContainsPosition(TextLocation position)
109
        {
110
13
            System.Diagnostics.Debug.WriteLine("ContainsPosition");
111
            //if (itsStartPosition.Line == position.Line)
112
113
13
            return false;
114
13
        }
115
116
        /// <summary>
117
        /// Navigates the current offset and locates the closest word.
118
        /// </summary>
119
        private void FindSelection()
120
        {
121
27
            if (itsDocument.TextLength > 0)
122
            {
123
23
                if (NotPositionedAtSingleCharacter())
124
                {
125
21
                    SetStartingLocation();
126
21
                    SetStartOffset();
127
21
                    SetEndOffset();
128
                }
129
130
23
                itsSelectedText = itsDocument.GetText(Offset, EndOffset - Offset);
131
            }
132
27
        }
133
134
        /// <summary>
135
        /// Check if the cursor is positioned inside a single character quote.
136
        /// </summary>
137
        /// <returns>True if cursor is positioned at a single character, otherwise false.</returns>
138
        private bool NotPositionedAtSingleCharacter()
139
        {
140
            const char SingleQuote = '\'';
141
23
            bool isSingleCharacter = false;
142
23
            if (itsDocument.GetCharAt(Offset) == SingleQuote && (Offset - 2) > 0)
143
            {
144
3
                if (itsDocument.GetCharAt(Offset - 2) == SingleQuote)
145
                {
146
1
                    itsOffset--;
147
1
                    isSingleCharacter = true;
148
                }
149
            }
150
20
            else if ((Offset - 1) > 0 && itsDocument.GetCharAt(Offset - 1) == SingleQuote)
151
            {
152
1
                if ((EndOffset + 1) < itsDocument.TextLength && itsDocument.GetCharAt(EndOffset + 1) == SingleQuote)
153
                {
154
1
                    itsEndOffset++;
155
1
                    isSingleCharacter = true;
156
                }
157
            }
158
159
23
            if (isSingleCharacter)
160
            {
161
2
                StartPosition = itsDocument.OffsetToPosition(Offset);
162
2
                EndPosition = itsDocument.OffsetToPosition(EndOffset);
163
            }
164
165
23
            return !isSingleCharacter;
166
23
        }
167
168
        /// <summary>
169
        /// Reposition starting offset if the cursor is positioned at the end of a word.
170
        /// </summary>
171
        private void SetStartingLocation()
172
        {
173
21
            char firstChar = itsDocument.GetCharAt(itsOffset);
174
21
            if (firstChar == ' ' || firstChar == '.' || firstChar == '(')
175
            {
176
5
                char secondChar = itsDocument.GetCharAt(itsOffset - 1);
177
5
                if (itsOffset > 0 && secondChar != ' ' || secondChar != '.' || secondChar != '(')
178
5
                    itsOffset--;
179
            }
180
21
        }
181
182
        /// <summary>
183
        /// Navigate the document from the current cursor position and locates the ending position of the word.
184
        /// </summary>
185
        private void SetEndOffset()
186
        {
187
21
            int temp = itsOffset;
188
189
            bool ok;
190
            do
191
            {
192
136
                char c = itsDocument.GetCharAt(temp);
193
136
                ok = ValidCharacter(c);
194
195
136
                if (ok && temp < itsDocument.TextLength - 1) 
196
115
                    temp++;
197
21
                else ok = false;
198
            }
199
136
            while (ok);
200
201
21
            itsEndOffset = temp;
202
21
            EndPosition = itsDocument.OffsetToPosition(temp);
203
21
        }
204
205
        /// <summary>
206
        /// Navigate the document from the current cursor position and locates the starting position of the word.
207
        /// </summary>
208
        private void SetStartOffset()
209
        {
210
21
            int temp = itsOffset;
211
212
21
            if (itsDocument.GetCharAt(temp) == '\"') temp--;
213
214
            bool ok;
215
            do
216
            {
217
80
                char c = itsDocument.GetCharAt(temp);
218
80
                ok = ValidCharacter(c);
219
220
80
                if (ok && temp > 0) temp--;
221
                else
222
                {
223
21
                    if (!ok && temp > -1  && temp < itsDocument.TextLength - 1) 
224
17
                        temp++;
225
21
                    ok = false;
226
                }
227
            }
228
80
            while (ok);
229
230
21
            itsOffset = temp;
231
21
            StartPosition = itsDocument.OffsetToPosition(temp);
232
21
        }
233
234
        /// <summary>
235
        /// Validates a character.
236
        /// </summary>
237
        /// <param name="input">Character to validate.</param>
238
        /// <returns>True if the input character is valid, otherwise false.</returns>
239
        private static bool ValidCharacter(char input)
240
        {
241
216
            bool result = true;
242
216
            char[] invalidChars = new char[] { ' ', '\n', '\r', '\t', '(', ')', '{', '}', '[', ']', '<', '>', '"', '.', ',', ';', ':' };
243
244
3888
            foreach (char c in invalidChars)
245
            {
246
3672
                if (input == c)
247
38
                    result = false;
248
            }
249
216
            return result;
250
        }
251
    }
252
}