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

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.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:
33
33
using System.Linq;
34
34
using System.Text;
35
35
using System.Collections.Generic;
 
36
using MonoDevelop.Core.Text;
36
37
 
37
38
namespace MonoDevelop.Ide.CodeCompletion
38
39
{
130
131
                {
131
132
                        list.CompletionString = PartialWord;
132
133
                        
133
 
                        if (list.filteredItems.Count == 0 && !list.PreviewCompletionString) {
134
 
                                Hide ();
135
 
                        } else {
136
 
                                if (IsRealized && !Visible)
137
 
                                        Show ();
138
 
                        }
 
134
                        if (IsRealized && !Visible)
 
135
                                Show ();
139
136
                        
140
137
                        int width = list.WidthRequest;
141
138
                        int height = list.HeightRequest + (footer != null ? footer.Allocation.Height : 0);
240
237
                        get;
241
238
                        set;
242
239
                }
 
240
                
 
241
                /// <summary>
 
242
                /// Gets or sets a value indicating that shift was pressed during enter.
 
243
                /// </summary>
 
244
                /// <value>
 
245
                /// <c>true</c> if was shift pressed; otherwise, <c>false</c>.
 
246
                /// </value>
 
247
                public bool WasShiftPressed {
 
248
                        get;
 
249
                        private set;
 
250
                }
243
251
 
244
252
                public KeyActions ProcessKey (Gdk.Key key, char keyChar, Gdk.ModifierType modifier)
245
253
                {
246
254
                        switch (key) {
247
255
                        case Gdk.Key.Home:
 
256
                                if ((modifier & ModifierType.ShiftMask) == ModifierType.ShiftMask)
 
257
                                        return KeyActions.Process;
248
258
                                List.Selection = 0;
249
259
                                return KeyActions.Ignore;
250
260
                        case Gdk.Key.End:
 
261
                                if ((modifier & ModifierType.ShiftMask) == ModifierType.ShiftMask)
 
262
                                        return KeyActions.Process;
251
263
                                List.Selection = List.filteredItems.Count - 1;
252
264
                                return KeyActions.Ignore;
253
265
                                
293
305
                                return KeyActions.Ignore;
294
306
 
295
307
                        case Gdk.Key.Page_Up:
 
308
                                if ((modifier & ModifierType.ShiftMask) == ModifierType.ShiftMask)
 
309
                                        return KeyActions.Process;
296
310
                                if (list.filteredItems.Count < 2)
297
311
                                        return KeyActions.CloseWindow | KeyActions.Process;
298
312
                                list.MoveCursor (-(list.VisibleRows - 1));
299
313
                                return KeyActions.Ignore;
300
314
 
301
315
                        case Gdk.Key.Page_Down:
 
316
                                if ((modifier & ModifierType.ShiftMask) == ModifierType.ShiftMask)
 
317
                                        return KeyActions.Process;
302
318
                                if (list.filteredItems.Count < 2)
303
319
                                        return KeyActions.CloseWindow | KeyActions.Process;
304
320
                                list.MoveCursor (list.VisibleRows - 1);
316
332
                                word.Remove (curPos, 1);
317
333
                                ResetSizes ();
318
334
                                UpdateWordSelection ();
319
 
                                if (word.Length == 0)
 
335
                                if (HideWhenWordDeleted && word.Length == 0)
320
336
                                        return KeyActions.CloseWindow | KeyActions.Process;
321
337
                                return KeyActions.Process;
322
338
 
340
356
                        case Gdk.Key.ISO_Enter:
341
357
                        case Gdk.Key.Key_3270_Enter:
342
358
                        case Gdk.Key.KP_Enter:
 
359
                                WasShiftPressed = (modifier & ModifierType.ShiftMask) == ModifierType.ShiftMask;
343
360
                                return (!list.AutoSelect ? KeyActions.Process : (KeyActions.Complete | KeyActions.Ignore)) | KeyActions.CloseWindow;
344
361
 
345
362
                        case Gdk.Key.Escape:
367
384
                                & modifier) != 0;
368
385
                        if (nonShiftModifierActive)
369
386
                                return KeyActions.Ignore;
370
 
                        const string commitChars = " <>()[]{}=";
 
387
                        const string commitChars = " <>()[]{}=+-*/%~&|!";
371
388
                        if (System.Char.IsLetterOrDigit (keyChar) || keyChar == '_') {
372
389
                                word.Insert (curPos, keyChar);
373
390
                                ResetSizes ();
380
397
 
381
398
                                bool hasMismatches;
382
399
                                int match = FindMatchedEntry (CurrentPartialWord, out hasMismatches);
383
 
                                
 
400
                                if (match >= 0 && System.Char.IsPunctuation (keyChar)) {
 
401
                                        string text = DataProvider.GetCompletionText (FilteredItems [match]);
 
402
                                        if (!text.ToUpper ().StartsWith (word.ToString ().ToUpper ()))
 
403
                                                match =-1;       
 
404
                                }
384
405
                                if (match >= 0 && !hasMismatches && keyChar != '<') {
385
406
                                        ResetSizes ();
386
407
                                        UpdateWordSelection ();
397
418
 
398
419
                        return KeyActions.CloseWindow | KeyActions.Process;
399
420
                }
 
421
                
 
422
                protected bool HideWhenWordDeleted {
 
423
                        get; set;
 
424
                }
400
425
 
401
426
                public void UpdateWordSelection ()
402
427
                {
409
434
                class WordComparer : IComparer <KeyValuePair<int, string>>
410
435
                {
411
436
                        string filterWord;
 
437
                        StringMatcher matcher;
412
438
 
413
439
                        public WordComparer (string filterWord)
414
440
                        {
415
441
                                this.filterWord = filterWord ?? "";
 
442
                                matcher = CompletionMatcher.CreateCompletionMatcher (filterWord);
416
443
                        }
417
444
                        
418
445
                        public int Compare (KeyValuePair<int, string> xpair, KeyValuePair<int, string> ypair)
419
446
                        {
420
447
                                string x = xpair.Value;
421
448
                                string y = ypair.Value;
422
 
                                int[] xMatches = ListWidget.Match (filterWord, x) ?? new int[0];
423
 
                                int[] yMatches = ListWidget.Match (filterWord, y) ?? new int[0];
 
449
                                int[] xMatches = matcher.GetMatch (x) ?? new int[0];
 
450
                                int[] yMatches = matcher.GetMatch (y) ?? new int[0];
424
451
                                if (xMatches.Length < yMatches.Length) 
425
452
                                        return 1;
426
453
                                if (xMatches.Length > yMatches.Length) 
458
485
                {
459
486
                        // default - word with highest match rating in the list.
460
487
                        hasMismatches = true;
 
488
                        if (partialWord == null)
 
489
                                return -1;
 
490
                        
461
491
                        int idx = -1;
462
 
                        
463
 
                        List<KeyValuePair<int, string>> words = new List<KeyValuePair<int, string>> ();
 
492
                        var matcher = CompletionMatcher.CreateCompletionMatcher (partialWord);
 
493
                        
 
494
                        string bestWord = null;
 
495
                        int bestRank = int.MinValue;
 
496
                        int bestIndex = 0;
 
497
                        
464
498
                        if (!string.IsNullOrEmpty (partialWord)) {
465
499
                                for (int i = 0; i < list.filteredItems.Count; i++) {
466
500
                                        int index = list.filteredItems[i];
467
501
                                        string text = DataProvider.GetCompletionText (index);
468
 
                                        if (!ListWidget.Matches (partialWord, text))
 
502
                                        int rank;
 
503
                                        if (!matcher.CalcMatchRank (text, out rank))
469
504
                                                continue;
470
 
                                        words.Add (new KeyValuePair <int,string> (i, text));
 
505
                                        if (rank > bestRank) {
 
506
                                                bestWord = text;
 
507
                                                bestRank = rank;
 
508
                                                bestIndex = i;
 
509
                                        }
471
510
                                }
472
511
                        }
473
512
                        
474
 
                        ListWindow.WordComparer comparer = new WordComparer (partialWord);
475
 
                        if (words.Count > 0) {
476
 
                                words.Sort (comparer);
477
 
                                idx = words[0].Key;
 
513
                        if (bestWord != null) {
 
514
                                idx = bestIndex;
478
515
                                hasMismatches = false;
479
516
                                // exact match found.
480
 
                                if (words[0].Value.ToUpper () == (partialWord ?? "").ToUpper ()) 
 
517
                                if (string.Compare (bestWord, partialWord ?? "", true) == 0) 
481
518
                                        return idx;
482
519
                        }
483
520
                        
484
521
                        if (string.IsNullOrEmpty (partialWord) || partialWord.Length <= 2) {
485
522
                                // Search for history matches.
486
 
                                for (int i = 0; i < wordHistory.Count; i++) {
487
 
                                        string historyWord = wordHistory[i];
488
 
                                        if (ListWidget.Matches (partialWord, historyWord)) {
489
 
                                                for (int xIndex = 0; xIndex < list.filteredItems.Count; xIndex++) {
490
 
                                                        string currentWord = DataProvider.GetCompletionText (list.filteredItems[xIndex]);
491
 
                                                        if (currentWord == historyWord) {
492
 
                                                                idx = xIndex;
493
 
                                                                break;
494
 
                                                        }
 
523
                                string historyWord;
 
524
                                if (wordHistory.TryGetValue (partialWord, out historyWord)) {
 
525
                                        for (int xIndex = 0; xIndex < list.filteredItems.Count; xIndex++) {
 
526
                                                string currentWord = DataProvider.GetCompletionText (list.filteredItems[xIndex]);
 
527
                                                if (currentWord == historyWord) {
 
528
                                                        idx = xIndex;
 
529
                                                        break;
495
530
                                                }
496
531
                                        }
497
532
                                }
499
534
                        return idx;
500
535
                }
501
536
 
502
 
                static List<string> wordHistory = new List<string> ();
 
537
                static Dictionary<string,string> wordHistory = new Dictionary<string,string> ();
 
538
                static List<string> partalWordHistory = new List<string> ();
503
539
                const int maxHistoryLength = 500;
504
 
                protected void AddWordToHistory (string word)
 
540
                protected void AddWordToHistory (string partialWord, string word)
505
541
                {
506
 
                        if (!wordHistory.Contains (word)) {
507
 
                                wordHistory.Add (word);
508
 
                                while (wordHistory.Count > maxHistoryLength)
509
 
                                        wordHistory.RemoveAt (0);
 
542
                        if (!wordHistory.ContainsKey (partialWord)) {
 
543
                                wordHistory.Add (partialWord, word);
 
544
                                partalWordHistory.Add (partialWord);
 
545
                                while (partalWordHistory.Count > maxHistoryLength) {
 
546
                                        string first = partalWordHistory [0];
 
547
                                        partalWordHistory.RemoveAt (0);
 
548
                                        wordHistory.Remove (first);
 
549
                                }
510
550
                        } else {
511
 
                                wordHistory.Remove (word);
512
 
                                wordHistory.Add (word);
 
551
                                partalWordHistory.Remove (partialWord);
 
552
                                partalWordHistory.Add (partialWord);
 
553
                                wordHistory [partialWord] = word;
513
554
                        }
514
555
                }
515
556
                public static void ClearHistory ()
516
557
                {
517
558
                        wordHistory.Clear ();
 
559
                        partalWordHistory.Clear ();
518
560
                }
519
561
 
520
562
                void SelectEntry (int n)