<commit_before>package org.jetbrains.plugins.scala.editor.typedHandler

import com.intellij.codeInsight.editorActions.TypedHandlerDelegate
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate.Result
import com.intellij.openapi.project.Project
import org.jetbrains.plugins.scala.lang.psi.api.ScalaFile
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.lang.psi.api.base.patterns.ScCaseClause
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.openapi.editor.{Document, Editor}
import org.jetbrains.plugins.scala.lang.scaladoc.lexer.docsyntax.ScaladocSyntaxElementType
import com.intellij.psi.{PsiElement, PsiDocumentManager, PsiWhiteSpace, PsiFile}
import org.jetbrains.plugins.scala.lang.scaladoc.psi.api.ScDocComment
import com.intellij.openapi.fileTypes.FileType
import org.jetbrains.plugins.scala.lang.scaladoc.lexer.ScalaDocTokenType
import org.jetbrains.plugins.scala.extensions
import com.intellij.psi.xml.XmlTokenType
import com.intellij.lexer.XmlLexer
import org.jetbrains.plugins.scala.lang.parser.ScalaElementTypes
import org.jetbrains.plugins.scala.lang.psi.api.expr.xml._


/**
 * @author <NAME>
 * @author <NAME>
 */
class ScalaTypedHandler extends TypedHandlerDelegate {
  override def charTyped(c: Char, project: Project, editor: Editor, file: PsiFile): Result = {
    if (!file.isInstanceOf[ScalaFile]) return Result.CONTINUE

    val offset = editor.getCaretModel.getOffset
    val element = file.findElementAt(offset - 1)
    if (element == null) return Result.CONTINUE

    val document = editor.getDocument
    val text = document.getText
    var myTask: (Document, Project, PsiElement, Int) => Unit = null

    def chooseXmlTask(withAttr: Boolean) {
      c match {
        case '>' => myTask = completeXmlTag(tag => "</" + Option(tag.getTagName).getOrElse("") + ">") _
        case '/' => myTask = completeEmptyXmlTag(editor) _
        case '=' if withAttr => myTask = completeXmlAttributeQuote(editor) _
        case _ =>
      }
    }

    if (isInDocComment(element)) {//we don't have to check offset >= 3 because "/**" is already has 3 characters
      myTask = getScaladocTask(text, offset)
    } else if (c == ' ' && offset >= 6 && offset < text.length && text.substring(offset - 6, offset) == " case ") {
      myTask = indentCase(file)
    } else if (isInPlace(element, classOf[ScXmlExpr], classOf[ScXmlPattern])) {
      chooseXmlTask(true)
    } else if (element.getPrevSibling != null && element.getPrevSibling.getNode.getElementType == ScalaElementTypes.CASE_CLAUSES) {
      val ltIndex = element.getPrevSibling.getText.indexOf("<")
      if (ltIndex > "case ".length - 1 && element.getPrevSibling.getText.substring(0, ltIndex).trim() == "case") {
        chooseXmlTask(false)
      }
    }

    if (myTask == null) return Result.CONTINUE

    extensions.inWriteAction {
      PsiDocumentManager.getInstance(project).commitDocument(document)
    }

    myTask(document, project, file.findElementAt(offset - 1), offset) // prev element is not valid here
    Result.STOP
  }

