@@ -10,14 +10,31 @@ mod url_processor;
1010
1111use crate :: analyzer:: process_directory;
1212use crate :: cli:: Cli ;
13- use crate :: config:: { get_config_path, load_config} ;
13+ use crate :: config:: { get_config_path, load_config, load_repo_config , save_repo_config , RepoConfig } ;
1414use crate :: git_processor:: GitProcessor ;
1515use crate :: url_processor:: UrlProcessor ;
1616use std:: fs;
17+ use std:: io:: { self , Write } ;
18+ use std:: path:: { Path , PathBuf } ;
19+
20+ fn is_url_or_git ( path : & str ) -> bool {
21+ GitProcessor :: is_git_url ( path) || path. starts_with ( "http://" ) || path. starts_with ( "https://" )
22+ }
23+
24+ fn has_custom_options ( args : & Cli ) -> bool {
25+ args. include . is_some ( )
26+ || args. exclude . is_some ( )
27+ || args. max_size . is_some ( )
28+ || args. max_depth . is_some ( )
29+ || args. output . is_some ( )
30+ || args. file . is_some ( )
31+ || args. hidden
32+ || args. no_ignore
33+ }
1734
1835fn main ( ) -> anyhow:: Result < ( ) > {
1936 let config = load_config ( ) ?;
20- let args = Cli :: parse_with_config ( & config) ?;
37+ let mut args = Cli :: parse_with_config ( & config) ?;
2138
2239 if args. config_path {
2340 let path = get_config_path ( ) ?;
@@ -28,14 +45,38 @@ fn main() -> anyhow::Result<()> {
2845 let url_paths: Vec < _ > = args
2946 . paths
3047 . iter ( )
31- . filter ( |path| {
32- GitProcessor :: is_git_url ( path)
33- || path. starts_with ( "http://" )
34- || path. starts_with ( "https://" )
35- } )
48+ . filter ( |path| is_url_or_git ( path) )
3649 . take ( 1 )
50+ . cloned ( )
3751 . collect ( ) ;
3852
53+ if url_paths. is_empty ( ) && !args. paths . is_empty ( ) {
54+ let base_path = PathBuf :: from ( & args. paths [ 0 ] ) ;
55+ let root_dir = find_containing_dir_with_glimpse ( & base_path) ?;
56+ let glimpse_file = root_dir. join ( ".glimpse" ) ;
57+
58+ if args. config {
59+ let repo_config = create_repo_config_from_args ( & args) ;
60+ save_repo_config ( & glimpse_file, & repo_config) ?;
61+ println ! ( "Configuration saved to {}" , glimpse_file. display( ) ) ;
62+ } else if glimpse_file. exists ( ) {
63+ println ! ( "Loading configuration from {}" , glimpse_file. display( ) ) ;
64+ let repo_config = load_repo_config ( & glimpse_file) ?;
65+ apply_repo_config ( & mut args, & repo_config) ;
66+ } else if has_custom_options ( & args) {
67+ print ! ( "Would you like to save these options as defaults for this directory? (y/n): " ) ;
68+ io:: stdout ( ) . flush ( ) ?;
69+ let mut response = String :: new ( ) ;
70+ io:: stdin ( ) . read_line ( & mut response) ?;
71+
72+ if response. trim ( ) . to_lowercase ( ) == "y" {
73+ let repo_config = create_repo_config_from_args ( & args) ;
74+ save_repo_config ( & glimpse_file, & repo_config) ?;
75+ println ! ( "Configuration saved to {}" , glimpse_file. display( ) ) ;
76+ }
77+ }
78+ }
79+
3980 if url_paths. len ( ) > 1 {
4081 return Err ( anyhow:: anyhow!(
4182 "Only one URL or git repository can be processed at a time"
@@ -88,8 +129,19 @@ fn main() -> anyhow::Result<()> {
88129
89130 if let Some ( output_file) = & args. file {
90131 fs:: write ( output_file, content) ?;
132+ println ! ( "Output written to: {}" , output_file. display( ) ) ;
91133 } else if args. print {
92134 println ! ( "{}" , content) ;
135+ } else {
136+ // Default behavior for URLs if no -f or --print: copy to clipboard
137+ match arboard:: Clipboard :: new ( )
138+ . and_then ( |mut clipboard| clipboard. set_text ( content) )
139+ {
140+ Ok ( _) => println ! ( "URL content copied to clipboard" ) ,
141+ Err ( _) => {
142+ println ! ( "Failed to copy to clipboard, use -f to save to a file instead" )
143+ }
144+ }
93145 }
94146 }
95147 } else {
@@ -99,3 +151,76 @@ fn main() -> anyhow::Result<()> {
99151
100152 Ok ( ( ) )
101153}
154+
155+ fn find_containing_dir_with_glimpse ( path : & Path ) -> anyhow:: Result < PathBuf > {
156+ let mut current = if path. is_file ( ) {
157+ path. parent ( ) . unwrap_or ( Path :: new ( "." ) ) . to_path_buf ( )
158+ } else {
159+ path. to_path_buf ( )
160+ } ;
161+
162+ // Try to find a .glimpse file or go up until we reach the root
163+ loop {
164+ if current. join ( ".glimpse" ) . exists ( ) {
165+ return Ok ( current) ;
166+ }
167+
168+ if !current. pop ( ) {
169+ // If we can't go up anymore, just use the original path
170+ return Ok ( if path. is_file ( ) {
171+ path. parent ( ) . unwrap_or ( Path :: new ( "." ) ) . to_path_buf ( )
172+ } else {
173+ path. to_path_buf ( )
174+ } ) ;
175+ }
176+ }
177+ }
178+
179+ fn create_repo_config_from_args ( args : & Cli ) -> RepoConfig {
180+ use crate :: config:: BackwardsCompatOutputFormat ;
181+
182+ RepoConfig {
183+ include : args. include . clone ( ) ,
184+ exclude : args. exclude . clone ( ) ,
185+ max_size : args. max_size ,
186+ max_depth : args. max_depth ,
187+ output : args. output . clone ( ) . map ( BackwardsCompatOutputFormat :: from) ,
188+ file : args. file . clone ( ) ,
189+ hidden : Some ( args. hidden ) ,
190+ no_ignore : Some ( args. no_ignore ) ,
191+ }
192+ }
193+
194+ fn apply_repo_config ( args : & mut Cli , repo_config : & RepoConfig ) {
195+ if let Some ( ref include) = repo_config. include {
196+ args. include = Some ( include. clone ( ) ) ;
197+ }
198+
199+ if let Some ( ref exclude) = repo_config. exclude {
200+ args. exclude = Some ( exclude. clone ( ) ) ;
201+ }
202+
203+ if let Some ( max_size) = repo_config. max_size {
204+ args. max_size = Some ( max_size) ;
205+ }
206+
207+ if let Some ( max_depth) = repo_config. max_depth {
208+ args. max_depth = Some ( max_depth) ;
209+ }
210+
211+ if let Some ( ref output) = repo_config. output {
212+ args. output = Some ( ( * output) . clone ( ) . into ( ) ) ;
213+ }
214+
215+ if let Some ( ref file) = repo_config. file {
216+ args. file = Some ( file. clone ( ) ) ;
217+ }
218+
219+ if let Some ( hidden) = repo_config. hidden {
220+ args. hidden = hidden;
221+ }
222+
223+ if let Some ( no_ignore) = repo_config. no_ignore {
224+ args. no_ignore = no_ignore;
225+ }
226+ }
0 commit comments