11using Hypr . Configuration ;
22using Hypr . Services . Terminals ;
33using Microsoft . Extensions . Logging ;
4+ using Microsoft . Extensions . Options ;
45
56namespace Hypr . Services ;
67
@@ -10,13 +11,32 @@ namespace Hypr.Services;
1011/// </summary>
1112public class TerminalService
1213{
14+ private static readonly Dictionary < string , string [ ] > ProviderAliases = new ( StringComparer . OrdinalIgnoreCase )
15+ {
16+ [ "Cursor" ] = [ "cursor" ] ,
17+ [ "Echo" ] = [ "echo" ] ,
18+ [ "GNOME Terminal" ] = [ "gnome" , "gnome-terminal" ] ,
19+ [ "Inplace" ] = [ "inplace" ] ,
20+ [ "iTerm2" ] = [ "iterm" , "iterm2" ] ,
21+ [ "Terminal.app" ] = [ "terminal" , "terminalapp" ] ,
22+ [ "tmux" ] = [ "tmux" ] ,
23+ [ "VS Code" ] = [ "code" , "vscode" ] ,
24+ [ "WezTerm" ] = [ "wez" , "wezterm" ] ,
25+ [ "Windows Terminal" ] = [ "wt" , "windows-terminal" , "windowsterminal" ] ,
26+ } ;
27+
1328 private readonly ILogger < TerminalService > _logger ;
1429 private readonly IEnumerable < ITerminalProvider > _providers ;
30+ private readonly IOptionsMonitor < TerminalConfig > _terminalConfig ;
1531
16- public TerminalService ( ILogger < TerminalService > logger , IEnumerable < ITerminalProvider > providers )
32+ public TerminalService (
33+ ILogger < TerminalService > logger ,
34+ IEnumerable < ITerminalProvider > providers ,
35+ IOptionsMonitor < TerminalConfig > terminalConfig )
1736 {
1837 _logger = logger ;
1938 _providers = providers ;
39+ _terminalConfig = terminalConfig ;
2040 }
2141
2242 /// <summary>
@@ -50,12 +70,71 @@ public bool OpenWorktree(string worktreePath, TerminalMode mode, string? session
5070 /// </summary>
5171 private ITerminalProvider ? SelectProvider ( TerminalMode mode )
5272 {
53- return _providers
73+ var candidates = _providers
5474 . Where ( p => p . SupportsMode ( mode ) && p . IsAvailable )
75+ . ToList ( ) ;
76+
77+ var configuredProgram = _terminalConfig . CurrentValue . Program ;
78+ if ( ! string . IsNullOrWhiteSpace ( configuredProgram ) )
79+ {
80+ var normalizedProgram = NormalizeProgramName ( configuredProgram ) ;
81+ var configuredProvider = candidates . FirstOrDefault ( provider => MatchesConfiguredProgram ( provider , normalizedProgram ) ) ;
82+
83+ if ( configuredProvider == null )
84+ {
85+ _logger . LogWarning (
86+ "Configured terminal program {Program} is not available or does not support mode {Mode}" ,
87+ configuredProgram ,
88+ mode ) ;
89+ }
90+
91+ return configuredProvider ;
92+ }
93+
94+ return candidates
5595 . OrderByDescending ( p => p . Priority )
5696 . FirstOrDefault ( ) ;
5797 }
5898
99+ private static bool MatchesConfiguredProgram ( ITerminalProvider provider , string configuredProgram )
100+ {
101+ if ( string . IsNullOrEmpty ( configuredProgram ) )
102+ {
103+ return false ;
104+ }
105+
106+ return GetProgramIdentifiers ( provider ) . Contains ( configuredProgram , StringComparer . Ordinal ) ;
107+ }
108+
109+ private static IEnumerable < string > GetProgramIdentifiers ( ITerminalProvider provider )
110+ {
111+ var normalizedName = NormalizeProgramName ( provider . Name ) ;
112+ if ( ! string . IsNullOrEmpty ( normalizedName ) )
113+ {
114+ yield return normalizedName ;
115+ }
116+
117+ if ( ProviderAliases . TryGetValue ( provider . Name , out var aliases ) )
118+ {
119+ foreach ( var alias in aliases )
120+ {
121+ var normalizedAlias = NormalizeProgramName ( alias ) ;
122+ if ( ! string . IsNullOrEmpty ( normalizedAlias ) )
123+ {
124+ yield return normalizedAlias ;
125+ }
126+ }
127+ }
128+ }
129+
130+ private static string NormalizeProgramName ( string programName )
131+ {
132+ return new string ( programName
133+ . Where ( char . IsLetterOrDigit )
134+ . Select ( char . ToLowerInvariant )
135+ . ToArray ( ) ) ;
136+ }
137+
59138 /// <summary>
60139 /// Builds the init command from session init and after init scripts.
61140 /// </summary>
0 commit comments