* Added new command wrapper, abstracts static and dynamic commands - All uses of the `Command` are replaced with either `AppCommand`, for a command that is static to the scope of the application, or a reference to an ICommand (specifically, an `EnumCommand<AppCommand>()` instance), which provides the abstract wrapper. - Functionality seems intact. - Next step is to have the MainViewModel add the per-shell commands via SettingsService.CreateShellKeyboardShortcuts(), and have the SettingsService.ParseCommandString() function parse the command strings passed around properly. - Finally, add the keyboard chord input to each shell's settings page. * First kick at adding a new terminal keyboard command. - It isn't presented anywhere, but references to keybindings should be using the ICommand key as their identifier for recognizing anything, and when xterm passes back a keyboard command event, the SettingsService is asked to convert the string into an ICommand. * Renaming ICommand to Command. It's not longer an interface, so this makes more sense. * Renaming back to Command, and new class is AbstractCommand. Going to simplify the PR diff considerably. * Shortcuts for default shells work. Need to get the shell profile edit UI elements working. * Added keyboard shortcut UI elements to shell profile pages. * New and deleted shell profiles propagate to all terminal views. * A bit of cleanup. * Camel-casing command text to fix Ctrl+C and copy behaviour. * Fixed failing test. The new on disk store uses a .ToString(), not the Enum description, since the command isn't an Enum, it's a class now in general, and those semantics make more sense. * Adding default value for null keybindings in shell profiles. * Merge branch 'shell_commands' of https://github.com/Riebart/FluentTerminal into pr/85 Improved default value for keybinding property * Renamed KeyBinding collection to KeyBindings * Use strings as Command parameter of KeyBinding * Added missing Commands to keyBindings of default shellProfiles * fix build and unit tests after merge with master * improve UI * Split OnShellProfileCollectionChanged event
130 lines
4.3 KiB
C#
130 lines
4.3 KiB
C#
using FluentTerminal.Models;
|
|
using FluentTerminal.Models.Enums;
|
|
using FluentTerminal.Models.Requests;
|
|
using FluentTerminal.Models.Responses;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace FluentTerminal.App.Services.Implementation
|
|
{
|
|
public class TrayProcessCommunicationService : ITrayProcessCommunicationService
|
|
{
|
|
private readonly ISettingsService _settingsService;
|
|
private IAppServiceConnection _appServiceConnection;
|
|
private Dictionary<int, Action<string>> _terminalOutputHandlers;
|
|
|
|
public event EventHandler<int> TerminalExited;
|
|
|
|
public TrayProcessCommunicationService(ISettingsService settingsService)
|
|
{
|
|
_settingsService = settingsService;
|
|
_terminalOutputHandlers = new Dictionary<int, Action<string>>();
|
|
}
|
|
|
|
public async Task<CreateTerminalResponse> CreateTerminal(TerminalSize size, ShellProfile shellProfile)
|
|
{
|
|
var request = new CreateTerminalRequest
|
|
{
|
|
Size = size,
|
|
Profile = shellProfile
|
|
};
|
|
|
|
var responseMessage = await _appServiceConnection.SendMessageAsync(CreateMessage(request));
|
|
|
|
return JsonConvert.DeserializeObject<CreateTerminalResponse>(responseMessage[MessageKeys.Content]);
|
|
}
|
|
|
|
public void Initialize(IAppServiceConnection appServiceConnection)
|
|
{
|
|
_appServiceConnection = appServiceConnection;
|
|
_appServiceConnection.MessageReceived += OnMessageReceived;
|
|
}
|
|
|
|
private void OnMessageReceived(object sender, IDictionary<string, string> e)
|
|
{
|
|
var messageType = e[MessageKeys.Type];
|
|
var messageContent = e[MessageKeys.Content];
|
|
|
|
if (messageType == nameof(DisplayTerminalOutputRequest))
|
|
{
|
|
var request = JsonConvert.DeserializeObject<DisplayTerminalOutputRequest>(messageContent);
|
|
|
|
if (_terminalOutputHandlers.ContainsKey(request.TerminalId))
|
|
{
|
|
_terminalOutputHandlers[request.TerminalId].Invoke(request.Output);
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine("output was not handled: " + request.Output);
|
|
}
|
|
}
|
|
else if (messageType == nameof(TerminalExitedRequest))
|
|
{
|
|
var request = JsonConvert.DeserializeObject<TerminalExitedRequest>(messageContent);
|
|
|
|
TerminalExited?.Invoke(this, request.TerminalId);
|
|
}
|
|
}
|
|
|
|
public Task ResizeTerminal(int id, TerminalSize size)
|
|
{
|
|
var request = new ResizeTerminalRequest
|
|
{
|
|
TerminalId = id,
|
|
NewSize = size
|
|
};
|
|
|
|
return _appServiceConnection.SendMessageAsync(CreateMessage(request));
|
|
}
|
|
|
|
public void SubscribeForTerminalOutput(int terminalId, Action<string> callback)
|
|
{
|
|
_terminalOutputHandlers[terminalId] = callback;
|
|
}
|
|
|
|
public Task UpdateToggleWindowKeyBindings()
|
|
{
|
|
var keyBindings = _settingsService.GetCommandKeyBindings()[nameof(Command.ToggleWindow)];
|
|
|
|
var request = new SetToggleWindowKeyBindingsRequest
|
|
{
|
|
KeyBindings = keyBindings
|
|
};
|
|
|
|
return _appServiceConnection.SendMessageAsync(CreateMessage(request));
|
|
}
|
|
|
|
public Task WriteText(int id, string text)
|
|
{
|
|
var request = new WriteTextRequest
|
|
{
|
|
TerminalId = id,
|
|
Text = text
|
|
};
|
|
|
|
return _appServiceConnection.SendMessageAsync(CreateMessage(request));
|
|
}
|
|
|
|
public Task CloseTerminal(int terminalId)
|
|
{
|
|
var request = new TerminalExitedRequest
|
|
{
|
|
TerminalId = terminalId
|
|
};
|
|
|
|
return _appServiceConnection.SendMessageAsync(CreateMessage(request));
|
|
}
|
|
|
|
private IDictionary<string, string> CreateMessage(object content)
|
|
{
|
|
return new Dictionary<string, string>
|
|
{
|
|
[MessageKeys.Type] = content.GetType().Name,
|
|
[MessageKeys.Content] = JsonConvert.SerializeObject(content)
|
|
};
|
|
}
|
|
}
|
|
} |