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

Camelcade / Perl5-IDEA / #525521557

29 May 2025 01:55PM UTC coverage: 82.275% (+0.001%) from 82.274%
#525521557

push

github

hurricup
Migrated to ProjectActivity

0 of 1 new or added line in 1 file covered. (0.0%)

104 existing lines in 12 files now uncovered.

30882 of 37535 relevant lines covered (82.28%)

0.82 hits per line

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

45.33
/plugin/debugger/src/main/java/com/perl5/lang/perl/debugger/ui/PerlScriptsPanel.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.perl.debugger.ui;
18

19
import com.intellij.ide.actions.OpenFileAction;
20
import com.intellij.openapi.application.ApplicationManager;
21
import com.intellij.openapi.project.Project;
22
import com.intellij.openapi.util.text.StringUtil;
23
import com.intellij.openapi.vfs.VfsUtil;
24
import com.intellij.openapi.vfs.VirtualFile;
25
import com.intellij.openapi.vfs.VirtualFileManager;
26
import com.intellij.ui.SimpleListCellRenderer;
27
import com.intellij.ui.SortedListModel;
28
import com.intellij.ui.components.JBList;
29
import com.intellij.ui.components.JBScrollPane;
30
import com.perl5.lang.perl.debugger.PerlDebugThread;
31
import com.perl5.lang.perl.debugger.PerlRemoteFileSystem;
32
import com.perl5.lang.perl.debugger.protocol.PerlLoadedFileDescriptor;
33
import com.perl5.lang.perl.fileTypes.PerlFileTypeScript;
34
import org.jetbrains.annotations.NotNull;
35
import org.jetbrains.annotations.Nullable;
36

37
import javax.swing.*;
38
import java.awt.*;
39
import java.awt.event.MouseAdapter;
40
import java.awt.event.MouseEvent;
41
import java.io.File;
42
import java.util.Arrays;
43
import java.util.Collections;
44
import java.util.Comparator;
45
import java.util.List;
46

47

48
public class PerlScriptsPanel extends JPanel {
49
  private static final Comparator<PerlLoadedFileDescriptor> compareEntries =
1✔
50
    (o1, o2) -> StringUtil.compare(o1.getPresentableName(), o2.getPresentableName(), false);
1✔
51
  private final @NotNull Project myProject;
52
  private final PerlDebugThread myDebugThread;
53
  private final SortedListModel<PerlLoadedFileDescriptor> myModel = SortedListModel.create(compareEntries);
1✔
54

55
  public PerlScriptsPanel(@NotNull Project project, PerlDebugThread debugThread) {
56
    super(new BorderLayout());
1✔
57
    init();
1✔
58
    myProject = project;
1✔
59
    myDebugThread = debugThread;
1✔
60
  }
1✔
61

62

63
  private @Nullable VirtualFile getVirtualFileByName(String virtualFileName) {
64
    VirtualFile result = VfsUtil.findFileByIoFile(new File(virtualFileName), false);
×
65

66
    if (result != null) {
×
67
      return result;
×
68
    }
69

70
    return VirtualFileManager.getInstance().findFileByUrl(PerlRemoteFileSystem.PROTOCOL_PREFIX + virtualFileName);
×
71
  }
72

73
  private void init() {
74
    add(new JBScrollPane(createList()), BorderLayout.CENTER);
1✔
75
  }
1✔
76

77
  private @NotNull JBList<PerlLoadedFileDescriptor> createList() {
78
    final JBList<PerlLoadedFileDescriptor> jbList = new JBList<>(myModel);
1✔
79
    jbList.setCellRenderer(new SimpleListCellRenderer<>() {
1✔
80
      @Override
81
      public void customize(@NotNull JList list, PerlLoadedFileDescriptor fileDescriptor, int index, boolean selected, boolean hasFocus) {
82
        String remotePath = fileDescriptor.getPath();
×
83
        String localPath = myDebugThread.getDebugProfileState().mapPathToLocal(remotePath);
×
UNCOV
84
        VirtualFile virtualFile = getVirtualFileByName(localPath);
×
85

86
        setIcon(PerlFileTypeScript.INSTANCE.getIcon());
×
87
        setText(fileDescriptor.getPresentableName());
×
88

89
        if (virtualFile != null) {
×
UNCOV
90
          setText(fileDescriptor.getPresentableName());
×
UNCOV
91
          setIcon(virtualFile.getFileType().getIcon());
×
92
        }
UNCOV
93
      }
×
94
    });
95
    jbList.addMouseListener(new MouseAdapter() {
1✔
96
      @Override
97
      public void mouseClicked(MouseEvent e) {
98
        if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
×
99
          PerlLoadedFileDescriptor fileDescriptor = jbList.getSelectedValue();
×
100
          String remotePath = fileDescriptor.getPath();
×
UNCOV
101
          String localPath = myDebugThread.getDebugProfileState().mapPathToLocal(remotePath);
×
UNCOV
102
          VirtualFile selectedVirtualFile = getVirtualFileByName(localPath);
×
103
          if (selectedVirtualFile == null) {
×
104
            selectedVirtualFile = myDebugThread.loadRemoteSource(remotePath);
×
105
          }
106

107
          if (selectedVirtualFile != null) {
×
UNCOV
108
            OpenFileAction.openFile(selectedVirtualFile, myProject);
×
109
          }
110
        }
UNCOV
111
      }
×
112
    });
113
    return jbList;
1✔
114
  }
