/// <summary> /// Invoked when an unhandled <see cref="E:System.Windows.Input.Keyboard.PreviewKeyDown"/> attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event. /// </summary> /// <param name="e">The <see cref="T:System.Windows.Input.KeyEventArgs"/> that contains the event data.</param> protected override void OnPreviewKeyDown(KeyEventArgs e) { Trace.TraceInformation("Entering popup_PreviewKeyDown:"); Trace.Indent(); //Trace.WriteLine("Event: {0}" + e.RoutedEvent); Trace.WriteLine("Key: " + e.Key); Trace.WriteLine("Index: " + _intellisense.SelectedIndex); Trace.WriteLine("Count: " + _intellisense.Items.Count); //Trace.WriteLine("Source: {0}" + e.Source); _terminalString = string.Empty; switch (e.Key) { case Key.Up: { MovePrevious(); e.Handled = true; Trace.WriteLine("Key.Up: " + _intellisense.SelectedIndex); } break; case Key.Down: { MoveNext(); e.Handled = true; Trace.WriteLine("Key.Dn: " + _intellisense.SelectedIndex); } break; case Key.Space: { _terminalString = " "; e.Handled = true; IsOpen = false; } break; case Key.Back: { // BUGBUG: if you tab back past where TAB was pressed. // this doesn't actually expand the _intellisense! // WORSE: it doesn't update the text on the fly. // Update the filter _tabbing = (_tabbing.Length == 0) ? "" : _tabbing.Substring(0, _tabbing.Length - 1); _lastWord = (_lastWord.Length == 0) ? "" : _lastWord.Substring(0, _lastWord.Length - 1); _intellisense.Items.Filter = TypeAheadFilter; _intellisense.SelectedIndex = 0; e.Handled = true; } break; case Key.Delete: goto case Key.Escape; case Key.Escape: { _intellisense.SelectedIndex = -1; e.Handled = false; IsOpen = false; } break; case Key.Tab: { if (e.IsModifierOn(ModifierKeys.Shift)) { MovePrevious(); } else { MoveNext(); } e.Handled = true; } break; case Key.Enter: { e.Handled = true; IsOpen = false; } break; } Trace.Unindent(); Trace.TraceInformation("Exiting popup_PreviewKeyDown"); base.OnPreviewKeyDown(e); }
private void OnTabPressed(KeyEventArgs e) { Thread.Sleep(0); // CurrentCommand.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); string cmdline = CurrentCommandPreCursor; bool hasMore = CurrentCommandPostCursor.Length > 0; if (!e.IsModifierOn(ModifierKeys.Control) && !hasMore) { var choices = _expansion.GetChoices(CurrentCommand, CurrentCommandCursorPos); Trace.WriteLine((DateTime.Now - _tabTime).TotalMilliseconds); // DO NOT use menu mode if we're in _playbackMode // OTHERWISE, DO USE it if there are more than TabCompleteMenuThreshold items // OR if they double-tapped if ((CurrentCommandPostCursor.Trim('\n', '\r').Length == 0) && ((Settings.Default.TabCompleteMenuThreshold > 0 && choices.CompletionMatches.Count > Settings.Default.TabCompleteMenuThreshold) || ((DateTime.Now - _tabTime).TotalMilliseconds < Settings.Default.TabCompleteDoubleTapMilliseconds))) { var position = _commandBox.PointToScreen( _commandBox.CaretPosition.GetCharacterRect(LogicalDirection.Forward).TopLeft ); var placement = new Rect(position.X, position.Y, Math.Abs(ScrollViewer.ViewportWidth - position.X), Math.Abs(ScrollViewer.ViewportHeight - position.Y)); _popup.ShowTabPopup(placement, choices, CurrentCommand); } else { string tabExpansion = e.IsModifierOn(ModifierKeys.Shift) ? _expansion.Previous(cmdline) : _expansion.Next(cmdline); CurrentCommand = cmdline.Substring(0, cmdline.Length - cmdline.GetLastWord(false).Length) + tabExpansion;// + (hasMore ? CurrentCommandPostCursor : string.Empty); } _tabTime = DateTime.Now; e.Handled = true; } }
private void OnUpPressed(KeyEventArgs e) { if (!e.KeyboardDevice.IsScrollLockToggled() || CurrentCommandLineCountPreCursor == 1) { CurrentCommand = _cmdHistory.Previous(CurrentCommand); if(!e.IsModifierOn(ModifierKeys.Control)) e.Handled = true; } }
// TODO: change this to handle with the Tokenizer private void OnEnterPressed(KeyEventArgs e) { // if they CTRL+ENTER (or SHIFT+ENTER), we just let that pass if (!e.IsModifierOn(ModifierKeys.Control) && !e.IsModifierOn(ModifierKeys.Shift)) { // we expect it to parse as legal script except when we're waiting for input if (!WaitingForInput) { // TODO: Find a way to do this IF v2, and not otherwise. // BUGBUG: Make sure we're handling the exceptions right. var errors = new Collection<PSParseError>(); PSParser.Tokenize(CurrentCommand, out errors); if (errors.Count > 0) { TextRange error; foreach (var err in errors) { // TODO: what is a (locale-safe) test that the error is NOT just "Missing function body in function declaration." because they're still writing it? error = new TextRange( _commandBox.Document.ContentStart.GetPositionAtOffset( err.Token.Start + (2*(err.Token.StartLine - 1)), LogicalDirection.Forward) ?? _commandBox.Document.ContentStart, _commandBox.Document.ContentStart.GetPositionAtOffset( err.Token.Start + (2*(err.Token.EndLine - 1)) + err.Token.Length, LogicalDirection.Backward) ?? _commandBox.Document.ContentEnd); error.ApplyPropertyValue(Inline.TextDecorationsProperty, TextDecorations.Underline); error.ApplyPropertyValue(TextElement.ForegroundProperty, System.Windows.Media.Brushes.Red); // TODO: put in some sort of milder "clunk" sound here, since this isn't necessarily an error... SystemSounds.Exclamation.Play(); } e.Handled = true; return; // out past the normal OnEnterPressed stuff... } } // get the command string cmd = CurrentCommand; // clear the box FlushInputBuffer(); lock (_commandContainer) { // and move the _commandContainer to the "next" paragraph if (Current.Inlines.Contains(_commandContainer)) { Current.Inlines.Remove(_commandContainer); Next = new Paragraph(_commandContainer); Document.Blocks.Add(Next); } } UpdateLayout(); cmd = cmd.TrimEnd(); if (WaitingForInput) { _lastInputString = cmd; _gotInputLine.Set(); Write(cmd + "\n"); } else if (cmd.Length > 0) { OnCommand(new CommandEventArgs {Command = cmd, OutputBlock = Current}); } e.Handled = true; } else { //var indx = _commandBox.CaretPosition.GetOffsetToPosition.CaretIndex; _commandBox.CaretPosition = _commandBox.CaretPosition.InsertLineBreak(); e.Handled = true; } }