PsiElement (PyStringLiteralExpression oldExpression, TextRange textRange, String prefix, String suffix, PyExpression formatValue, String newText, List<SubstitutionChunk> substitutions) { // 'foo%s' % value if value is not tuple or mapping -> '%s%s' % (s, value) final PyElementGenerator generator = PyElementGenerator.getInstance(oldExpression.getProject()); final LanguageLevel languageLevel = LanguageLevel.forElement(oldExpression); final String newLiteralText = prefix + "%s" + suffix; final PyStringLiteralExpression newLiteralExpression = generator.createStringLiteralAlreadyEscaped(newLiteralText); oldExpression.replace(newLiteralExpression); final StringBuilder builder = new StringBuilder(); builder.append("("); final int i = getPositionInRanges(substitutionsToRanges(substitutions), textRange); final int pos; if (i == 0) { pos = builder.toString().length(); builder.append(newText); builder.append(","); builder.append(formatValue.getText()); } else { builder.append(formatValue.getText()); builder.append(","); pos = builder.toString().length(); builder.append(newText); } builder.append(")"); final PsiElement newElement = formatValue.replace(generator.createExpressionFromText(languageLevel, builder.toString())); return newElement.findElementAt(pos); }