Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The shortcut key Ctrl+K,Ctrl+D can format all the code. #423

Open
Philorrine opened this issue Mar 7, 2024 · 1 comment
Open

The shortcut key Ctrl+K,Ctrl+D can format all the code. #423

Philorrine opened this issue Mar 7, 2024 · 1 comment

Comments

@Philorrine
Copy link

Philorrine commented Mar 7, 2024

When we use Visual Studio and press Ctrl+K, Ctrl+D, the code will be formatted. And how can we achieve this functionality in avalonedit? And when we press Ctrl+D after Ctrl+K, the line where the cursor is located will be deleted.

@Philorrine Philorrine changed the title The shortcut key Ctrl+K+C can format all the code. The shortcut key Ctrl+K,Ctrl+D can format all the code. Mar 7, 2024
@blakepell
Copy link

blakepell commented Aug 20, 2024

I can answer half the question. I don't think AvalonEdit (or WPF) supports "chords" like Visual Studio out of the box (or if I does I'm unaware). To listen for Chords with AvalonEdit I use this code (you can use this for WPF in general). Here is an example to comment and uncomment code with Ctrl+K Ctrl+C and Ctrl+K Ctrl+U (I've gotten a lot of mileage out of this class).

public class KeyChordGesture : KeyGesture
{
    private readonly Key _key;
    private bool _gotFirstGesture;
    private readonly InputGesture _firstGesture;

    public KeyChordGesture(ModifierKeys modifier, Key firstKey, Key secondKey) : base(Key.None)
    {
        _firstGesture = new KeyGesture(firstKey, modifier);
        _key = secondKey;
    }

    public override bool Matches(object obj, InputEventArgs inputEventArgs)
    {
        var keyArgs = inputEventArgs as KeyEventArgs;

        if (keyArgs == null || keyArgs.IsRepeat)
        {
            return false;
        }

        if (_gotFirstGesture)
        {
            _gotFirstGesture = false;

            if (keyArgs.Key == _key)
            {
                inputEventArgs.Handled = true;
            }

            return keyArgs.Key == _key;
        }

        _gotFirstGesture = _firstGesture.Matches(null, inputEventArgs);

        if (_gotFirstGesture)
        {
            inputEventArgs.Handled = true;
        }

        return false;
    }
}

Then you would setup your key bindings like this (I pass it two relay commands in this example):

// Comment command
Editor.TextArea.InputBindings.Add(new KeyBinding(this.ViewModel.CommentCommand,
    new KeyChordGesture(ModifierKeys.Control, Key.K, Key.C)));

// Uncomment command.
Editor.TextArea.InputBindings.Add(new KeyBinding(this.ViewModel.UncommentCommand,
    new KeyChordGesture(ModifierKeys.Control, Key.K, Key.U)));

Then here is the relay commands those calls (these might need a little work but they mostly work):

/// <summary>
/// Comments out the selected section of code.
/// </summary>
public void Comment()
{
    if (this.Editor.SelectionLength <= 1)
    {
        return;
    }

    var sb = StringBuilderPool.Take();
    var lines = this.Editor.SelectedText.Split('\n');

    foreach (var line in lines)
    {
        string codeLine = line.TrimEnd();

        if (codeLine.StartsWith("//"))
        {
            sb.AppendLine(codeLine);
        }
        else
        {
            sb.Append("//").Append(codeLine).Append("\r\n");
        }
    }

    this.Editor.SelectedText = sb.ToString().TrimEnd('\r', '\n').TrimEnd("//");

    StringBuilderPool.Return(sb);
}

/// <summary>
/// Uncomment out the selected section of code.
/// </summary>
public ICommand UncommentCommand => new RelayCommand(Uncomment);

/// <summary>
/// Uncomment out the selected section of code.
/// </summary>
public void Uncomment()
{
    if (this.Editor.SelectionLength <= 1)
    {
        return;
    }

    var sb = StringBuilderPool.Take();
    var lines = this.Editor.SelectedText.Split('\n');

    foreach (var line in lines)
    {
        string codeLine = line.TrimEnd();

        if (codeLine.StartsWith("//"))
        {
            sb.AppendLine(codeLine.Substring(2));
        }
        else
        {
            sb.Append(codeLine).Append("\r\n");
        }
    }

    this.Editor.SelectedText = sb.ToString().TrimEnd('\r', '\n');

    StringBuilderPool.Return(sb);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants