Saturday, November 28, 2009

Re: How to seach and category some strings in one file?

On 05/11/09 16:09, Chris Suter wrote:
>
>
> On Thu, Nov 5, 2009 at 6:27 AM, Wu, Yue <vanopen@gmail.com
> <mailto:vanopen@gmail.com>> wrote:
>
>
> Hi list,
>
> Let's begin with my issue:
>
> I want to get some strings which matches with a particular regex,
> say '@\S\+',
> then category them into an array, so I have to know how many types
> of the
> strings a file has, so I must search all of them, which matches with
> '@\S\+',
> then category them into an array. How to achieve it in vimscript?
>
> Here is a example case:
>
> I have a file, which has some strings, say @tag1, @tag2, @tag3, but
> I don't know
> the names of them, so I have to find all of them firstly, then test
> if a string
> has been in the array, if not, then use add() to add them into an arry.
>
> I don't know if I have describe the issue clearly, if not, please
> let me know,
> thank you!
>
> --
> Hi,
> Wu, Yue
>
>
> I'd do this in a couple of steps:
>
> First, open an empty buffer window with <C-w>n -- this should open a new
> window above the window with your file, assuming you only had one window
> open to start.
>
> Now, type <C-w>j to return down to the bottom window and do
> :%g/@\S\+/normal yaW^WkGo^[p^Wj
>
> That's a pretty gnarly ex command, but with a little explanation, it
> will be clear. I use things like this all the time. First thing to note
> is that the ^W and ^[ are not two separate characters. They are,
> respectively, the text form of vim's <C-w> and <Esc> key presses. These
> can be entered in insert or command mode by typing <C-v><C-w> and
> <C-v><Esc> (try it and it will make some sense).
>
> That being said, this command does the following: For each match of
> /@\S\+/ in the file, it executes the normal command with the given
> input. See :help normal for more, but basically it lets you give vim a
> key sequence and have it behave as if you had typed those keys directly.
> So this command will, for each match, place the cursor at that match,
> yank the whole word, from whitespace before to whitespace after (yaW),
> switch to the top window (^Wk), move to the end of the buffer, open a
> new line and leave insert mode (Go^[), put the contents of the default
> register after the cursor (p), and return to the lower window (^Wj).
> When this is done for all matches, all the instances of /@\S\+/ will be
> in this new buffer.
>
> Now, to get each instance to appear only once, type <C-w>k to go up to
> the top window and do
> :%!sort | uniq
> This will filter through the sort and uniq commands to remove duplcate
> entries (NB: this requires the standard GNU toolset; if you are on
> windows, you will need Cygwin or something like that). Now, you have a
> list in this window of all the instances from the lower window, each
> appearing only once. I'm not sure what type of array you wanted to put
> these values in (i.e. a c array, a python list, a vim array, or
> otherwise), but at least now you have them all in one place!
>
> HTH, and let me know if you have questions. I find this sort of method
> useful very often for, say, grabbing every function name from a file to
> do something or other with them, etc.

Assuming that you write this in a function or command (rather than doing
it by hand every time), it won't work if 'splitbelow' is set, because
^Wj and ^Wk will work in the wrong direction then. This may be
unimportant if you write this only for yourself, but you cannot assume
'nosplitbelow' if you distribute it as a plugin or even a VimTip.

I would split, ":saveas" to a tempfile [using tempname()], remove
everything other than the @something strings, put them one to a line,
and sort with uniq but _internally_ (:%sort u). This way there's no
shuttling about between both windows, and no need to assume that GNU
utilities are available. When finished with the tempfile (and with the
result of the sort), ":q!" followed by ":call delete(expand('#'))" will
close the split-window and go back to the original, then delete the
tempfile, regardless of the split direction.


Best regards,
Tony.
--
A Los Angeles judge ruled that "a citizen may snore with immunity in
his own home, even though he may be in possession of unusual and
exceptional ability in that particular field."

--
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php

No comments: