2

I have two text files including steps, one is the main-file which has the entire steps and the other one is a sub-file has only part of steps. As follows.

[main-file] SeqMain.txt

0001 K1G554   1  1 21-56 3  C- 2 1 0 0     0 D001
0002 K1H060   1  3 11-46 1 21-56 3 0 0 P   0
0003 K1G049   5  1 23-56 4  C- 4 1 0 0     0 D002
0004 K1H520   5  3 27-36 4 23-56 4 0 0 P   0
0005 K1G004  15  1 29-56 3  C- 6 1 0 0     0 D003

[sub-file] SeqSub.txt

001 000x K1G554  C- 2 1 AY-29 1
002 000y K1G049  C- 4 1 AY-19 1
003 000z K1G004  C- 6 1 AY-09 1

And I always have to modify the main-file to change the sequence of steps many times. Every time the main file was changed, the step numbers in the sub-file needs to be updated too.

Here is how I edit them by using VIM:

1.I sort the main-file by the column 46 :sort/\%46, put the cursor at row3-column1 and blockwisely visual select ctrl-v the row3-column1 to row6-column4 and yank y

0002 K1H060   1  3 11-46 1 21-56 3 0 0 P   0
0004 K1H520   5  3 27-36 4 23-56 4 0 0 P   0
0001 K1G554   1  1 21-56 3  C- 2 1 0 0     0 D001
0003 K1G049   5  1 23-56 4  C- 4 1 0 0     0 D002
0005 K1G004  15  1 29-56 3  C- 6 1 0 0     0 D003
0001
0003
0005

2.Then I open the sub-file vsplit SeqSub.txt, put the cursor at row1-column4, and paste what I just yanked on it 1vp.

001 0001 K1G554  C- 2 1 AY-29 1
002 0002 K1G049  C- 4 1 AY-19 1
003 0003 K1G004  C- 6 1 AY-09 1

I tried to write the steps above into a syntax file in vimscript or recording them q that I can source the script to complete the steps. The function execute normal! ... can do the same editting in normal mode. But in visual mode it did't work.

Does there any function for blockwise visual selection in vimscript? Or does anyone have a better solution to compare and update both files?

  • I'm a little confused by the wording. One reading is "how do I do visual block selection in a macro or Ex command". The other is something of larger scope. Since the answer to the first one is just e.g. norm! ^V^Vjjllly (^V^V meaning to enter actual Ctrl-V twice to enter visual block select upon execution) that makes me think it has to be the second in which case I need clarification. – B Layer Aug 17 at 19:32
  • Thank you for reply. Does the macro means "key mapping"? Why should i enter Ctrl-v twice? – Weison Zhuang Aug 17 at 19:57
  • By macro I meant a recorded command sequence (e.g. qq). There you should just be able to do things normally while recording. However if you wanted to edit the "recording" then to insert a visual block select command into the string you'd have to do the double Ctrl-V. Is this the information you're looking for? If so I can write an answer and explain what the double Ctrl-V is for. For mappings you'd also use it. – B Layer Aug 17 at 20:07
  • There are also cases where you can use \<C-V> instead (i.e. mappings). There may actually already be an answer that addresses these particular topics. Did you search for visual block? – B Layer Aug 17 at 20:11
  • FYI I'd probably use shell commands if it were me. "join" would be handy for this... join -1 x -2 x -o 2.1,1.1,2.3,2.4,2.5,2.6,2.7,2.8 ... etc – B Layer Aug 17 at 20:59
0

I get the gist of what you want to do now. First, sourcing a script is not a great way to manage reusable code. That's what functions are for.

As for what you have so far you are unnecessarily putting :execute in front of everything when you're already in an Ex execution context.

Here's a function that you can put in your vimrc and call with :call JoinColumn(). This is adapted from the code in your comment but has some necessary or recommended changes. And you may need to do some tuning of your own once you start testing (esp. the last line...your original command doesn't do what you describe).

func! JoinColumn()
    sort /\%46c/
    " yank visual block selection into reg 'a'
    norm! 2j^V^V2j3l"ay
    vsplit SeqSub.txt
    " paste reg 'a' into desired location
    norm! 1G3l"ap
endfunc

Note that where you see ^V^V is where you should type in the double Ctrl+V that we talked about. The first Ctrl-V is a special key that allows you to embed a control character in text. We're using another Ctrl-V here but the second key entered could be whatever control character you need. After you enter this you should see just a single ^V. See :h i_CTRL-V and :h ins-special-keys.


As an aside, various shell commands could do the same operation. Following is an example of such a command sequence in a form that you'd run in Vim.

:%!join -1 13 -2 1 -o 2.1,1.1,2.3,2.4,2.5,2.6,2.7,2.8 <(sed -E 's/D([0-9]+)$/\1/' # | sort -k13) %

Before you run you should have both files loaded with the file to modify in the current buffer and the other file as the "alternate" (i.e. hitting Ctrl+^ should jump between the two files).

  • Thank you very much again! I have tried the func but to put content into the register 'a' failed. An error message "Nothing in register a" appears. I try to modify ^v^v into <c-v><c-v> or <ctrl-v><ctrl-v> does not work. Do I miss understand something? – Weison Zhuang Aug 19 at 3:57
  • While in insert mode you pressed Ctrl+V (not Ctrl+Shift+V) two times? Did it appear as a single ^V? (I tested it all, btw, so should work.) – B Layer Aug 19 at 4:01
  • It does work! Very appreciate again. I will re-read the :h again. Seems like I miss understand a lot of it. Thank you!!! – Weison Zhuang Aug 19 at 4:14
  • Cool. You're welcome. Cheers. – B Layer Aug 19 at 4:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.