• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Camelcade / Perl5-IDEA / #525521660

24 Aug 2025 01:28PM UTC coverage: 75.89% (-6.3%) from 82.227%
#525521660

push

github

hurricup
Migrated coverage reporting to https://github.com/nbaztec/coveralls-jacoco-gradle-plugin

See: https://github.com/kt3k/coveralls-gradle-plugin/issues/119

14751 of 22639 branches covered (65.16%)

Branch coverage included in aggregate %.

31091 of 37767 relevant lines covered (82.32%)

0.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.16
/mason/mason2/common/src/main/java/com/perl5/lang/mason2/idea/editor/MasonTypedHandler.java
1
/*
2
 * Copyright 2015-2025 Alexandr Evstigneev
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package com.perl5.lang.mason2.idea.editor;
18

19
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
20
import com.intellij.openapi.editor.Document;
21
import com.intellij.openapi.editor.Editor;
22
import com.intellij.openapi.editor.EditorModificationUtilEx;
23
import com.intellij.openapi.project.Project;
24
import com.intellij.psi.PsiElement;
25
import com.intellij.psi.PsiFile;
26
import com.intellij.psi.tree.IElementType;
27
import com.perl5.lang.mason2.psi.Mason2TemplatingFileViewProvider;
28
import com.perl5.lang.perl.psi.utils.PerlPsiUtil;
29
import org.jetbrains.annotations.NotNull;
30

31
import java.util.Map;
32

33
import static com.intellij.psi.xml.XmlTokenType.XML_DATA_CHARACTERS;
34
import static com.perl5.lang.mason2.Mason2SyntaxElements.*;
35
import static com.perl5.lang.mason2.elementType.Mason2ElementTypes.*;
36
import static com.perl5.lang.perl.parser.PerlElementTypesGenerated.LEFT_BRACE;
37
import static com.perl5.lang.perl.parser.PerlElementTypesGenerated.RIGHT_BRACE;
38

39

40
public class MasonTypedHandler extends TypedHandlerDelegate {
1✔
41
  private static final Map<String, String> SIMPLE_COMPLETION_MAP = Map.of(
1✔
42
    KEYWORD_DOC_OPENER_UNCLOSED, KEYWORD_DOC_CLOSER,
43
    KEYWORD_CLASS_OPENER_UNCLOSED, KEYWORD_CLASS_CLOSER,
44
    KEYWORD_INIT_OPENER_UNCLOSED, KEYWORD_INIT_CLOSER,
45
    KEYWORD_PERL_OPENER_UNCLOSED, KEYWORD_PERL_CLOSER,
46
    KEYWORD_TEXT_OPENER_UNCLOSED, KEYWORD_TEXT_CLOSER);
47

48
  @Override
49
  public @NotNull Result charTyped(char c, final @NotNull Project project, final @NotNull Editor editor, @NotNull PsiFile file) {
50
    if (!(file.getViewProvider() instanceof Mason2TemplatingFileViewProvider)) {
1!
51
      return super.charTyped(c, project, editor, file);
×
52
    }
53
    if (c == '>') {
1✔
54
      handleRightAngle(editor, file);
1✔
55
    }
56
    else if (c == ' ') {
1✔
57
      handleSpace(editor, file);
1✔
58
    }
59
    else if (c == '{') {
1!
60
      handleLeftBrace(editor, file);
1✔
61
    }
62
    return super.charTyped(c, project, editor, file);
1!
63
  }
64

65
  private void handleLeftBrace(@NotNull Editor editor, @NotNull PsiFile file) {
66
    int offset = editor.getCaretModel().getOffset();
1✔
67
    PsiElement element = file.findElementAt(offset - 2);
1✔
68
    if (element == null || element.getNode().getElementType() != LEFT_BRACE) {
1✔
69
      return;
1✔
70
    }
71
    Document document = editor.getDocument();
1✔
72
    int lineNumber = document.getLineNumber(offset - 1);
1✔
73
    PsiElement lineStartElement = file.findElementAt(document.getLineStartOffset(lineNumber));
1✔
74

75
    if (lineStartElement != null && lineStartElement.getNode().getElementType() == MASON_LINE_OPENER) {
1!
76
      PsiElement nextElement = file.findElementAt(offset - 1);
1✔
77
      if (nextElement != null && nextElement.getNode().getElementType() == RIGHT_BRACE) {
1!
78
        EditorModificationUtilEx.insertStringAtCaret(editor, "\n\n% ", false, true, 1);
×
79
      }
80
    }
81
  }
1✔
82

83
  private void handleSpace(@NotNull Editor editor, @NotNull PsiFile file) {
84
    PsiElement element = file.findElementAt(editor.getCaretModel().getOffset() - 2);
1✔
85
    if (element == null) {
1✔
86
      return;
1✔
87
    }
88
    IElementType elementType = element.getNode().getElementType();
1✔
89
    if (elementType == MASON_BLOCK_OPENER && !isNextElement(element, MASON_BLOCK_CLOSER)) {
1!
90
      EditorModificationUtilEx.insertStringAtCaret(editor, KEYWORD_BLOCK_CLOSER, false, false);
1✔
91
    }
92
    else if (elementType == MASON_CALL_OPENER && !isNextElement(element, MASON_CALL_CLOSER)) {
1!
93
      EditorModificationUtilEx.insertStringAtCaret(editor, KEYWORD_CALL_CLOSER, false, false);
1✔
94
    }
95
    else if (elementType == MASON_METHOD_OPENER) {
1✔
96
      EditorModificationUtilEx.insertStringAtCaret(editor, ">\n" + KEYWORD_METHOD_CLOSER, false, false);
1✔
97
    }
98
    else if (elementType == MASON_FILTER_OPENER) {
1✔
99
      EditorModificationUtilEx.insertStringAtCaret(editor, ">\n" + KEYWORD_FILTER_CLOSER, false, false);
1✔
100
    }
101
    else if (elementType == MASON_OVERRIDE_OPENER) {
1✔
102
      EditorModificationUtilEx.insertStringAtCaret(editor, ">\n" + KEYWORD_OVERRIDE_CLOSER, false, false);
1✔
103
    }
104
  }
1✔
105

106
  private void handleRightAngle(@NotNull Editor editor, @NotNull PsiFile file) {
107
    PsiElement element = file.findElementAt(editor.getCaretModel().getOffset() - 2);
1✔
108
    if (element == null || element.getNode().getElementType() != XML_DATA_CHARACTERS) {
1✔
109
      return;
1✔
110
    }
111
    String elementText = element.getText();
1✔
112
    String closeTag;
113
    if ((closeTag = SIMPLE_COMPLETION_MAP.get(elementText)) != null) {
1✔
114
      EditorModificationUtilEx.insertStringAtCaret(editor, closeTag, false, false);
1✔
115
    }
116
    else if (elementText.equals(KEYWORD_FLAGS_OPENER_UNCLOSED)) {
1✔
117
      EditorModificationUtilEx.insertStringAtCaret(editor, " extends => '' " + KEYWORD_FLAGS_CLOSER, false, true, 13);
1✔
118
    }
119
  }
1✔
120

121
  protected boolean isNextElement(PsiElement element, IElementType typeToCheck) {
122
    PsiElement nextElement = PerlPsiUtil.getNextSignificantSibling(element);
1✔
123
    return nextElement != null && nextElement.getNode().getElementType() == typeToCheck;
1!
124
  }
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc