Vim: Как да събера всички съвпадащи и околни линии от файл?

Тъй като предложението за отделен VimOverflow беше отхвърлено, ще трябва да продължим да публикуваме тук.

Трябваше да преместя преводи от един файл в друг, само msgid съвпада с конкретен RegExp.

Преводите се повтарят на блокове, освен това могат да обхващат няколко реда:

# English.po

#: ...
msgid "..."
msgstr "..."

#: templates/common/commonTranslation.phtml:10 | These parts can be
#: any/number/of/lines/can/precede/the/data:0  | of any length.
msgid "buttonhelp.edit"                       <- Matching string
msgstr "Edit your details"                     | 
"the long line continues"                      | Translation
"and can be even longer"                       |

#: ...
msgid "..."
msgstr "..."

Ето какво направих в Sublime:

  1. Направих regexp за msgid модел, който ми трябва.
  2. Sublime поставя множество курсори около файла.
  3. Нагоре, нагоре, Shift-надолу-надолу-надолу-надолу – избрани са всички блокове за превод със заобикалящите ги празни редове.
  4. Cmd-C, Поставете в новия файл. Свършен.

Как мога да направя това във Vim?

Само да повторя, имам нужда от множество селекции, които мога да извлека в отделен файл въз основа на стойността msgid. Ето как изглежда един блок за избор, включително крайните и водещите празни редове:

     
#: templates/common/commonTranslation.phtml:10
msgid "buttonhelp.edit" # <- value for regexp
msgstr "Edit your details"
 

Актуализация Съжалявам, че в началото не разбрах това, но преводите могат да обхващат неопределено количество редове, това е мястото, където Sublime не успя, тъй като избрах блокове с фиксиран размер. Но преводите винаги са разделени с празен ред, с изключение на края на файла, но можем да пренебрегнем това. Това е възможно най-краткото количество данни:

     
#~ msgid "hotline.title"  | POEdit stores obsolete
#~ msgstr "HOTLINE"       | strings as well
 

Решено Благодарение на коментаторите най-накрая ми просветна и ето какво направих в крайна сметка:

:let @a=''
:g/\v"\w+\.\w+"/norm! "Ayap
:tabe
:put A

Първо изчиства регистъра a, намира всички редове с точки между думите в кавички ("\w+\.\w+") и издърпва околните абзаци в регистъра a, чието съдържание поставям в нов раздел.


person firedev    schedule 09.10.2014    source източник


Отговори (2)


за да "издърпате" всички тези блокове в регистър a, можете да опитате това във vim:

:g/msgid "buttonhelp\./norm! 2kV2)"Ay

в горния :g cmd, msgid "buttonhelp\. е регулярният израз, който съответства на вашия msgid.

преди да изпълните :g cmd, моля, направете qaq, за да изчистите регистъра a.

person Kent    schedule 09.10.2014
comment
Благодаря, това работи още по-добре, при условие че избра целия абзац, тъй като преводът може да обхваща няколко реда, нещо, което напълно пропуснах в Sublime и сега ще трябва да проверя всичко отново :/ Въпреки това последният превод беше пропуснат напълно, файлът завършва на msgid ред без съответния превод. Предполагам, че това може да се промени, като се добави празен ред в края. - person firedev; 10.10.2014
comment
Съжалявам, не се изчистих. В новия файл, който получих след поставяне на буфера, последният превод липсваше. Не съм сигурен как е възможно това, има празен ред, така че ) трябваше да работи. Ще го проверя по-късно. - person firedev; 10.10.2014
comment
Предполагам, че нещо като "Ayap в края вместо 2kV2) би направило това още по-добре, така че копира целия блок за превод от горния празен ред до долния. - person firedev; 10.10.2014

Можете да намерите (и да изпълните команда yank) на всички съвпадащи редове чрез :global.

В случай, че винаги имате нужда от редовете над и под реда msgid, можете да ги посочите като диапазон .-1,.+1 (.+2, за да включите и празния разделителен ред).

За да съберете всички съвпадения в регистър, първо го изчистете и използвайте главни букви за (за добавяне):

:let @a = '' | global/^msgid "\.\.\."/.-1,.+1yank A

За да поставите това в друг буфер, можете да използвате

:new | put! a
person Ingo Karkat    schedule 09.10.2014
comment
Удивително, това проработи. Има ли начин първо да се извърши търсене и след това просто да се направи global с посочване на регулярен израз отново? - person firedev; 10.10.2014
comment
Също така има ли начин да се копира до края на абзаца в този случай, тъй като преводът може да обхване няколко реда, нещо, което за съжаление не забелязах. - person firedev; 10.10.2014
comment
Можете да пропуснете регулярния израз, ако вече сте го търсили: :g//. Можете също да извършвате търсения (до края на абзаца) с диапазон, вижте :h :range. - person Ingo Karkat; 10.10.2014