(Duplicate of 1296, 945) |
(Duplicate of 1087, 1267) |
||
Line 1: | Line 1: | ||
− | {{Duplicate |
+ | {{Duplicate|945|1087|1267|1296}} |
{{review}} |
{{review}} |
||
{{Tip |
{{Tip |
Revision as of 19:57, 14 August 2007
Duplicate tip
This tip is very similar to the following:
These tips need to be merged – see the merge guidelines.
Tip: #1454 - Show what function the cursor is in
Created: January 1, 2007 2:46 Complexity: intermediate Author: AOYAMA Shotaro Version: n/a Karma: 11/5 Imported from: Tip#1454
This is a function to show what C/C++ function/struct/class the cursor is in.
I think this method is fast enough for practical use, but not complete.
Any feedback is appreciated.
function! GetProtoLine() let ret = "" let line_save = line(".") let col_save = col(".") let top = line_save - winline() + 1 let so_save = &so let &so = 0 let istypedef = 0 " find closing brace let closing_lnum = search('^}','cW') if closing_lnum > 0 if getline(line(".")) =~ '\w\s*;\s*$' let istypedef = 1 let closingline = getline(".") endif " go to the opening brace normal! % " if the start position is between the two braces if line(".") <= line_save if istypedef let ret = matchstr(closingline, '\w\+\s*;') else " find a line contains function name let lnum = search('^\w','bcnW') if lnum > 0 let ret = getline(lnum) endif endif endif endif " restore position and screen line exe "normal! " . top . "Gz\<CR>" call cursor(line_save, col_save) let &so = so_save return ret endfunction function! WhatFunction() if &ft != "c" && &ft != "cpp" return "" endif let proto = GetProtoLine() if proto == "" return "?" endif if stridx(proto, '(') > 0 let ret = matchstr(proto, '\w\+(\@=') elseif proto =~# '\<struct\>' let ret = matchstr(proto, 'struct\s\+\w\+') elseif proto =~# '\<class\>' let ret = matchstr(proto, 'class\s\+\w\+') else let ret = strpart(proto, 0, 15) . "..." endif return ret endfunction " You may want to call WhatFunction in the statusline set statusline=%f:%{WhatFunction()}\ %m%=\ %l-%v\ %p%%\ %02B
This function works well in the following testcase:
void draw() { // When cursor is here, WhatFunction() shows "draw" glClear(GL_COLOR_BUFFER_BIT {{|}} GL_DEPTH_BUFFER_BIT); } typedef struct { int ident; // { <- braces in comments are ignored thanks to %. Great! int version; // here it shows "} HEADER" } HEADER; # define EX(a, b, c, d) a enum CMD_index #endif { EX(CMD_append, "append", ex_append); // here "enum CMD_index..." }; class Sys { public: load() { // NG: here, it shows "Sys" instead of "load"... } }; class Camera : public Object { public: void init(); }; void Camera::init() { // here WhatFunction shows "init" }
Comments
I again had some problems with scrolling. This time, side-to-side scrolling in diff mode (specifically no line wrap). When the text was scrolled left, pressing 'h' or 'l' would act as if I'd pressed 'zh' or 'zl'.
Similar to the previous issue, I solved the problem by storing the value returned from wincol() in a variable, at the beginning of GetProtoLine(). Then at the end of GetProtoLine(), if wincol() is different, I scroll appropriately...
So:
" restore position and screen line exe "normal! " . top . "Gz\<CR>" call cursor(line_save, col_save) let &so = so_save
Became:
" restore position and screen line exe "normal! " . top . "Gz\<CR>" call cursor(line_save, col_save) let line_diff = winline() - window_line if line_diff > 0 exe 'normal ' . line_diff . '^E' elseif line_diff < 0 exe 'normal ' . -line_diff . '^Y' endif let col_diff = wincol() - window_col if col_diff > 0 exe 'normal ' . col_diff . 'zl' elseif col_diff < 0 exe 'normal ' . -col_diff . 'zh' endif let &so = so_save
Anonymous , January 9, 2007 5:51
Calling WhatFunction() in the status line breaks multi-line actions like "2yy" for me, just one line is copied instead of two. Any idea how to fix that?
andrel--AT--cybernoia.de , January 15, 2007 0:46
It would have been better if you could also tell how to use it!!!
Anonymous , January 4, 2007 4:20
To use it, simply
:echo WhatFunction()
shows the function name. Or use it in the statusline as already mentioned.
The method of finding opening brace can be replaced by the one of script#1628. That's better?
Anonymous , January 4, 2007 14:03
The regexp used to find the function name, assumes that the function name would not have underscores
present code:
let ret = matchstr(proto, '\w\+(\--AT--=')
could be:
let ret = matchstr(proto, '[[:alnum:]_ ]\+(\--AT--=')
And yes, Thank you, AOYAMA Shotaro
nihars--AT--gmail.com
, January 8, 2007 1:17
Don't forget that you'll have tildas in destructor names.
So:
let ret = matchstr(proto, '[[:alnum:]_ ]\+(\--AT--=')
could be:
let ret = matchstr(proto, '\~\?[[:alnum:]_ ]\+(\--AT--=')
Anonymous
, January 8, 2007 6:33
I set this up to show the function name in my statusline. However, when I was diff-ing two different versions of the same file, and odd scrolling behavior occured... With the cursor on the bottom line of the window, I pressed 'k', and vi acted as if I pressed 'Ctrl-y'.
I solved the problem by storing the value returned from winline() in a variable, at the beginning of GetProtoLine(). Then at the end of GetProtoLine(), if winline() is different, I scroll appropriately...
So:
" restore position and screen line exe "normal! " . top . "Gz\<CR>" call cursor(line_save, col_save) let &so = so_save
Became:
" restore position and screen line exe "normal! " . top . "Gz\<CR>" call cursor(line_save, col_save) let line_diff = winline() - window_line if line_diff > 0 exe 'normal ' . line_diff . '^E' elseif line_diff < 0 exe 'normal ' . -line_diff . '^Y' endif let &so = so_save
Anonymous
, January 8, 2007 12:33