@@ -181,6 +181,14 @@ pub fn normalize_pasted_path(pasted: &str) -> Option<PathBuf> {
181181 drive || unc
182182 } ;
183183 if looks_like_windows_path {
184+ #[ cfg( target_os = "linux" ) ]
185+ {
186+ if is_probably_wsl ( )
187+ && let Some ( converted) = convert_windows_path_to_wsl ( pasted)
188+ {
189+ return Some ( converted) ;
190+ }
191+ }
184192 return Some ( PathBuf :: from ( pasted) ) ;
185193 }
186194
@@ -193,6 +201,41 @@ pub fn normalize_pasted_path(pasted: &str) -> Option<PathBuf> {
193201 None
194202}
195203
204+ #[ cfg( target_os = "linux" ) ]
205+ fn is_probably_wsl ( ) -> bool {
206+ std:: env:: var_os ( "WSL_DISTRO_NAME" ) . is_some ( )
207+ || std:: env:: var_os ( "WSL_INTEROP" ) . is_some ( )
208+ || std:: env:: var_os ( "WSLENV" ) . is_some ( )
209+ }
210+
211+ #[ cfg( target_os = "linux" ) ]
212+ fn convert_windows_path_to_wsl ( input : & str ) -> Option < PathBuf > {
213+ if input. starts_with ( "\\ \\ " ) {
214+ return None ;
215+ }
216+
217+ let drive_letter = input. chars ( ) . next ( ) ?. to_ascii_lowercase ( ) ;
218+ if !drive_letter. is_ascii_lowercase ( ) {
219+ return None ;
220+ }
221+
222+ if input. get ( 1 ..2 ) != Some ( ":" ) {
223+ return None ;
224+ }
225+
226+ let mut result = PathBuf :: from ( format ! ( "/mnt/{drive_letter}" ) ) ;
227+ for component in input
228+ . get ( 2 ..) ?
229+ . trim_start_matches ( [ '\\' , '/' ] )
230+ . split ( [ '\\' , '/' ] )
231+ . filter ( |component| !component. is_empty ( ) )
232+ {
233+ result. push ( component) ;
234+ }
235+
236+ Some ( result)
237+ }
238+
196239/// Infer an image format for the provided path based on its extension.
197240pub fn pasted_image_format ( path : & Path ) -> EncodedImageFormat {
198241 match path
@@ -210,6 +253,40 @@ pub fn pasted_image_format(path: &Path) -> EncodedImageFormat {
210253#[ cfg( test) ]
211254mod pasted_paths_tests {
212255 use super :: * ;
256+ #[ cfg( target_os = "linux" ) ]
257+ use std:: ffi:: OsString ;
258+
259+ #[ cfg( target_os = "linux" ) ]
260+ struct EnvVarGuard {
261+ key : & ' static str ,
262+ original : Option < OsString > ,
263+ }
264+
265+ #[ cfg( target_os = "linux" ) ]
266+ impl EnvVarGuard {
267+ fn set ( key : & ' static str , value : & str ) -> Self {
268+ let original = std:: env:: var_os ( key) ;
269+ unsafe {
270+ std:: env:: set_var ( key, value) ;
271+ }
272+ Self { key, original }
273+ }
274+ }
275+
276+ #[ cfg( target_os = "linux" ) ]
277+ impl Drop for EnvVarGuard {
278+ fn drop ( & mut self ) {
279+ if let Some ( original) = & self . original {
280+ unsafe {
281+ std:: env:: set_var ( self . key , original) ;
282+ }
283+ } else {
284+ unsafe {
285+ std:: env:: remove_var ( self . key ) ;
286+ }
287+ }
288+ }
289+ }
213290
214291 #[ cfg( not( windows) ) ]
215292 #[ test]
@@ -223,7 +300,17 @@ mod pasted_paths_tests {
223300 fn normalize_file_url_windows ( ) {
224301 let input = r"C:\Temp\example.png" ;
225302 let result = normalize_pasted_path ( input) . expect ( "should parse file URL" ) ;
226- assert_eq ! ( result, PathBuf :: from( r"C:\Temp\example.png" ) ) ;
303+ #[ cfg( target_os = "linux" ) ]
304+ let expected = if is_probably_wsl ( )
305+ && let Some ( converted) = convert_windows_path_to_wsl ( input)
306+ {
307+ converted
308+ } else {
309+ PathBuf :: from ( r"C:\Temp\example.png" )
310+ } ;
311+ #[ cfg( not( target_os = "linux" ) ) ]
312+ let expected = PathBuf :: from ( r"C:\Temp\example.png" ) ;
313+ assert_eq ! ( result, expected) ;
227314 }
228315
229316 #[ test]
@@ -291,10 +378,17 @@ mod pasted_paths_tests {
291378 fn normalize_unquoted_windows_path_with_spaces ( ) {
292379 let input = r"C:\\Users\\Alice\\My Pictures\\example image.png" ;
293380 let result = normalize_pasted_path ( input) . expect ( "should accept unquoted windows path" ) ;
294- assert_eq ! (
295- result,
381+ #[ cfg( target_os = "linux" ) ]
382+ let expected = if is_probably_wsl ( )
383+ && let Some ( converted) = convert_windows_path_to_wsl ( input)
384+ {
385+ converted
386+ } else {
296387 PathBuf :: from ( r"C:\\Users\\Alice\\My Pictures\\example image.png" )
297- ) ;
388+ } ;
389+ #[ cfg( not( target_os = "linux" ) ) ]
390+ let expected = PathBuf :: from ( r"C:\\Users\\Alice\\My Pictures\\example image.png" ) ;
391+ assert_eq ! ( result, expected) ;
298392 }
299393
300394 #[ test]
@@ -322,4 +416,16 @@ mod pasted_paths_tests {
322416 EncodedImageFormat :: Other
323417 ) ;
324418 }
419+
420+ #[ cfg( target_os = "linux" ) ]
421+ #[ test]
422+ fn normalize_windows_path_in_wsl ( ) {
423+ let _guard = EnvVarGuard :: set ( "WSL_DISTRO_NAME" , "Ubuntu-24.04" ) ;
424+ let input = r"C:\\Users\\Alice\\Pictures\\example image.png" ;
425+ let result = normalize_pasted_path ( input) . expect ( "should convert windows path on wsl" ) ;
426+ assert_eq ! (
427+ result,
428+ PathBuf :: from( "/mnt/c/Users/Alice/Pictures/example image.png" )
429+ ) ;
430+ }
325431}
0 commit comments