【问题标题】:How to emulate Matlab’s Run command (F5) from within Vim?如何在 Vim 中模拟 Matlab 的运行命令(F5)?
【发布时间】:2012-04-20 16:55:53
【问题描述】:

我使用 Linux 和 gVim/Vim 作为 Matlab 的外部编辑器。

在 Matlab 编辑器中,您可以通过按 F5 来运行文件。我正在尝试在 Vim 中重现这个(从 gvim-gtk Debian 软件包安装)。

我知道可以像这样以“shell 模式”将名称或当前文件或选定文本发送到 Matlab:

execute '!echo "' ."run(\'".expand("%:p")."\')" . '"| matlab -nojvm' 
execute '!matlab -nodisplay < '.expand("%:p") 
noremap <C-CR> :?%%?;/%%/w !matlab -nojvm

但我想使用 Matlab GUI(在我的情况下它已经打开)。

这是我认为可以为我解决的解决方案:

  1. 在 vim 中使用一个键映射:

    • (a) 在剪贴板中添加类似:run('path-to-file') 或 cd('folder');run('filename')。
    • (b) 调用一个 shell 命令,将焦点放在 Matlab GUI 上
  2. 此时,我应该在Matlab命令窗口,所以我只要按Ctrl-V,剪贴板的内容应该被粘贴了。 (即使我在 Linux 上,我也使用带有 Windows 键绑定的 Matlab。)

步骤 1(a): 下面将run('filename')命令放到剪贴板,Matlab会在Ctrl-V按下时粘贴:

let @+="run(\'".expand("%:p")."')" 

以下两个命令适用于 Linux 中键粘贴,但这不是我想要的,因为我想在这一步中避免使用鼠标:

let @*="run(\'".expand("%:p")."')" 

execute '!echo "' . "run(\'".expand("%:p")."\')" . '"| xclip'  

步骤 1(b): 要将焦点放在 Matlab 窗口上,我使用以下命令:

wmctrl -a MATLAB &

这很好用,但它也可能会打开一个浏览器窗口,如果它碰巧打开了一个标题中带有单词 Matlab 的页面(就像你现在正在阅读的那个)。

另请参阅更复杂的解决方案:Is there a linux command to determine the window IDs associated with a given process ID?。

我的(现在是旧的)选项,但 Ctrl-V 不起作用!只有鼠标粘贴可以:

function! MatRun()
    let @+="run(\'".expand("%:p")."')" 
    let @*="run(\'".expand("%:p")."\')" 
    :call system('xclip', @+)
    !wmctrl -a MAT
endfunction

map <F5> :call MatRun() <cr><cr>

不知何故,Ctrl-V 在与wmctrl 结合使用时在这种情况下不起作用(请参阅下面的编辑)。我的重点是避免使用鼠标进行此操作。

感谢您的帮助。

更新:一个可行的选择

我的错,我在应该使用 xclip -selection c 的地方使用 xclip。请参阅下面的回复。

如果有人找到更好的解决方案,我会很高兴,例如:直接在 Matlab 命令窗口中粘贴,确保您在命令窗口中 (Ctrl-0),或避免使用wmctrl 捕获浏览器窗口。

【问题讨论】:

  • 读得很好,不知道 xclip。
  • mathworks.co.uk/help/techdoc/apiref/engopen.html - 您可以使用这种技术启动一个服务器进程,该进程将从 vim 接收到的命令通过管道传输到 matlab(或者手动打开管道,直接进入,无需中间 C 程序)
  • @Tom :看起来不错,我猜它不适用于 GUI/桌面,对吧?使用 engdemo.c,并将其限制为对 engOpen 的简单调用,这行得通吗?你能举个例子吗?谢谢

标签: matlab vim clipboard


【解决方案1】:

编辑: 查看由它制作的插件:https://github.com/elmanuelito/vim-matlab-behave

很抱歉回答我自己的问题。这是我的错,我在应该使用 xclip -selection c 的地方使用 xclip 。 我在下面列出了对我有用的不同代码:它重现了 F5 和评估单元格的行为,但您必须按 Ctrl-V 或使用鼠标粘贴到 Matlab 命令行窗口中。如果您不在命令窗口上,请使用 matlab 快捷键 Ctrl-0 跳转到它。该脚本会自动从 vim 转到 matlab(除非您有另一个窗口,名称为“matlab”)。之后我添加了标记以返回之前的光标位置。

运行整个脚本matlab:这是“运行/F5”行为(进入正确的目录并执行整个脚本):

function! MatRun()
   normal mm " mark current cursor in mark m"
   let @+="cd('".expand("%:p:h")."\'); run('./".expand("%:f"). "')"
   call system('xclip -selection c ', @+)
   call system('xclip ', @+)
   normal `m "go back to cursor location"
   !wmctrl -a MATLAB 
endfunction
map ,m :call MatRun() <cr><cr>

要运行,只评估单元格: 这是 Ctrl+Enter 行为。在与上面相同的行中: (edit: 我现在对其进行了扩展,以便它可以从第一个向上的 %% 或文件的开头 (\%^) 到第一个向下的 %% OR文件结尾 (\^$) 结束编辑)

function! MatRunCell()
    normal mm "remember cursor"
    :?%%\|\%^?;/%%\|\%$/w !xclip -selection c  "pipe the cell to xclip"
    normal `m "go back to cursor location"
    !wmctrl -a MATLAB  "go to matlab window"
endfunction
map ,k :call MatRunCell()  <cr><cr>

但我更喜欢下面的,虽然更复杂(当然可以只做 vim)。 以下内容确保您在正确的目录中运行单元,并在评估单元后返回 Vim(如果您在 matlab 中正确配置了外部编辑器。我使用:gvim --servername MAT --remote-tab -沉默的)。

 function! MatRunCellAdvanced()
     execute "!echo \"cd(\'".expand("%:p:h")."\')\">/tmp/buff"  
     normal mm
     :?%%\|\%^?;/%%\|\%$/w>> /tmp/buff
     execute "!echo \"edit ".expand("%:f")."\">>/tmp/buff"
     !cat /tmp/buff|xclip -selection c
     !cat /tmp/buff|xclip
     normal `m
     !wmctrl -a MATLAB 
 endfunction
map ,n :call MatRunCellAdvanced()  <cr><cr>

运行当前行: 将当前行复制到剪贴板并转到 matlab 窗口。 (再次Ctrl+V粘贴到matlab中,如果是你在matlab中使用的快捷方式)

 function! MatRunLine()
     " write current line and pipe to xclip "
     :.w !xclip -selection c
     !wmctrl -a MATLAB 
 endfunction
 map ,l :call MatRunLine()  <cr><cr>

运行选择:模拟 F9 行为。

  function! MatRunSelect()
     normal mm
     !rm -f /tmp/buff
     :redir > /tmp/buff
     :echo @*
     :redir END
     execute "!echo \" \">>/tmp/buff"
     execute "!echo \"edit ".expand("%:p")."\">>/tmp/buff"
     !cat /tmp/buff|xclip -selection c
      normal `m
     !wmctrl -a MATLAB 
  endfunction

粗体单元格标题 单元格标题中的粗体字

 highlight MATCELL cterm=bold term=bold gui=bold
 match MATCELL /%%.*$/

这些命令的放置位置 .vim/after/ftplugin/matlab.vim 中的所有这些命令

编辑 而不是使用:

 run('./".expand("%:f")."')"

我现在用

run('".expand("%:p")."')"

处理vim 'pwd' 与脚本目录不同的情况。我没有找到仅提取脚本名称的方法,因此我使用了完整路径。有人可能会为此找到更好的解决方案。