  override def beforeCharTyped(c: Char, project: Project, editor: Editor, file: PsiFile, fileType: FileType): Result = {
    if (!file.isInstanceOf[ScalaFile]) return Result.CONTINUE

    val offset = editor.getCaretModel.getOffset
    val element = file.findElementAt(offset)
    val prevElement = file.findElementAt(offset - 1)
    if (element == null) return Result.CONTINUE
    val elementType = element.getNode.getElementType

    def moveCaret() {
      editor.getCaretModel.moveCaretRelatively(1, 0, false, false, false)
    }

    if ((c == '"' && elementType == ScalaTokenTypes.tMULTILINE_STRING &&                            // TODO split "if" condition
            element.getTextOffset + element.getTextLength - offset < 4) ||
            isInDocComment(element) && (elementType.isInstanceOf[ScaladocSyntaxElementType] ||
                    elementType == ScalaDocTokenType.DOC_INNER_CLOSE_CODE_TAG) &&
                    element.getParent.getLastChild == element && element.getText.startsWith("" + c) &&
                    !(elementType == ScalaDocTokenType.DOC_ITALIC_TAG && element.getPrevSibling != null
                            && element.getPrevSibling.getNode.getElementType == ScalaDocTokenType.DOC_ITALIC_TAG)) {
      moveCaret()
      return Result.STOP
    } else if (c == '"' && element.getNode.getElementType == XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER) {
      moveCaret()
      return Result.STOP
    } else if ((c == '>' || c == '/') && element.getNode.getElementType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
      moveCaret()
      return Result.STOP
    } else if (c == '>' && element.getNode.getElementType == XmlTokenType.XML_TAG_END) {
      moveCaret()
      return Result.STOP
    } else if (c == '>' && prevElement != null && prevElement.getNode.getElementType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
      return Result.STOP
    } else if (element.getParent != null && element.getParent.isInstanceOf[ScXmlStartTag]) {
      val offsetInName = offset + 2 - (element.getNode.getElementType match {
        case XmlTokenType.XML_NAME => element.getTextOffset
        case XmlTokenType.XML_TAG_END =>
          if (prevElement != null && prevElement.getNode.getElementType == XmlTokenType.XML_NAME) {
            prevElement.getTextOffset
          } else {
            return Result.CONTINUE
          }
        case _ => return Result.CONTINUE
      })

      if (offsetInName >= element.getParent.asInstanceOf[ScXmlStartTag].getTagName.length) {
        return Result.CONTINUE
      }

      val openingTag = element.getParent.asInstanceOf[ScXmlStartTag]
      val closingTag = openingTag.getClosingTag

      if (closingTag.getText.substring(2, closingTag.getTextLength - 1) == openingTag.getTagName) {
        extensions.inWriteAction {
          editor.getDocument.insertString(closingTag.getTextOffset + offsetInName, "" + c)
          PsiDocumentManager.getInstance(file.getProject).commitDocument(editor.getDocument)
        }
      }

      return Result.CONTINUE
    } else if (c == '"' && element.getNode.getElementType != ScalaTokenTypes.tSTRING &&
            prevElement != null && prevElement.getNode.getElementType == ScalaTokenTypes.tSTRING &&
            prevElement.getParent.getText == "\"\"") {
      completeMultilineString(editor, project, element, offset)
    }

    Result.CONTINUE
  }

  private def isInDocComment(element: PsiElement): Boolean = isInPlace(element, classOf[ScDocComment])

  private def isInPlace(element: PsiElement, place : Class[_ <: PsiElement]*): Boolean = {
    if (element == null || place == null) return false

    var nextParent = element.getParent
    while (nextParent != null) {
      if (place.exists(_.isAssignableFrom(nextParent.getClass))) return true
      nextParent = nextParent.getParent
    }
    false
  }<commit_msg>EA-34480 Removed matching xml tags rename on fly feature.<commit_after>package org.jetbrains.plugins.scala.editor.typedHandler

import com.intellij.codeInsight.editorActions.TypedHandlerDelegate
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate.Result
import com.intellij.openapi.project.Project
import org.jetbrains.plugins.scala.lang.psi.api.ScalaFile
import org.jetbrains.plugins.scala.lang.psi.ScalaPsiUtil
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
import org.jetbrains.plugins.scala.lang.psi.api.base.patterns.ScCaseClause
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.openapi.editor.{Document, Editor}
import org.jetbrains.plugins.scala.lang.scaladoc.lexer.docsyntax.ScaladocSyntaxElementType
import com.intellij.psi.{PsiElement, PsiDocumentManager, PsiWhiteSpace, PsiFile}
import org.jetbrains.plugins.scala.lang.scaladoc.psi.api.ScDocComment
import com.intellij.openapi.fileTypes.FileType
import org.jetbrains.plugins.scala.lang.scaladoc.lexer.ScalaDocTokenType
import org.jetbrains.plugins.scala.extensions
import com.intellij.psi.xml.XmlTokenType
import com.intellij.lexer.XmlLexer
import org.jetbrains.plugins.scala.lang.parser.ScalaElementTypes
import org.jetbrains.plugins.scala.lang.psi.api.expr.xml._


/**
 * @author <NAME>
 * @author <NAME>
 */
class ScalaTypedHandler extends TypedHandlerDelegate {
  override def charTyped(c: Char, project: Project, editor: Editor, file: PsiFile): Result = {
    if (!file.isInstanceOf[ScalaFile]) return Result.CONTINUE

    val offset = editor.getCaretModel.getOffset
    val element = file.findElementAt(offset - 1)
    if (element == null) return Result.CONTINUE

    val document = editor.getDocument
    val text = document.getText
    var myTask: (Document, Project, PsiElement, Int) => Unit = null

    def chooseXmlTask(withAttr: Boolean) {
      c match {
        case '>' => myTask = completeXmlTag(tag => "</" + Option(tag.getTagName).getOrElse("") + ">") _
        case '/' => myTask = completeEmptyXmlTag(editor) _
        case '=' if withAttr => myTask = completeXmlAttributeQuote(editor) _
        case _ =>
      }
    }

    if (isInDocComment(element)) {//we don't have to check offset >= 3 because "/**" is already has 3 characters
      myTask = getScaladocTask(text, offset)
    } else if (c == ' ' && offset >= 6 && offset < text.length && text.substring(offset - 6, offset) == " case ") {
      myTask = indentCase(file)
    } else if (isInPlace(element, classOf[ScXmlExpr], classOf[ScXmlPattern])) {
      chooseXmlTask(true)
    } else if (element.getPrevSibling != null && element.getPrevSibling.getNode.getElementType == ScalaElementTypes.CASE_CLAUSES) {
      val ltIndex = element.getPrevSibling.getText.indexOf("<")
      if (ltIndex > "case ".length - 1 && element.getPrevSibling.getText.substring(0, ltIndex).trim() == "case") {
        chooseXmlTask(false)
      }
    }

    if (myTask == null) return Result.CONTINUE

    extensions.inWriteAction {
      PsiDocumentManager.getInstance(project).commitDocument(document)
    }

    myTask(document, project, file.findElementAt(offset - 1), offset) // prev element is not valid here
    Result.STOP
  }

