@@ -598,90 +598,97 @@ async function run(
598598 function getRelativePath ( ) {
599599 // Get the project url
600600 const projectFolder = addedFolder [ 0 ] ;
601-
602- // Set the root folder to the file parent if no project folder is set
601+
602+ // FIXED: Better root folder determination for Termux URIs
603603 let rootFolder = pathName ;
604- if ( projectFolder !== undefined && pathName . includes ( projectFolder ) ) {
604+
605+ // Special handling for Termux URIs - extract the actual root from the URI structure
606+ if ( activeFile && activeFile . uri && activeFile . uri . includes ( "com.termux.documents" ) && activeFile . uri . includes ( "tree/" ) ) {
607+ // Extract the tree part and decode it to get the actual root path
608+ const treeMatch = activeFile . uri . match ( / t r e e \/ ( [ ^ : ] + ) / ) ;
609+ if ( treeMatch ) {
610+ try {
611+ const decodedRoot = decodeURIComponent ( treeMatch [ 1 ] ) ;
612+ rootFolder = decodedRoot ;
613+ console . log ( `DEBUG - Termux root folder set to: ${ rootFolder } ` ) ;
614+ } catch ( e ) {
615+ console . error ( "Error decoding Termux root:" , e ) ;
616+ }
617+ }
618+ } else if ( projectFolder !== undefined && pathName && pathName . includes ( projectFolder . url ) ) {
605619 rootFolder = projectFolder . url ;
606- } else {
607- rootFolder = pathName ;
608620 }
609-
621+
610622 //make the uri absolute if necessary
611623 rootFolder = makeUriAbsoluteIfNeeded ( rootFolder ) ;
612-
624+
613625 // Parent of the file
614626 let filePath = pathName ;
615-
627+
616628 if ( rootFolder . startsWith ( "ftp:" ) || rootFolder . startsWith ( "sftp:" ) ) {
617629 if ( rootFolder . includes ( "?" ) ) {
618630 rootFolder = rootFolder . split ( "?" ) [ 0 ] ;
619631 }
620632 }
621-
633+
622634 //remove the query string if present this is needs to be removed because the url is not valid
623635 if ( filePath . startsWith ( "ftp:" ) || rootFolder . startsWith ( "sftp:" ) ) {
624636 if ( filePath . includes ( "?" ) ) {
625637 filePath = filePath . split ( "?" ) [ 0 ] ;
626638 }
627639 }
628-
640+
629641 // Create full file path
630642 let temp = Url . join ( filePath , filename ) ;
631-
643+
632644 // Special handling for Termux URIs
633645 if ( temp . includes ( "com.termux.documents" ) && temp . includes ( "::" ) ) {
634646 try {
635647 const [ , realPath ] = temp . split ( "::" ) ;
636-
637- // Determine root folder inside :: path
638- let rootPath = rootFolder ;
639- if ( rootFolder . includes ( "::" ) ) {
640- rootPath = rootFolder . split ( "::" ) [ 1 ] ;
641- }
642-
643- // Normalize both paths to arrays
644- const realParts = realPath . split ( "/" ) . filter ( Boolean ) ;
645- const rootParts = rootPath . split ( "/" ) . filter ( Boolean ) ;
646-
647- // Find where the paths start to differ
648- let diffIndex = 0 ;
649- while (
650- diffIndex < realParts . length &&
651- diffIndex < rootParts . length &&
652- realParts [ diffIndex ] === rootParts [ diffIndex ]
653- ) {
654- diffIndex ++ ;
655- }
656-
657- // Return everything after the common root
658- const relativeParts = realParts . slice ( diffIndex ) ;
659- if ( relativeParts . length > 0 ) {
660- return relativeParts . join ( "/" ) ;
648+
649+ console . log ( `DEBUG - realPath: ${ realPath } ` ) ;
650+ console . log ( `DEBUG - rootFolder: ${ rootFolder } ` ) ;
651+
652+ // Ensure rootFolder doesn't have trailing slash for comparison
653+ const normalizedRoot = rootFolder . replace ( / \/ + $ / , "" ) ;
654+
655+ // Check if realPath starts with rootFolder
656+ if ( realPath . startsWith ( normalizedRoot ) ) {
657+ // Remove the rootFolder from the beginning of realPath
658+ let relativePath = realPath . substring ( normalizedRoot . length ) ;
659+
660+ // Remove leading slash if present
661+ relativePath = relativePath . replace ( / ^ \/ + / , "" ) ;
662+
663+ console . log ( `DEBUG - relativePath: ${ relativePath } ` ) ;
664+
665+ if ( relativePath ) {
666+ return relativePath ;
667+ }
661668 }
662669 } catch ( e ) {
663670 console . error ( "Error handling Termux URI:" , e ) ;
664671 }
665672 }
666-
673+
667674 // Handle other content:// URIs
668675 if ( temp . includes ( "content://" ) && temp . includes ( "::" ) ) {
669676 try {
670677 // Get the part after :: which contains the actual file path
671678 const afterDoubleColon = temp . split ( "::" ) [ 1 ] ;
672-
679+
673680 if ( afterDoubleColon ) {
674681 // Extract the rootFolder's content path if it has ::
675682 let rootFolderPath = rootFolder ;
676683 if ( rootFolder . includes ( "::" ) ) {
677684 rootFolderPath = rootFolder . split ( "::" ) [ 1 ] ;
678685 }
679-
686+
680687 // If rootFolder doesn't have ::, try to extract the last part of the path
681688 if ( ! rootFolderPath . includes ( "::" ) ) {
682689 const rootParts = rootFolder . split ( "/" ) ;
683690 const lastPart = rootParts [ rootParts . length - 1 ] ;
684-
691+
685692 // Check if the lastPart is encoded
686693 if ( lastPart . includes ( "%3A" ) ) {
687694 // Try to decode it
@@ -696,42 +703,31 @@ async function run(
696703 rootFolderPath = lastPart ;
697704 }
698705 }
699-
700- // Now find this rootFolderPath in the afterDoubleColon string
701- if ( afterDoubleColon . includes ( rootFolderPath ) ) {
702- // Find where to start the relative path
703- const parts = afterDoubleColon . split ( "/" ) ;
704-
705- // Find the index of the part that matches or contains rootFolderPath
706- let startIndex = - 1 ;
707- for ( let i = 0 ; i < parts . length ; i ++ ) {
708- if (
709- parts [ i ] . includes ( rootFolderPath ) ||
710- rootFolderPath . includes ( parts [ i ] )
711- ) {
712- startIndex = i ;
713- break ;
714- }
715- }
716-
717- // If we found a matching part, get everything after it
718- if ( startIndex >= 0 && startIndex < parts . length - 1 ) {
719- return parts . slice ( startIndex + 1 ) . join ( "/" ) ;
706+
707+ // Use direct string replacement instead of path component comparison
708+ const normalizedRoot = rootFolderPath . replace ( / \/ + $ / , "" ) ;
709+ if ( afterDoubleColon . startsWith ( normalizedRoot ) ) {
710+ let relativePath = afterDoubleColon . substring ( normalizedRoot . length ) ;
711+ // Remove leading slash if present
712+ relativePath = relativePath . replace ( / ^ \/ + / , "" ) ;
713+
714+ if ( relativePath ) {
715+ return relativePath ;
720716 }
721717 }
722718 }
723719 } catch ( e ) {
724720 console . error ( "Error parsing content URI:" , e ) ;
725721 }
726722 }
727-
723+
728724 // For regular paths or if content:// URI parsing failed
729725 // Try to find a common prefix between rootFolder and temp
730726 // and remove it from temp
731727 try {
732728 const rootParts = rootFolder . split ( "/" ) ;
733729 const tempParts = temp . split ( "/" ) ;
734-
730+
735731 let commonIndex = 0 ;
736732 for ( let i = 0 ; i < Math . min ( rootParts . length , tempParts . length ) ; i ++ ) {
737733 if ( rootParts [ i ] === tempParts [ i ] ) {
@@ -740,19 +736,19 @@ async function run(
740736 break ;
741737 }
742738 }
743-
739+
744740 if ( commonIndex > 0 ) {
745741 return tempParts . slice ( commonIndex ) . join ( "/" ) ;
746742 }
747743 } catch ( e ) {
748744 console . error ( "Error finding common path:" , e ) ;
749745 }
750-
746+
751747 // If all else fails, just return the filename
752748 if ( filename ) {
753749 return filename ;
754750 }
755-
751+
756752 console . log ( "Unable to determine relative path, returning full path" ) ;
757753 return temp ;
758754 }
@@ -761,6 +757,7 @@ async function run(
761757 * Opens the preview in browser
762758 */
763759 function openBrowser ( ) {
760+ console . log ( `Running ${ Url . join ( pathName , filename ) } ` )
764761 let url = "" ;
765762 if ( pathName === null && ! activeFile . location ) {
766763 url = `http://localhost:${ port } /__unsaved_file__` ;
0 commit comments