@@ -209,6 +209,26 @@ function PythonTreeSitterCommands.ts_wrap_at_cursor(subtitute_option)
209209 end )
210210end
211211
212+ ---
213+ --- @param node TSNode the current ts node we are checking for parents
214+ --- @return string callText check if this node has a " call" type node 3 parents up
215+ --- this is used for checking on "".format() calls for strings.
216+ local function checkForFStringCallParent (node )
217+ local callStatus , callText = pcall (function ()
218+ local callNode = node :parent ():parent ():parent ()
219+ if callNode then
220+ local text = getNodeText (callNode )
221+ return text
222+ end
223+ return " "
224+ end ) -- Get potential function call on string for .format()
225+
226+ if not callStatus then
227+ callText = " "
228+ end
229+ return callText
230+ end
231+
212232function PythonTreeSitterCommands .pythonFStr ()
213233 local maxCharacters = 200 -- safeguard to prevent converting invalid code
214234 local node = getNodeAtCursor ()
@@ -217,6 +237,8 @@ function PythonTreeSitterCommands.pythonFStr()
217237 end
218238
219239 local strNode
240+ local callText = checkForFStringCallParent (node )
241+
220242 if node :type () == " string" then
221243 strNode = node
222244 elseif node :type ():find (" ^string_" ) then
@@ -239,10 +261,12 @@ function PythonTreeSitterCommands.pythonFStr()
239261 return
240262 end -- safeguard on converting invalid code
241263
242- local isFString = text :find (" ^r?f" ) -- rf -> raw-formatted-string
264+ local isFormatString = callText :find ([[ ^.*["']%.format%(]] )
265+ local isRString = text :find (" ^r" )
266+ local isFString = text :find (" ^r?f" ) -- rf -> raw-formatted-string
243267 local hasBraces = text :find (" {.-[^%d,%s].-}" ) -- nonRegex-braces, see #12 and #15
244268
245- if not isFString and hasBraces then
269+ if ( not isFString and not isFormatString and not isRString ) and hasBraces then
246270 text = " f" .. text
247271 replaceNodeText (strNode , text )
248272 elseif isFString and not hasBraces then
0 commit comments