  override def beforeCharTyped(c: Char, project: Project, editor: Editor, file: PsiFile, fileType: FileType): Result = {
    if (!file.isInstanceOf[ScalaFile]) return Result.CONTINUE

    val offset = editor.getCaretModel.getOffset
    val element = file.findElementAt(offset)
    val prevElement = file.findElementAt(offset - 1)
    if (element == null) return Result.CONTINUE
    val elementType = element.getNode.getElementType

    def moveCaret() {
      editor.getCaretModel.moveCaretRelatively(1, 0, false, false, false)
    }

    if ((c == '"' && elementType == ScalaTokenTypes.tMULTILINE_STRING &&                            // TODO split "if" condition
            element.getTextOffset + element.getTextLength - offset < 4) ||
            isInDocComment(element) && (elementType.isInstanceOf[ScaladocSyntaxElementType] ||
                    elementType == ScalaDocTokenType.DOC_INNER_CLOSE_CODE_TAG) &&
                    element.getParent.getLastChild == element && element.getText.startsWith("" + c) &&
                    !(elementType == ScalaDocTokenType.DOC_ITALIC_TAG && element.getPrevSibling != null
                            && element.getPrevSibling.getNode.getElementType == ScalaDocTokenType.DOC_ITALIC_TAG)) {
      moveCaret()
      return Result.STOP
    } else if (c == '"' && element.getNode.getElementType == XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER) {
      moveCaret()
      return Result.STOP
    } else if ((c == '>' || c == '/') && element.getNode.getElementType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
      moveCaret()
      return Result.STOP
    } else if (c == '>' && element.getNode.getElementType == XmlTokenType.XML_TAG_END) {
      moveCaret()
      return Result.STOP
    } else if (c == '>' && prevElement != null && prevElement.getNode.getElementType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
      return Result.STOP
    } else if (c == '"' && element.getNode.getElementType != ScalaTokenTypes.tSTRING &&
            prevElement != null && prevElement.getNode.getElementType == ScalaTokenTypes.tSTRING &&
            prevElement.getParent.getText == "\"\"") {
      completeMultilineString(editor, project, element, offset)
    }

    Result.CONTINUE
  }

  private def isInDocComment(element: PsiElement): Boolean = isInPlace(element, classOf[ScDocComment])

  private def isInPlace(element: PsiElement, place : Class[_ <: PsiElement]*): Boolean = {
    if (element == null || place == null) return false

    var nextParent = element.getParent
    while (nextParent != null) {
      if (place.exists(_.isAssignableFrom(nextParent.getClass))) return true
      nextParent = nextParent.getParent
    }
    false
  }
{'fraction_non_alphanumeric': 0.11598599766627771, 'fraction_numerical': 0.0024893037728510306, 'mean_word_length': 3.544361965358784, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 5}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1118558', 'n_tokens_mistral': 3934, 'n_tokens_neox': 3822, 'n_words': 739}