115

116
  public void clear() {
117
    myModel.clear();
1✔
118
  }
1✔
119

120
  public void add(final PerlLoadedFileDescriptor value) {
121
    ApplicationManager.getApplication().invokeLater(() -> {
1✔
122
      if (myModel.indexOf(value) == -1) {
1✔
123
        myModel.add(value);
1✔
124
      }
125
    });
1✔
126
  }
1✔
127

128
  public void remove(final PerlLoadedFileDescriptor value) {
129
    ApplicationManager.getApplication().invokeLater(() -> {
1✔
130
      if (myModel.indexOf(value) != -1) {
1✔
131
        myModel.remove(value);
1✔
132
      }
133
    });
1✔
134
  }
1✔
135

136
  public void bulkChange(final List<? extends PerlLoadedFileDescriptor> toAdd, final List<? extends PerlLoadedFileDescriptor> toRemove) {
137
    // based on synthetic benchmarks, at 5000 items the performance of bulkChangeNow is definitely
138
    // better than the naive method; the exact number might still need some tweaking
139
    if (toAdd.size() + toRemove.size() < 5000) {
1✔
140
      for (PerlLoadedFileDescriptor value : toRemove) {
1✔
141
        remove(value);
1✔
142
      }
1✔
143
      for (PerlLoadedFileDescriptor value : toAdd) {
1✔
144
        add(value);
1✔
145
      }
1✔
146
    }
147
    else {
UNCOV
148
      ApplicationManager.getApplication().invokeLater(() -> bulkChangeNow(toAdd, toRemove));
×
149
    }
150
  }
1✔
151

152
  // so the naive version is good for "small" added/removed; where the exact value needs to be determined with benchmarks;
153
  // there is a slightly more detailed analysis in the commit message
154
  private void bulkChangeNow(final List<? extends PerlLoadedFileDescriptor> toAdd,
155
                             final List<? extends PerlLoadedFileDescriptor> toRemove) {
UNCOV
156
    List<PerlLoadedFileDescriptor> currentEntries = myModel.getItems();
×
157
    if (!toRemove.isEmpty()) {
×
158
      // first find all indices to be removed, then remove them in reverse order by overwriting with
159
      // the last element and then removing the last element
160
      int removeSize = toRemove.size();
×
UNCOV
161
      int[] indices = new int[removeSize];
×
162
      for (int i = 0; i < removeSize; ++i) {
×
163
        indices[i] = Collections.binarySearch(currentEntries, toRemove.get(i), compareEntries);
×
164
      }
165
      Arrays.sort(indices);
×
166
      int lastIndex = currentEntries.size() - 1;
×
167
      for (int i = removeSize - 1; i >= 0; --i) {
×
168
        int index = indices[i];
×
169
        if (index >= 0) {
×
UNCOV
170
          currentEntries.set(index, currentEntries.get(lastIndex));
×
UNCOV
171
          currentEntries.remove(lastIndex);
×
UNCOV
172
          --lastIndex;
×
173
        }
174
      }
175
    }
UNCOV
176
    currentEntries.addAll(toAdd);
×
UNCOV
177
    myModel.setAll(currentEntries);
×
UNCOV
178
  }
×
179
}
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