@@ -2809,73 +2809,57 @@ def add_assistant_reply_to_cur_messages(self):
28092809 )
28102810
28112811 def get_file_mentions (self , content , ignore_current = False ):
2812- # Get file-like words from content (contiguous strings containing slashes or periods )
2812+ # 1. Extract words once: O(N )
28132813 words = set ()
28142814 for word in content .split ():
2815- # Strip quotes and punctuation
28162815 word = word .strip ("\" '`*_,.!;:?" )
28172816 if re .search (r"[\\\/._-]" , word ):
28182817 words .add (word )
28192818
2820- # Also check basenames of file-like words
2821- basename_words = set ()
2822- for word in words :
2823- basename = os .path .basename (word )
2824- if basename and basename != word : # Only add if basename is different
2825- basename_words .add (basename )
2826-
2827- # Combine all words to check
2819+ basename_words = {os .path .basename (w ) for w in words if os .path .basename (w ) != w }
28282820 all_words = words | basename_words
28292821
2830- if ignore_current :
2831- files_to_check = self .get_all_relative_files ()
2832- existing_basenames = set ()
2833- else :
2834- files_to_check = self .get_addable_relative_files ()
2835- # Get basenames of files already in chat or read-only
2822+ # Pre-normalize for O(1) lookups: O(W)
2823+ normalized_words = {w .replace ("\\ " , "/" ) for w in all_words }
2824+
2825+ # 2. Get files and filter ignored once: O(F)
2826+ raw_files = (
2827+ self .get_all_relative_files () if ignore_current else self .get_addable_relative_files ()
2828+ )
2829+
2830+ # Filter ignored files once to avoid repeated expensive calls
2831+ files_to_check = [f for f in raw_files if not (self .repo and self .repo .git_ignored_file (f ))]
2832+
2833+ # 3. Existing basenames setup
2834+ existing_basenames = set ()
2835+
2836+ if not ignore_current :
28362837 existing_basenames = {os .path .basename (f ) for f in self .get_inchat_relative_files ()} | {
28372838 os .path .basename (self .get_rel_fname (f ))
28382839 for f in self .abs_read_only_fnames | self .abs_read_only_stubs_fnames
28392840 }
28402841
2841- # Build map of basenames to files for uniqueness check
2842- # Only consider basenames that look like filenames (contain /, \, ., _, or -)
2843- # to avoid false matches on common words like "run" or "make"
2842+ # 4. Build map: O(F)
28442843 basename_to_files = {}
28452844 for rel_fname in files_to_check :
2846- # Skip git-ignored files
2847- if self .repo and self .repo .git_ignored_file (rel_fname ):
2848- continue
2849-
2850- basename = os .path .basename (rel_fname )
2851- # Only include basenames that look like filenames
2852- if re .search (r"[\\\/._-]" , basename ):
2853- if basename not in basename_to_files :
2854- basename_to_files [basename ] = []
2855- basename_to_files [basename ].append (rel_fname )
2845+ bn = os .path .basename (rel_fname )
2846+ if re .search (r"[\\\/._-]" , bn ):
2847+ basename_to_files .setdefault (bn , []).append (rel_fname )
28562848
2849+ # 5. Final selection: O(F)
28572850 mentioned_rel_fnames = set ()
2858-
28592851 for rel_fname in files_to_check :
2860- # Skip git-ignored files
2861- if self .repo and self .repo .git_ignored_file (rel_fname ):
2862- continue
2863-
2864- # Check if full path matches
2865- normalized_fname = rel_fname .replace ("\\ " , "/" )
2866- normalized_words = {w .replace ("\\ " , "/" ) for w in all_words }
2867-
2868- if normalized_fname in normalized_words :
2852+ # Full path match
2853+ if rel_fname .replace ("\\ " , "/" ) in normalized_words :
28692854 mentioned_rel_fnames .add (rel_fname )
28702855 continue
28712856
2872- # Check basename - only add if unique among addable files and not already in chat
2873- basename = os .path .basename (rel_fname )
2857+ # Basename match logic
2858+ bn = os .path .basename (rel_fname )
28742859 if (
2875- basename in all_words
2876- and basename not in existing_basenames
2877- and len (basename_to_files .get (basename , [])) == 1
2878- and basename_to_files [basename ][0 ] == rel_fname
2860+ bn in all_words
2861+ and bn not in existing_basenames
2862+ and len (basename_to_files .get (bn , [])) == 1
28792863 ):
28802864 mentioned_rel_fnames .add (rel_fname )
28812865
0 commit comments