@@ -2,6 +2,45 @@ use crate::database::FileDatabase;
22use anyhow:: { format_err, Result } ;
33use ssh_cfg:: { SshConfig , SshConfigParser , SshHostConfig } ;
44use std:: fmt:: Debug ;
5+ use std:: collections:: HashMap ;
6+ use std:: fs:: read_to_string;
7+ use std:: path:: PathBuf ;
8+
9+ trait ConfigComments {
10+ fn get_comments ( & self ) -> HashMap < String , String > ;
11+ }
12+
13+ impl ConfigComments for SshConfig {
14+ fn get_comments ( & self ) -> HashMap < String , String > {
15+ let mut comments = HashMap :: new ( ) ;
16+
17+ let home = std:: env:: var ( "HOME" ) . unwrap_or_else ( |_| "." . to_string ( ) ) ;
18+ let config_path = PathBuf :: from ( home) . join ( ".ssh" ) . join ( "config" ) ;
19+
20+ if let Ok ( contents) = read_to_string ( config_path) {
21+ let mut current_comment = Vec :: new ( ) ;
22+
23+ for line in contents. lines ( ) {
24+ let trimmed = line. trim ( ) ;
25+
26+ if trimmed. starts_with ( '#' ) {
27+ let comment_text = trimmed[ 1 ..] . trim ( ) . to_string ( ) ;
28+ current_comment. push ( comment_text) ;
29+ } else if trimmed. starts_with ( "Host " ) {
30+ let host = trimmed[ "Host " . len ( ) ..] . trim ( ) . to_string ( ) ;
31+ if !current_comment. is_empty ( ) {
32+ comments. insert ( host, current_comment. join ( "\n " ) ) ;
33+ current_comment. clear ( ) ;
34+ }
35+ } else if trimmed. is_empty ( ) {
36+ current_comment. clear ( ) ;
37+ }
38+ }
39+ }
40+
41+ comments
42+ }
43+ }
544
645#[ derive( Debug ) ]
746pub struct SshGroupItem {
@@ -10,6 +49,7 @@ pub struct SshGroupItem {
1049 pub connection_count : i64 ,
1150 pub last_used : i64 ,
1251 pub host_config : SshHostConfig ,
52+ pub comment : Option < String > ,
1353}
1454
1555#[ derive( Debug ) ]
@@ -28,12 +68,14 @@ impl SshConfigStore {
2868 pub async fn new ( db : & FileDatabase ) -> Result < SshConfigStore > {
2969 let ssh_config = SshConfigParser :: parse_home ( ) . await ?;
3070
71+ let comments = ssh_config. get_comments ( ) ;
72+
3173 let mut scs = SshConfigStore {
3274 config : ssh_config,
3375 groups : Vec :: new ( ) ,
3476 } ;
3577
36- scs. create_ssh_groups ( db) ;
78+ scs. create_ssh_groups ( db, & comments ) ;
3779
3880 if scs. groups . is_empty ( ) {
3981 return Err ( format_err ! ( "Your configuration file contains no entries (or only wildcards) ! Please add at least one." ) ) ;
@@ -42,7 +84,7 @@ impl SshConfigStore {
4284 Ok ( scs)
4385 }
4486
45- fn create_ssh_groups ( & mut self , db : & FileDatabase ) {
87+ fn create_ssh_groups ( & mut self , db : & FileDatabase , comments : & std :: collections :: HashMap < String , String > ) {
4688 let mut groups: Vec < SshGroup > = vec ! [ SshGroup {
4789 name: "Others" . to_string( ) ,
4890 items: Vec :: new( ) ,
@@ -67,6 +109,7 @@ impl SshConfigStore {
67109 last_used : host_entry. last_used_date ,
68110 full_name : key. to_string ( ) ,
69111 host_config : value. clone ( ) ,
112+ comment : comments. get ( key) . cloned ( ) ,
70113 } ;
71114
72115 if group. is_none ( ) {
@@ -90,6 +133,7 @@ impl SshConfigStore {
90133 last_used : host_entry. last_used_date ,
91134 name : key. to_string ( ) ,
92135 host_config : value. clone ( ) ,
136+ comment : comments. get ( key) . cloned ( ) ,
93137 } ) ;
94138 } ) ;
95139
0 commit comments