Re: Operator pending mode
[CCing vim_dev; apologies for my continued disorganised postings!] OK, folks, After reading feedback, etc., here is a revised patch. It's just the documentation that is different from the previous patch. In the end, given that a number of things can be done without v:operator, as Andy demonstrated, and that Yankring is a pretty specific example, I thought perhaps the best thing would be to put a brief example analogous to the v:prevcount example which is right nextdoor in the docs. If you still think a lengthier example is better, though, Bram, I'm happy to revise the patch again. I thought this, or a scaled-down count-ignorant version might be a more useful lengthy example (compared to the function name thing I suggested before): : Defines a motion/text-object C which allows you to operate on : the {count}th column of a tab-delimited table, or the column : the cursor is currently in if no count is given. :onoremap C Esc:call OperateColumn()CR :function! OperateColumn() : let c = v:prevcount : if c == 0 :call search('^\|\t\zs','bc',line(.)) : else :call cursor(line(.),1) :while search('\v(\zs[^\t]*(\t|$)){'.c.'}','c',line(.)) == 0 : call setline(line(.),getline(line(.)).\t) :endwhile : endif : call feedkeys(''.v:register.v:operator) : if strpart(getline(line('.')),col('.')-1,1) == \t :call feedkeys(:\CR) : else :call feedkeys(search('\t','n',line(.)) == 0 ? $ : t\t) : endif :endfun Ben. --~--~-~--~~~---~--~~ You received this message from the vim_dev maillist. For more information, visit http://www.vim.org/maillist.php -~--~~~~--~~--~--~--- Index: runtime/doc/eval.txt === --- runtime/doc/eval.txt(revision 621) +++ runtime/doc/eval.txt(working copy) @@ -1401,10 +1401,20 @@ This is the screen column number, like with |virtcol()|. The value is zero when there was no mouse button click. + *v:operator* *operator-variable* +v:operator The last operator given in Normal mode. This is a single + character except for commands starting with g or z, + in which case it is two characters. Best used alongside + |v:prevcount| and |v:register|. Useful if you want to cancel + Operator-pending mode and then use the operator. + :omap O Esc:call MyMotion(v:operator)CR + Read-only. + *v:prevcount* *prevcount-variable* v:prevcountThe count given for the last but one Normal mode command. This is the v:count value of the previous command. Useful if - you want to cancel Visual mode and then use the count. + you want to cancel Visual or Operator-pending mode and then + use the count. :vmap % Esc:call MyFilter(v:prevcount)CR Read-only. Index: src/vim.h === --- src/vim.h (revision 607) +++ src/vim.h (working copy) @@ -1688,7 +1688,8 @@ #define VV_MOUSE_WIN 49 #define VV_MOUSE_LNUM 50 #define VV_MOUSE_COL 51 -#define VV_LEN 52 /* number of v: vars */ +#define VV_OP 52 +#define VV_LEN 53 /* number of v: vars */ #ifdef FEAT_CLIPBOARD Index: src/eval.c === --- src/eval.c (revision 607) +++ src/eval.c (working copy) @@ -345,6 +345,7 @@ {VV_NAME(mouse_win, VAR_NUMBER), 0}, {VV_NAME(mouse_lnum, VAR_NUMBER), 0}, {VV_NAME(mouse_col, VAR_NUMBER), 0}, +{VV_NAME(operator,VAR_STRING), VV_RO}, }; /* shorthand */ @@ -17260,6 +17261,35 @@ } /* + * Set v:operator if needed. + */ +void +set_op_var(optype) +intoptype; +{ +/* This will either be two operator characters, or one and a NUL. */ +char_u opchars[2]; + +if (optype == OP_NOP) +{ + set_vim_var_string(VV_OP, NULL, 0); + return; +} + +opchars[0] = get_op_char(optype); +if (opchars[0] == 'g' || opchars[0] == 'z') + opchars[1] = get_extra_op_char(optype); +else + opchars[1] = 0; + +/* Avoid free/alloc when the value is already right. */ +if (vimvars[VV_OP].vv_str == NULL || + vimvars[VV_OP].vv_str[0] != opchars[0] || + vimvars[VV_OP].vv_str[1] != opchars[1]) + set_vim_var_string(VV_OP, opchars, opchars[1]==0?1:2); +} + +/* * Get or set v:exception. If oldval == NULL, return the current value. * Otherwise, restore the value to oldval and return NULL. * Must always be called
Re: Operator pending mode
Ben Schmidt wrote: Well, I can see that you get the information, but this is not really a useful real-world example. Think of a user that wants to get something done for which v:operator is needed. And for which there is no other solution. Here's a somewhat naively implemented example where a custom text-object is defined that allows you to operate on a function name whether the cursor is on the name itself or on its arguments. You can yank with yF, change with cF, uppercase with gUF, etc. I can't think of any other way to do this, or more complicated language-based custom text-object definition--e.g. yank/change a whole conjunction or disjunction in a logic language, yank or change the condition of an 'if' or 'while' loop from anywhere within its body. Some of these would be more useful than others, of course, but there are a lot of real world possibilities, I think. Ben. :onoremap F Esc:call OperateFunctionName()CR function! OperateFunctionName() let last_count = v:count let last_op = v:operator let last_reg = v:register exe normal \Esc while search('\(\%#\i\|\i\s*\%#\)\i*\s*(','ce',line('.')+1) == 0 normal [( endwhile exe normal \BS\_yiw echo 'normal '.(last_count0?(last_count):'').''.last_reg.last_op.'e' endfun I see. In general the reason we need v:operator would then be that you need it for situations where you need to get out of operator pending mode, move around and restart the operator. Did you copy the v:variable values because they change when executing the other commands? A remark about that will be useful in the docs. OK, I'll include the patch after sufficient testing. -- hundred-and-one symptoms of being an internet addict: 70. ISDN lines are added to your house on a hourly basis /// Bram Moolenaar -- [EMAIL PROTECTED] -- http://www.Moolenaar.net \\\ ///sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\download, build and distribute -- http://www.A-A-P.org/// \\\help me help AIDS victims -- http://ICCF-Holland.org/// --~--~-~--~~~---~--~~ You received this message from the vim_dev maillist. For more information, visit http://www.vim.org/maillist.php -~--~~~~--~~--~--~---
Re: Operator pending mode
David Fishburn wrote: This is very useful for me, but I suspect other plugin developers will also benefit since they can make smarter functions by looking at what the user has keyed in. Well, I can see that you get the information, but this is not really a useful real-world example. Think of a user that wants to get something done for which v:operator is needed. And for which there is no other solution. This is as real as it gets, using omaps there is no other solution that I or this list could find. The echo was just an FYI to the user, but my function is replaying the command the user typed so that I can later act on the effects of the command: exec normal! . \ ((v:count 0)?(v:count):''). \ (v:register==''?'':''.v:register). \ v:operator. \ cmd Without v:operator, anyone who is writing an omap is hamstrung. omap lets me define (or redefine) a motion. But without the context of the command (in this case I don't know whether the user is yanking, deleting or changing). Vim provides all the other information except this one piece of critical data (basically the same thing showcmd displays in the statusline). omaps can be much more useful than they currently are. In my real world plugin I will be creating an omap for every motion Vim supports. That way I have the opporunity to record changes made by Vim and the user. The YankRing is missing a lot of functionality at the moment since I cannot support change commands (and quite a few others) but omaps can provide the missing link, but they are essentially useless without providing the intent of the user. c,d,y provides that context. Well, if you show us the omap for one command that would be the example I was asking for. Leaving out some of the YankRing stuff perhaps to keep it small. -- hundred-and-one symptoms of being an internet addict: 69. Yahoo welcomes you with your own start page /// Bram Moolenaar -- [EMAIL PROTECTED] -- http://www.Moolenaar.net \\\ ///sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\download, build and distribute -- http://www.A-A-P.org/// \\\help me help AIDS victims -- http://ICCF-Holland.org/// --~--~-~--~~~---~--~~ You received this message from the vim_dev maillist. For more information, visit http://www.vim.org/maillist.php -~--~~~~--~~--~--~---
Re: Operator pending mode
On Oct 30, 1:38 pm, Bram Moolenaar [EMAIL PROTECTED] wrote: Ben Schmidt wrote: 3. Don't know about v:operator (works for me), the showcmd option means it could also be v:command or v:operatorcommand (since there is ... I'm not quite convinced adding v:operator is useful. What would help is giving a couple of examples how it's used. Also, in the docs for v:operator it would be good to have a few examples of the values. I suppose it can be one char, like d, but also something longer. How about the count, e.g., when I do 4d? Here is a simple example: function! MyOp(op) let cmd = a:op echo 'v:count:' v:count 'v:register:' v:register 'v:operator' v:operator 'you pressed:' cmd exec normal! . \ ((v:count 0)?(v:count):''). \ (v:register==''?'':''.v:register). \ v:operator. \ cmd endfunction omap w :call MyOp('w')CR omap e :call MyOp('e')CR omap $ :call MyOp('$')CR If you type the following commands: c$ 2yw a3de You will get the following output: v:count: 0 v:register: v:operator c you pressed: $ v:count: 2 v:register: v:operator y you pressed: w v:count: 3 v:register: a v:operator d you pressed: e What this provides is all the information to capture what the user pressed which Vim does not currently support. In the YankRing case, I will be able to replay what the user typed and still manage to capture the registers. This is very useful for me, but I suspect other plugin developers will also benefit since they can make smarter functions by looking at what the user has keyed in. Dave --~--~-~--~~~---~--~~ You received this message from the vim_dev maillist. For more information, visit http://www.vim.org/maillist.php -~--~~~~--~~--~--~---
Re: Operator pending mode
On 10/30/07, Bram Moolenaar [EMAIL PROTECTED] wrote: David Fishburn wrote: On Oct 30, 1:38 pm, Bram Moolenaar [EMAIL PROTECTED] wrote: Ben Schmidt wrote: 3. Don't know about v:operator (works for me), the showcmd option means it could also be v:command or v:operatorcommand (since there is ... I'm not quite convinced adding v:operator is useful. What would help is giving a couple of examples how it's used. Also, in the docs for v:operator it would be good to have a few examples of the values. I suppose it can be one char, like d, but also something longer. How about the count, e.g., when I do 4d? Here is a simple example: function! MyOp(op) let cmd = a:op echo 'v:count:' v:count 'v:register:' v:register 'v:operator' v:operator 'you pressed:' cmd exec normal! . \ ((v:count 0)?(v:count):''). \ (v:register==''?'':''.v:register). \ v:operator. \ cmd endfunction omap w :call MyOp('w')CR omap e :call MyOp('e')CR omap $ :call MyOp('$')CR If you type the following commands: c$ 2yw a3de You will get the following output: v:count: 0 v:register: v:operator c you pressed: $ v:count: 2 v:register: v:operator y you pressed: w v:count: 3 v:register: a v:operator d you pressed: e What this provides is all the information to capture what the user pressed which Vim does not currently support. In the YankRing case, I will be able to replay what the user typed and still manage to capture the registers. This is very useful for me, but I suspect other plugin developers will also benefit since they can make smarter functions by looking at what the user has keyed in. Well, I can see that you get the information, but this is not really a useful real-world example. Think of a user that wants to get something done for which v:operator is needed. And for which there is no other solution. This is as real as it gets, using omaps there is no other solution that I or this list could find. The echo was just an FYI to the user, but my function is replaying the command the user typed so that I can later act on the effects of the command: exec normal! . \ ((v:count 0)?(v:count):''). \ (v:register==''?'':''.v:register). \ v:operator. \ cmd Without v:operator, anyone who is writing an omap is hamstrung. omap lets me define (or redefine) a motion. But without the context of the command (in this case I don't know whether the user is yanking, deleting or changing). Vim provides all the other information except this one piece of critical data (basically the same thing showcmd displays in the statusline). omaps can be much more useful than they currently are. In my real world plugin I will be creating an omap for every motion Vim supports. That way I have the opporunity to record changes made by Vim and the user. The YankRing is missing a lot of functionality at the moment since I cannot support change commands (and quite a few others) but omaps can provide the missing link, but they are essentially useless without providing the intent of the user. c,d,y provides that context. Dave --~--~-~--~~~---~--~~ You received this message from the vim_dev maillist. For more information, visit http://www.vim.org/maillist.php -~--~~~~--~~--~--~---
Re: Operator pending mode
Well, I can see that you get the information, but this is not really a useful real-world example. Think of a user that wants to get something done for which v:operator is needed. And for which there is no other solution. Here's a somewhat naively implemented example where a custom text-object is defined that allows you to operate on a function name whether the cursor is on the name itself or on its arguments. You can yank with yF, change with cF, uppercase with gUF, etc. I can't think of any other way to do this, or more complicated language-based custom text-object definition--e.g. yank/change a whole conjunction or disjunction in a logic language, yank or change the condition of an 'if' or 'while' loop from anywhere within its body. Some of these would be more useful than others, of course, but there are a lot of real world possibilities, I think. Ben. :onoremap F Esc:call OperateFunctionName()CR function! OperateFunctionName() let last_count = v:count let last_op = v:operator let last_reg = v:register exe normal \Esc while search('\(\%#\i\|\i\s*\%#\)\i*\s*(','ce',line('.')+1) == 0 normal [( endwhile exe normal \BS\_yiw echo 'normal '.(last_count0?(last_count):'').''.last_reg.last_op.'e' endfun Send instant messages to your online friends http://au.messenger.yahoo.com --~--~-~--~~~---~--~~ You received this message from the vim_dev maillist. For more information, visit http://www.vim.org/maillist.php -~--~~~~--~~--~--~---