Я добился этого в два этапа:
1) Добавить пользовательское правило сборки для .metal
файлов, которое индивидуально компилирует их в .metallib
с:
2) Добавьте пользовательский шаг сборки для копирования этих .metallib
в цель:
As far as I know, this can't be done. Here's why:
First, you have to search across lines. No problem, in vim adding a _ to a character class tells it to include new lines. so {_.*} would match everything between those brackets across multiple lines.
So now you need to match whatever the pattern is for a function header(brittle even if you get it to work), then , and here's the problem, whatever lines are between it and your search string, and finally match your search string. So you might have a regex like
/^\(void \+\a\+ *(.*)\)\_.*JOHN_DOE
But what happens is the first time vim finds a function header, it starts matching. It then matches every character until it finds JOHN_DOE. Which includes all the function headers in the file.
So the problem is that, as far as I know, there's no way to tell vim to match every character except for this regex pattern. And even if there was, a regex is not the tool for this job. It's like opening a beer with a hammer. What we should do is write a simple script that gives you this info, and I have.
fun! FindMyFunction(searchPattern, funcPattern)
call search(a:searchPattern)
let lineNumber = line(".")
let lineNumber = lineNumber - 1
"call setpos(".", [0, lineNumber, 0, 0])
let lineString = getline(lineNumber)
while lineString !~ a:funcPattern
let lineNumber = lineNumber - 1
if lineNumber < 0
echo "Function not found :/"
endif
let lineString = getline(lineNumber)
endwhile
echo lineString
endfunction
That should give you the result you want and it's way easier to share, debug, and repurpose than a regular expression spit from the mouth of Cthulhu himself.
Вероятно, за это меня проголосуют!
Я заядлый (G) пользователь VIM, но когда я хочу просмотреть или понять какой-то код, я использую Source Insight . Я почти никогда не использую его как настоящий редактор.
В этом случае он делает именно то, что вам нужно, например, показывает все функции / методы, которые используют какой-то выделенный тип данных / define / constant / etc ... в окне отношений ...
(источник: sourceinsight.com )
Ой! Вот мой представитель.
Tough call, although as a starting point I would suggest this wonderful VIM Regex Tutorial.
You cannot do that reliably with a regular expression, because code is not a regular language. You need a real parser for the language in question.
Для такого рода вещей, хотя это снова касается примитивного поиска, я бы порекомендовал плагин compview . Откроется окно поиска, так что вы сможете увидеть всю строку, где произошел поиск, и автоматически перейти к ней. Дает хороший обзор.
(источник: axisym3.net )
Как сказал Роберт, Регекс поможет. В командном режиме запустите поиск по регулярному выражению, введя символ "/", а затем свое регулярное выражение.
Ctags 1 также могут быть вам полезны. Он может генерировать файл тегов для проекта. Этот файл тегов позволяет пользователю переходить непосредственно от вызова функции к его определению, даже если он находится в другом файле с помощью «CTRL +]».
вы можете использовать grep -r -n -H JOHN_DOE *
он будет искать «JOHN_DOE» в файлах, рекурсивно начиная с текущего каталога
, который вы можете использовать следующий код, чтобы практически найти функцию, которая содержит текстовое выражение:
public void findFunction(File file, String expression) {
Reader r = null;
try {
r = new FileReader(file);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
BufferedReader br = new BufferedReader(r);
String match = "";
String lineWithNameOfFunction = "";
Boolean matchFound = false;
try {
while(br.read() > 0) {
match = br.readLine();
if((match.endsWith(") {")) ||
(match.endsWith("){")) ||
(match.endsWith("()")) ||
(match.endsWith(")")) ||
(match.endsWith("( )"))) {
// this here is because i guessed that method will start
// at the 0
if((match.charAt(0)!=' ') && !(match.startsWith("\t"))) {
lineWithNameOfFunction = match;
}
}
if(match.contains(expression)) {
matchFound = true;
break;
}
}
if(matchFound)
System.out.println(lineWithNameOfFunction);
else
System.out.println("No matching function found");
} catch (IOException ex) {
ex.printStackTrace();
}
}
я написал это в JAVA, протестировал его и работает как шарм. Есть несколько недостатков, но для начала это хорошо. не добавлена поддержка нескольких функций, содержащих одно и то же выражение и, возможно, некоторые другие вещи. попробуй.
Ага! Я признаю, что это немного перебор:
Маленькая программа для фильтрации стандартного ввода, удаления комментариев и помещения тел функций в одну строку. Помимо прочего, его обманут пространства имен и определения функций внутри объявлений классов. Но это может быть хорошим началом:
#include <stdio.h>
#include <assert.h>
int main() {
enum {
NORMAL,
LINE_COMMENT,
MULTI_COMMENT,
IN_STRING,
} state = NORMAL;
unsigned depth = 0;
for(char c=getchar(),prev=0; !feof(stdin); prev=c,c=getchar()) {
switch(state) {
case NORMAL:
if('/'==c && '/'==prev)
state = LINE_COMMENT;
else if('*'==c && '/'==prev)
state = MULTI_COMMENT;
else if('#'==c)
state = LINE_COMMENT;
else if('\"'==c) {
state = IN_STRING;
putchar(c);
} else {
if(('}'==c && !--depth) || (';'==c && !depth)) {
putchar(c);
putchar('\n');
} else {
if('{'==c)
depth++;
else if('/'==prev && NORMAL==state)
putchar(prev);
else if('\t'==c)
c = ' ';
if(' '==c && ' '!=prev)
putchar(c);
else if(' '<c && '/'!=c)
putchar(c);
}
}
break;
case LINE_COMMENT:
if(' '>c)
state = NORMAL;
break;
case MULTI_COMMENT:
if('/'==c && '*'==prev) {
c = '\0';
state = NORMAL;
}
break;
case IN_STRING:
if('\"'==c && '\\'!=prev)
state = NORMAL;
putchar(c);
break;
default:
assert(!"bug");
}
}
putchar('\n');
return 0;
}
Его c ++, поэтому просто его в файле, скомпилируйте его в файл с именем 'stripper', а затем:
cat my_source.cpp | ./stripper | grep JOHN_DOE
Итак, рассмотрим ввод:
int foo ( int arg1 )
{
/// code
}
void bar ( std::string arg2 )
{
/// code
aFunctionCall( JOHN_DOE );
/// more code
}
Вывод " cat example.cpp | ./stripper
":
int foo ( int arg1 ) { }
void bar ( std::string arg2 ){ aFunctionCall( JOHN_DOE ); }
Результатом" cat example.cpp | ./stripper | grep JOHN_DOE
"является:
void bar ( std::string arg2 ){ aFunctionCall( JOHN_DOE ); }
Задача поиска имя функции (предположить, что это последний идентификатор, предшествующий " (
") - оставлено читателю в качестве упражнения.