|
|
| Line 1: |
Line 1: |
| |
+ |
{{review}} |
| |
+ |
{{TipImported |
| |
+ |
|id=79 |
| |
+ |
|previous=78 |
| |
+ |
|next=80 |
| |
+ |
|created=June 14, 2001 |
| |
+ |
|complexity=basic |
| |
+ |
|author=Flemming Madsen |
| |
+ |
|version=6.0 |
| |
+ |
|rating=130/40 |
| |
+ |
|category1=C |
| |
+ |
|category2=Searching |
| |
+ |
}} |
| |
+ |
The following function will make a :cwindow window with a line per function in the current C source file. NOTE: It writes the file as a side effect. |
| |
|
|
|
| − |
#include<stdio.h> |
+ |
Invoke with ':call ShowFunc()' |
| − |
#include<string.h> |
+ |
|
| − |
int main(int argc,char *argv[]) |
+ |
You may want to do :nmap <somekey> :call ShowFunc()<CR> |
| − |
{ |
+ |
|
| − |
int i,j; |
+ |
<pre> |
| − |
char a1[100],b1[100]; |
+ |
function! ShowFunc() |
| − |
FILE *fp; |
+ |
let gf_s = &grepformat |
| − |
if(argc==3) |
+ |
let gp_s = &grepprg |
| − |
{ |
+ |
let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m' |
| − |
fp=fopen(argv[2],"r"); |
+ |
let &grepprg = 'ctags -x --c-types=f --sort=no -o -' |
| − |
strcpy(a1,argv[1]); |
+ |
write |
| − |
i=0; |
+ |
silent! grep % |
| − |
while(!feof(fp)) |
+ |
cwindow |
| − |
{ |
+ |
let &grepformat = gf_s |
| − |
fgets(b1,sizeof(b1),fp); |
+ |
let &grepprg = gp_s |
| − |
if(strstr(b1,a1)!=NULL) |
+ |
endfunc |
| − |
{ |
+ |
</pre> |
| − |
i++; |
+ |
|
| − |
printf("%s",b1); |
+ |
==Comments== |
| − |
} |
+ |
Some enhancements courtesy of Bill McCarthy: |
| − |
|
+ |
|
| − |
} |
+ |
<pre> |
| − |
if(i==0) |
+ |
> let &grepprg = 'ctags -x --c-types=f --sort=no -o -' |
| − |
printf("\n NO MATCH FOUND \n"); |
+ |
or just: let &grepprg = 'ctags -x --c-types=f --sort=no' |
| − |
fclose(fp); |
+ |
since the '-o -' is redundant with '-x'. |
| − |
} |
+ |
> write |
| − |
else if(argc==4) |
+ |
or better yet: update |
| − |
{ |
+ |
which will not change the filedate on a file that hasn't changed. |
| − |
int i=0; |
+ |
</pre> |
| − |
char a[100],b[100],c[100]; |
+ |
|
| − |
fp=fopen(argv[3],"r"); |
+ |
---- |
| − |
strcpy(a,argv[2]); |
+ |
I'd suggest that the call to write or update (as noted in the note above) be changed to: |
| − |
if(argv[1][1]=='n') |
+ |
if (&readonly == 0) | update | endif |
| − |
{ |
+ |
so that you don't get an error message when attempting this on a read only file. |
| − |
|
+ |
|
| − |
j=0; |
+ |
---- |
| − |
printf("Lno Line\n"); |
+ |
For some reason this fails in vim6.0au under unix with file names longer than about 14 characters. however, if you change |
| − |
while(!feof(fp)) |
+ |
let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m' |
| − |
{ |
+ |
to |
| − |
fgets(b,sizeof(b),fp); |
+ |
let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %m' |
| − |
i++; |
+ |
then it works fine regardless of file name length. |
| − |
if(strstr(b,a)!=NULL) |
+ |
|
| − |
{ |
+ |
running on a terminal, if there are a lot of functions in a file then the screen tends to get messed up, which can be fixed by insering a call to redraw after the cwindow call, so you get: |
| − |
j++; |
+ |
silent! grep % |
| − |
printf("%d %s\n",i,b); |
+ |
cwindow |
| − |
} |
+ |
redraw |
| − |
} |
+ |
let &grepformat = gf_s |
| − |
if(j==0) |
+ |
|
| − |
printf("\nNO MATCH FOUND\n"); |
+ |
---- |
| − |
fclose(fp); |
+ |
Ok, couple of small bugs and mistakes fixed. Try this version: |
| − |
} |
+ |
|
| − |
if(argv[1][1]=='c') |
+ |
<pre> |
| − |
{ |
+ |
function! ShowFunc(sort) |
| − |
i=0; |
+ |
let gf_s = &grepformat |
| − |
j=0; |
+ |
let gp_s = &grepprg |
| − |
fp=fopen(argv[3],"r"); |
+ |
if ( &filetype == "c" || &filetype == "php" || &filetype == "python" || |
| − |
while(!feof(fp)) |
+ |
\ &filetype == "sh" ) |
| − |
{ |
+ |
let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' |
| − |
fgets(b,sizeof(b),fp); |
+ |
let &grepprg = 'ctags -x --'.&filetype.'-types=f --sort='.a:sort |
| − |
if(strstr(b,a)!=NULL) |
+ |
elseif ( &filetype == "perl" ) |
| − |
{ |
+ |
let &grepformat='%*\k%*\ssubroutine%*\s%l%*\s%f %m' |
| − |
i++; |
+ |
let &grepprg = 'ctags -x --perl-types=s --sort='.a:sort |
| − |
} |
+ |
elseif ( &filetype == "vim" ) |
| − |
} |
+ |
let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m' |
| − |
printf("\n Number of lines containing Pattern %s is : %d\n",a,i); |
+ |
let &grepprg = 'ctags -x --vim-types=f --language-force=vim --sort='.a:sort |
| − |
if(i==0) |
+ |
endif |
| − |
printf("NO MATCH FOUND\n"); |
+ |
if (&readonly == 0) | update | endif |
| − |
fclose(fp); |
+ |
silent! grep % |
| − |
} |
+ |
cwindow 10 |
| − |
if(argv[1][1]=='v') |
+ |
redraw |
| − |
{ |
+ |
let &grepformat = gf_s |
| − |
i=0; |
+ |
let &grepprg = gp_s |
| − |
fp=fopen(argv[3],"r"); |
+ |
endfunc |
| − |
while(!feof(fp)) |
+ |
</pre> |
| − |
{ |
+ |
|
| − |
fgets(b,sizeof(b),fp); |
+ |
I map this function to F3 to produce a list in the order the functions appear in the file or Shift-F3 to list them in alphabetical order. |
| − |
if(strstr(b,a)==NULL) |
+ |
|
| − |
{ |
+ |
noremap <F3> <Esc>:call ShowFunc("no")<CR><Esc> |
| − |
i++; |
+ |
noremap <S-F3> <Esc>:call ShowFunc("yes")<CR><Esc> |
| − |
printf("%s",b); |
+ |
|
| − |
} |
+ |
And last be sure you have Exuberant CTags installed or it won't work. |
| − |
} |
+ |
|
| − |
if(i==0) |
+ |
---- |
| − |
printf("\nALL LINES CONTAINS THE PATTERN\n"); |
+ |
Try this for Java: |
| − |
|
+ |
elseif ( &filetype == "java" ) |
| − |
fclose(fp); |
+ |
let &grepformat='%*\k%*\sclass%*\s%l%*\s%f %m' |
| − |
} |
+ |
let &grepprg = 'ctags -x --java-types=c --sort='.a:sort |
| − |
if(argv[1][1]=='x') |
+ |
|
| − |
{ |
+ |
If this produces blank results, then you can try changing the last line to: |
| − |
|
+ |
let &grepprg = 'ctags -x --java-types=c --language-force=java --sort='.a:sort |
| − |
|
+ |
|
| − |
fp=fopen(argv[3],"r"); |
+ |
---- |
| − |
a[strlen(a)]='\n'; |
+ |
I increased the number of file types supported to 19. |
| − |
i=0; |
+ |
|
| − |
while(!feof(fp)) |
+ |
You can now search for |
| − |
{ |
+ |
1. Classes - Java |
| − |
fgets(b,sizeof(b),fp); |
+ |
2. Functions - Awk, C, C++, Fortran, Lisp, Pascal, PHP, Python, Ruby, Shell Scripts, Scheme, Slang, and Vim |
| − |
if(strcmp(a,b)==0) |
+ |
3. Macros - Makefiles |
| − |
{ |
+ |
4. Procedures - Expect, and Tcl |
| − |
i++; |
+ |
5. Subroutines - Perl and Rexx |
| − |
printf("%s",b); |
+ |
|
| − |
} |
+ |
C, Shell Scripts, Vim, Expect, Tcl and Perl are well tested. The rest work on the few tests that I have given them. Let me know of any bugs and I'll work them out. |
| − |
} |
+ |
|
| − |
if(i==0) |
+ |
Additionally, I changed it so that it opens a dynamically sized cwindow based on the height of the window it was called from and/or the number of links in the results. An empty search returns a cwindow a single line tall. |
| − |
printf("\nNO LINE MATCHES THE PATTERN\n"); |
+ |
|
| − |
fclose(fp); |
+ |
Last, I packaged this function as {{script|id=397}} to make it easier to install, and to get it out of my vimrc file. |
| − |
} |
+ |
|
| − |
if(argv[1][1]=='i') |
+ |
---- |
| − |
{ |
|
| − |
j=0; |
|
| − |
fp=fopen(argv[3],"r"); |
|
| − |
for(i=0;a[i];i++) |
|
| − |
a[i]=tolower(a[i]); |
|
| − |
while(!feof(fp)) |
|
| − |
{ |
|
| − |
fgets(b,sizeof(b),fp); |
|
| − |
for(i=0;b[i];i++) |
|
| − |
c[i]=tolower(b[i]); |
|
| − |
if(strstr(c,a)!=NULL) |
|
| − |
{ |
|
| − |
printf("%s",b); |
|
| − |
i++; |
|
| − |
} |
|
| − |
} |
|
| − |
if(j==0) |
|
| − |
printf("\nNO MATCH FOUND\n"); |
|
| − |
fclose(fp); |
|
| − |
} |
|
| − |
} |
|
| − |
else |
|
| − |
{ |
|
| − |
printf("\nEnter Arguments As Per Grep Command\n "); |
|
| − |
} |
|
| − |
return 0; |
|
| − |
} |
|
The following function will make a :cwindow window with a line per function in the current C source file. NOTE: It writes the file as a side effect.
Invoke with ':call ShowFunc()'
You may want to do :nmap <somekey> :call ShowFunc()<CR>
function! ShowFunc()
let gf_s = &grepformat
let gp_s = &grepprg
let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m'
let &grepprg = 'ctags -x --c-types=f --sort=no -o -'
write
silent! grep %
cwindow
let &grepformat = gf_s
let &grepprg = gp_s
endfunc
Some enhancements courtesy of Bill McCarthy:
> let &grepprg = 'ctags -x --c-types=f --sort=no -o -'
or just: let &grepprg = 'ctags -x --c-types=f --sort=no'
since the '-o -' is redundant with '-x'.
> write
or better yet: update
which will not change the filedate on a file that hasn't changed.
I'd suggest that the call to write or update (as noted in the note above) be changed to:
if (&readonly == 0) | update | endif
so that you don't get an error message when attempting this on a read only file.
For some reason this fails in vim6.0au under unix with file names longer than about 14 characters. however, if you change
let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %*\s%m'
to
let &grepformat = '%*\k%*\sfunction%*\s%l%*\s%f %m'
then it works fine regardless of file name length.
running on a terminal, if there are a lot of functions in a file then the screen tends to get messed up, which can be fixed by insering a call to redraw after the cwindow call, so you get:
silent! grep %
cwindow
redraw
let &grepformat = gf_s
Ok, couple of small bugs and mistakes fixed. Try this version:
function! ShowFunc(sort)
let gf_s = &grepformat
let gp_s = &grepprg
if ( &filetype == "c" || &filetype == "php" || &filetype == "python" ||
\ &filetype == "sh" )
let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m'
let &grepprg = 'ctags -x --'.&filetype.'-types=f --sort='.a:sort
elseif ( &filetype == "perl" )
let &grepformat='%*\k%*\ssubroutine%*\s%l%*\s%f %m'
let &grepprg = 'ctags -x --perl-types=s --sort='.a:sort
elseif ( &filetype == "vim" )
let &grepformat='%*\k%*\sfunction%*\s%l%*\s%f %m'
let &grepprg = 'ctags -x --vim-types=f --language-force=vim --sort='.a:sort
endif
if (&readonly == 0) | update | endif
silent! grep %
cwindow 10
redraw
let &grepformat = gf_s
let &grepprg = gp_s
endfunc
I map this function to F3 to produce a list in the order the functions appear in the file or Shift-F3 to list them in alphabetical order.
noremap <F3> <Esc>:call ShowFunc("no")<CR><Esc>
noremap <S-F3> <Esc>:call ShowFunc("yes")<CR><Esc>
And last be sure you have Exuberant CTags installed or it won't work.
Try this for Java:
elseif ( &filetype == "java" )
let &grepformat='%*\k%*\sclass%*\s%l%*\s%f %m'
let &grepprg = 'ctags -x --java-types=c --sort='.a:sort
If this produces blank results, then you can try changing the last line to:
let &grepprg = 'ctags -x --java-types=c --language-force=java --sort='.a:sort
I increased the number of file types supported to 19.
You can now search for
1. Classes - Java
2. Functions - Awk, C, C++, Fortran, Lisp, Pascal, PHP, Python, Ruby, Shell Scripts, Scheme, Slang, and Vim
3. Macros - Makefiles
4. Procedures - Expect, and Tcl
5. Subroutines - Perl and Rexx
C, Shell Scripts, Vim, Expect, Tcl and Perl are well tested. The rest work on the few tests that I have given them. Let me know of any bugs and I'll work them out.
Additionally, I changed it so that it opens a dynamically sized cwindow based on the height of the window it was called from and/or the number of links in the results. An empty search returns a cwindow a single line tall.
Last, I packaged this function as script#397 to make it easier to install, and to get it out of my vimrc file.