【讨论】:

  • 回答您自己的问题实际上是一件很棒的事情。你帮助了我和至少五个其他人。
  • 嘿,我似乎无法在 windows/givm 上使用它。我将wmctrcl 命令编辑为:!start cmd /c ""nircmd.exe" win max ititle "matlab"" 并单独运行该命令有效,但是当我运行MatRun 命令时它不起作用。 Matlab 打开一个空白的命令窗口(尽管我的工作区中已经有一个),它没有响应,我必须关闭/重新打开它。有什么想法吗?
  • 这个可以作为插件分发给像我这样的新手吗?
  • 我把它做成了一个插件,但现在它只是 linux。稍后我将尝试查看 Windows。 github.com/elmanuelito/vim-matlab-behave
【解决方案2】:

对于那些只想能够从 vim 运行 matlab 脚本并且不需要其他花哨的 GUI 东西的人,您可以尝试使用 matlab 的命令行 shell。

:! matlab -nosplash -nodesktop -r %:r 将启动一个新的 matlab shell 并将当前文件作为脚本(或不带参数的函数)运行,类似于 matlab GUI 中的 F5。您需要输入“exit”退出 matlab shell 并在之后返回 vim。当然,这只有在您要运行的文件位于 matlab 路径或终端的工作目录中时才有效。

这可能有点不方便,因为新的 matlab 实例一直在启动,运​​行脚本可能需要一段时间。您可以尝试使用 -nojvm 来避免 java 造成的开销,但我认为最好的解决方案是保持 matlab shell 处于打开状态。

您可以使用名为 Conque-Shell 的 Vim 插件来完成此操作。
安装后,您可以使用:ConqueTerm matlab -nodesktop 启动matlab shell,您将获得一个可以像matlab 控制台一样使用的缓冲区。 使用 yank 和 paste 执行代码部分就可以了。或者您可以创建为您执行此操作的 vim 函数。由于我不是很擅长,我只能在这里提供这个丑陋的映射:

:nmap &lt;f5&gt; :let @"=expand('%:r')&lt;cr&gt;:buffer matlab\ -nodesktop&lt;tab&gt;&lt;cr&gt;""p&lt;cr&gt;

【讨论】:

    【解决方案3】:

    我在 Windows 上使用 Autohotkey 执行此操作(我也使用它来交换 Esc 和 Caps Lock 键)。 Autohotkey 可以在没有管理员权限的情况下安装,在公司机器上很有用。

    使用如下所述的设置:

    • 在 gvim 中,在正常模式下按 CTRL-L 将评估 Matlab 中的当前行(然后返回 gvim)。
    • 在可视模式下,它将评估 Matlab 中的当前选择(并返回到 Vim)。

    单元模式可以通过 CTRL-E 的稍微不同的映射来实现(见下文)。 (Autohotkey 脚本将在 Matlab 中执行通过 gvim 中的 CTRL-E 映射放入剪贴板的任何内容。)然后您可以并排或在不同的屏幕上设置 Matlab 和 gvim,这是一个很棒的工作方式。

    在我的 Autohotkey 文件中,我使用了这个映射:

    ^l::
    ; execute line or current selection in Matlab
        IfWinActive, ahk_class Vim
        {
            ; CTRL-E is mapped to a Vim shortcut to yank the text you want
            Send, ^e
            WinActivate, ahk_class SunAwtFrame  
            Send, ^0^v{Enter}
            WinActivate, ahk_class ahk_class Vim
        } else if WinActive, ahk_class SunAwtFrame  
        {
            Send, ^0^v{Enter}
        } 
    Return 
    

    然后,在 vim 中我使用以下快捷方式:

    :nnoremap ^E Y
    :vnoremap ^R y
    

    注意:^E 是在 vim 中按 CTRL-V CTRL-E 或 CTRL 输入的文字 CTRL-E -Q CTRL-E。

    注意 2:SunAwtFrame 是 Windows 在我机器上的 Matlab 窗口。您可以使用 Windowspy(与 Autohotkey 捆绑在一起)来确认它在您的机器上的名称是否相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多