Vim是VSCode的Ctrl+D的最佳替代方案

bybem2ql  于 2022-11-11  发布在  Vscode
关注(0)|答案(4)|浏览(324)

Lets say we are editing this totally made up JSON file:

[{
  "id_4f7xg4egb": "<some_random_guid",
  // ... other fields
}, {
  "id_h34k3": "<another_id>",
  // ... different fields than prev object potentially
  "nested": {
    "id_j3h": "<nested_obj_id>",
    // ... nested obj fields
  }
},
// ...
]

It contains N objects (including the nested ones), and we'd like to replace the id value with the string coming appended to the field key itself. The result would be something like:

[{
  "id": "4f7xg4egb",
  // ... other fields
}, {
  "id": "h34k3",
  // ... different fields than prev object potentially
  "nested": {
    "id": "j3h",
    // ... nested obj fields
  }
},
// ...
]

Now, here is what I would do in VSCode using multiple cursors:

With VSCodeCtrl+d

  • Select first occurrence of "id_ with Shift+→x4
  • Select (and create a cursor on) every occurrence of the remaining N-1 "id_ with Ctrl+dx(N-1)
  • Select the id string(s) following "id_ with →,← (to deselect), Ctrl+Shift+→
  • Cut them with Ctrl+x (yes, each cursor gets its own "clipboard")
  • Delete the _ with Backspace
  • Select the portion we want to replace ( "<every_diff_id>" ) with →x4,Shift+End, ←x2
  • Replace the value with Ctrl+v and Esc to get rid of the extra cursors

So we are talking about 5+N+5+2+1+8+3=**N+24=o(N)**keystrokes (taking into account the fact that, for example, the Ctrl key is counted only once and then held down for the rest of the N-1 Ctrl+d commands).

With the Power of Vim

And... my question is:**How to accomplish the same result using Vim (in =< # of operations, ofc)?!**I'm a noob, one week old vimmer, and I'm loving it so far! I've been using . and basic macros for similar tasks, but I'm not sure what would be the most efficient way to tackle this one :(. I'd also prefer a solution NOT using plugins or involving adding some complicated mappings/functions to my .vimrc. After all, the VSCode solution is vanilla VSCode ;).
Thanks!

798qvoo8

798qvoo81#

我会在两个直观的通行证,而不是担心计数击键或殴打挂钟。
第一遍:

:g/id/norm f_s": "
  • 使用:global在与模式匹配的每一行上执行命令。
  • 模式为id
  • 该命令为:normal,后跟一个正常模式宏。
  • 宏...
  • 将光标移动到f_所在行上的第一个_
  • 并用": "代替它。

请参阅:help :global:help :normal:help f:help s
第二遍:

:g//norm f:;C,
  • 使用:global在与模式匹配的每一行上执行命令。
  • 模式相同,因此可以省略。
  • 该命令为:normal,后跟一个正常模式宏。
  • 宏...
  • 将光标移动到f:所在行的第一个:处,
  • 然后重复该移动以到达具有;的第二个:
  • 将该行的其余部分替换为,

请参阅:help ;:help C

3b6akqbq

3b6akqbq2#

通过录制宏并重播N次。
例如:

qa/"id_/e<CR>s": "<Esc>f:dt,q2@a

总共是25次击键。
分解:

  • qa:开始录制宏@a
  • /"id_/e:搜索模式id_,并将光标放在模式的末尾。<CR>将执行搜索。
  • s:替换光标下的字符(_),启动插入模式。然后使用": "作为替换文本(生成"id": "...<Esc>退出插入模式。
  • f:向前移动到字段后的:dt,:删除直到逗号(保留它。)
  • q:停止录制宏。
  • 2@a:执行宏@a两次。(如果有更多的id要替换,则执行更多次。使用999@a最多执行999次,或者直到出现错误为止,以先出现的为准。)

我同意多个光标是非常直观的,可能更容易掌握... VIM宏可能有些抽象,需要您考虑这些操作会对您应用宏的其他位置做些什么...
对于这种特殊的情况,也许使用:s命令会更容易一些。但这是Vim的一个优点,通常有多种方法来解决一个问题,你可以选择你喜欢的一种。

igetnqfo

igetnqfo3#

我可能会这样做:

:% s/"id_\([^"]*\)": .*,/"id": "\1"/

这是一个全局搜索和替换,匹配"id_<something>": <stuff>,并将其替换为"id": "<something>"。我认为这是一个单一的“操作”,但不确定这是否是您要寻找的。

sdnqo3pr

sdnqo3pr4#

使用全局命令将变为:

:g/"id/exe 'norm! f_xdt"f<vi"p'

where we find "id
normal mode
f_  .................... jump to underscore
x ...................... cut
dt" .................... deletes until " (goes to unnamed register)
f<  .................... jumps to <
vi" .................... visual select inner "
p ...................... paste default register

我已经发布了这个解决方案,但我认为filbranden's更好。

相关问题