简体   繁体   English

隐藏vim中的文本段以用于外部命令

[英]Hide text segments in vim for use in external commands

I am trying to create some sort of an ncurses-like menu appearence in vim. 我试图在vim中创建一些像ncurses一样的菜单外观。
Each line should have two fields: title, command 每行应该有两个字段:title,command
I read the input from stdin, formatted like: title COMMAND: command 我从stdin读取输入,格式为: title COMMAND: command

item 1 COMMAND: echo hey
item 2 COMMAND: ls /
item 3 COMMAND: some-other-command

I want to show only the titles, like so: 我想只显示标题,如下:

item 1
item 2
item 3

But then I want to be able to run the command of this line, like so: 但后来我希望能够运行这一行的命令,如下所示:

:.w !exec $(sed -r 's/COMMAND: (.*)/\1/')

But I haven't been able to hide the "COMMAND: ..." part. 但我无法隐藏“命令:...”部分。
How can I accomplish this? 我怎么能做到这一点?
Is vim not suited for such adventures? vim不适合这样的冒险吗?

Thank you... 谢谢...

first thing you need to take care is, :exec doesn't support [range] , that is, you cannot :% exec !whatever 你需要注意的第一件事是:exec不支持[range] ,也就是说,你不能:% exec !whatever

If I understood you right, you want to for each line in your example, pick part of the line, the text after COMMAND: , as external shell command, and execute it. 如果我理解你正确,你想要对你的例子中的每一行,选择行的一部分, COMMAND:之后的文本COMMAND:作为外部shell命令,并执行它。

You can try this command: 您可以尝试以下命令:

exec '!'.substitute(getline('.'),'.*COMMAND: ','','g')

To apply it on all your lines, you can consider to use macro, it is pretty easy. 要在所有线路上应用它,您可以考虑使用宏,这很容易。 Don't put sed in, it doesn't help much. 不要把sed放入,它没有多大帮助。

If you want to first execute the cmd, and then modify the line, remove COMMAND:.. part, you can chain a :s after the exec ... : 如果你想首先执行cmd,然后修改该行,删除COMMAND:.. part,你可以在exec ...之后链接一个:s exec ...

exec '!'.substitute(....)|s/COMMAND:.*//

Here is how to accomplish what you originally intended. 以下是如何完成您最初的目标。 There are many options but I personally use the Unite plugin. 有很多选择,但我个人使用Unite插件。

Install Unite 安装Unite

Add the following in your vimrc too see possibilities: vimrc添加以下内容也可以看到:

let g:unite_source_menu_menus = {}


let g:unite_source_menu_menus.filters = {
\'description' : 'Text filters',
\'command_candidates' : [
\  ["Remove empty lines"           , 'v/./d'],
\  ["Remove empty lines  [v]"      , "'<,'>v/./d"],
\  ['Condense empty lines'         , '%s/\n\{3,}/\r\r/e'],
\  ['Remove trailing white space'  , '%s/\s\+$//' ],
\  ['',''],
\]}

let g:unite_source_menu_menus.git = {
\ 'description' : 'Git commands (Fugitive)',
\ 'command_candidates' : [
\  ['git status       (Fugitive)                               '  , 'Gstatus'],
\  ['git diff         (Fugitive)                               '  , 'Gdiff'],
\  ['git commit       (Fugitive)                               '  , 'Gcommit'],
\  ['git cd           (Fugitive)                               '  , 'Gcd'],
\  ['',''],
\  ['git view file    (gitv)                                   '  , 'Gitv!'],
\  ['git view all     (gitv)                                   '  , 'Gitv'],
\]}

let g:unite_source_menu_menus.myhelp = {
\'description' : 'Interesting help topics',
\'command_candidates' : [
\  ['Executing shell commands in a window', 'h shell-window'],
\  ['File Searching and **', 'h starstar'],
\  ['Local directory .vimrc', "h 'exrc'"]
\]}

noremap <silent> sm  :<C-u>Unite -no-start-insert -quick-match -buffer-name=menu menu<CR>

You can launch menu with sm . 您可以使用sm启动菜单。 You can change menu options and you can execute, edit, bookmark and do other tasks with commands. 您可以更改菜单选项,还可以使用命令执行,编辑,添加书签和执行其他任务。 There is an option to filter items and use fuzzy search engine. 可以选择过滤项目并使用模糊搜索引擎。 Unite is unbelievable awesome plugin with many other benefits. Unite是令人难以置信的令人难以置信的插件,还有许多其他好处。

Another option is to use Forms plugin. 另一种选择是使用Forms插件。

As for custom solution, this is a fast idea: 至于自定义解决方案,这是一个快速的想法:

Given the file awesome.menu 鉴于文件awesome.menu

item 11 COMMAND: echo 'hey'
item 2 COMMAND: !ls /
item 3 COMMAND: version

you can use the following function. 你可以使用以下功能。

fu! Menu()

    let g:menu_bg = synIDattr(hlID('Normal'), 'bg#')
    let g:menu_fg = synIDattr(hlID('Normal'), 'fg#')
    let g:menu_s = 1

    exe 'highlight MyMenu guifg=' g:menu_fg
    match MyMenu /COMMAND:.*/
    nn <buffer> <space> :let g:menu_s = !g:menu_s<cr>:exe 'highlight MyMenu guifg=' . '<c-r>=g:menu_s ? g:menu_fg : g:menu_bg<cr>'<cr>
    nn <buffer> <cr> :exe substitute(getline('.'),'.*COMMAND: ','','g')<cr>

    norm <space>

    echo 'Menu Loaded'
endf


au BufCreate *.menu call Menu()

If you add above code in your vimrc and then load awesome.menu, your command text will be hidden and you can use "space" to toggle its visibility and "enter" to execute it. 如果你在vimrc中添加上面的代码然后加载awesome.menu,你的命令文本将被隐藏,你可以使用“space”来切换它的可见性并“输入”来执行它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM