faee0d18ab2f1f437bbf7b6ac47c2da58ba0f26b
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / macro / FileDirPathFromParentMacro.java
1 /*
2  * Copyright 2000-2013 JetBrains s.r.o.
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.intellij.ide.macro;
18
19 import com.intellij.ide.IdeBundle;
20 import com.intellij.openapi.actionSystem.DataContext;
21 import com.intellij.openapi.util.SystemInfo;
22 import com.intellij.openapi.util.io.FileUtil;
23 import com.intellij.openapi.util.text.StringUtil;
24 import com.intellij.openapi.vfs.VirtualFile;
25 import org.jetbrains.annotations.NotNull;
26
27 public class FileDirPathFromParentMacro extends Macro {
28
29   private static final String PATH_DELIMITER = "/";
30
31   @Override
32   public String getName() {
33     return "FileDirPathFromParent";
34   }
35
36   @Override
37   public String getDescription() {
38     return IdeBundle.message("macro.file.directory.from.parent");
39   }
40
41   @Override
42   public String expand(DataContext dataContext) {
43     return null;
44   }
45
46   @Override
47   public String expand(DataContext dataContext, String... args) throws ExecutionCancelledException {
48     if(args.length == 0) {
49       return super.expand(dataContext, args);
50     }
51     VirtualFile dir = getVirtualDirOrParent(dataContext);
52     if (dir == null) {
53       return "";
54     }
55     String dirPath = dir.getPath();
56     String surroundedSubDir = surroundWithSlashes(FileUtil.toSystemIndependentName(args[0]));
57     String surroundedDirPath = surroundWithSlashes(dirPath);
58     if (surroundedSubDir.length() == 1) {
59       return surroundedDirPath.substring(1);
60     }
61     int ind = lastIndexOf(surroundedDirPath,
62                           surroundedSubDir,
63                           surroundedDirPath.length(),
64                           !SystemInfo.isFileSystemCaseSensitive);
65     if (ind >= 0) {
66       return surroundedDirPath.substring(ind + surroundedSubDir.length());
67     }
68     return dirPath;
69   }
70
71   private static int lastIndexOf(@NotNull CharSequence buffer, @NotNull String pattern, int maxIndex, boolean ignoreCase) {
72     int patternLength = pattern.length();
73     int end = buffer.length() - patternLength;
74     if (maxIndex > end) {
75       maxIndex = end;
76     }
77     for (int i = maxIndex; i >= 0; i--) {
78       boolean found = true;
79       for (int j = 0; j < patternLength; j++) {
80         if (ignoreCase) {
81           if (StringUtil.charsEqualIgnoreCase(pattern.charAt(j), buffer.charAt(i + j))) {
82             found = false;
83             break;
84           }
85         }
86         else {
87           if (pattern.charAt(j) != buffer.charAt(i + j)) {
88             found = false;
89             break;
90           }
91         }
92       }
93       if (found) {
94         return i;
95       }
96     }
97     return -1;
98   }
99
100   @NotNull
101   private static String surroundWithSlashes(@NotNull String path) {
102     if (path.isEmpty()) {
103       return PATH_DELIMITER;
104     }
105     boolean prepend = !path.startsWith(PATH_DELIMITER);
106     boolean append = !path.endsWith(PATH_DELIMITER);
107     if (prepend && append) {
108       return PATH_DELIMITER + path + PATH_DELIMITER;
109     }
110     if (prepend) {
111       path = PATH_DELIMITER + path;
112     }
113     if (append) {
114       path += PATH_DELIMITER;
115     }
116     return path;
117   }
118 }