从Vim发送代码到外部应用执行

19 投票
3 回答
1784 浏览
提问于 2025-04-16 23:28

我在使用Stata的时候,文本编辑器是gVim。我用一些脚本,来自这里这里,可以把代码从Vim发送到Stata,这让我不需要切换到Linux。这些脚本是用AutoIt写的,而我在Linux上不能使用它们。它们和文本编辑器无关,写这些脚本的人使用的是Notepad++。通过在我的.vimrc文件中加几行代码,我可以把选中的内容或者整个文件发送到Stata窗口。

我现在想在Linux上找到类似的功能。Linux上有命令行版的Stata,还有图形界面的xstata。我用的是图形界面,所以ScreenTmux就不考虑了。我没找到适合Vim的插件。我想看看Bash,Python也可以。

我需要翻译的AutoIt脚本,我希望它不会覆盖剪贴板的内容。这个脚本会检查是否有打开的Stata窗口,选择或执行一个命令,把要执行的内容粘贴到一个临时文件中,然后切换到Stata窗口,按下 Ctrl + 1 选择命令行(同时也会选择已经写好的内容,按 Ctrl + A),然后把“tempfile”的内容粘贴到命令行中,最后执行代码。我在Bash中找到了解决方案

; Declare variables
Global $ini, $statapath, $statawin, $statacmd, $dofile, $clippause, $winpause, $keypause

; File locations
; Path to INI file
$ini = @ScriptDir & "\rundo.ini"
;; contents of ini file are the following
    ;[Stata]
    ;; Path to Stata executable
    ;statapath = "C:\Program Files\Stata11\StataSE.exe"
    ;; Title of Stata window
    ;statawin = "Stata/SE 11.2"
    ;; Keyboard shortcut for Stata command window
    ;statacmd = "^1"
    ;[Delays]
    ;; Pause after copying of Stata commands to clipboard, in milliseconds
    ;; Use higher number if script fails (default: 100, recommended range: 0 - 200)
    ;clippause = 100
    ;; Pause between window-related operations, in milliseconds
    ;; Use lower number to speed up script, higher number if script fails (default: 200)
    ;winpause = 200
    ;; Pause between key strokes sent to Stata, in milliseconds
    ;; Use lower number to speed up script, higher number if script fails (default: 1)
    ;keypause = 1


; Path to Stata executable
$statapath = IniRead($ini, "Stata", "statapath", "C:\Program Files\Stata11\StataSE.exe")
; Title of Stata window
$statawin = IniRead($ini, "Stata", "statawin", "Stata/SE 11.2")

; Keyboard shortcut for Stata command window
$statacmd = IniRead($ini, "Stata", "statacmd", "^1")

; Path to do-file that is passed to AutoIt
; Edit line to match editor used, if necessary
$dofile = $CmdLine[1]

; Delays
; Pause after copying of Stata commands to clipboard
$clippause = IniRead($ini, "Delays", "clippause", "100")
; Pause between window-related operations
$winpause = IniRead($ini, "Delays", "winpause", "200")
; Pause between keystrokes sent to Stata
$keypause = IniRead($ini, "Delays", "keypause", "1")

; Set WinWaitDelay and SendKeyDelay to speed up or slow down script
Opt("WinWaitDelay", $winpause)
Opt("SendKeyDelay", $keypause)

; If more than one Stata window is open, the window that was most recently active will be matched
Opt("WinTitleMatchMode", 2)

; Check if Stata is already open, start Stata if not
If WinExists($statawin) Then
  WinActivate($statawin)
  WinWaitActive($statawin)
  ; Activate Stata command window and select text (if any)
  Send($statacmd)
  Send("^a")
  ; Run saved do-file
  ; Double quotes around $dofile needed in case path contains blanks
  ClipPut("do " & '"' & $dofile & '"')
  ; Pause avoids problem with clipboard, may be AutoIt or Windows bug
  Sleep($clippause)
  Send("^v" & "{Enter}")
Else
  Run($statapath)
  WinWaitActive($statawin)
  ; Activate Stata command window
  Send($statacmd)
  ; Run saved do-file
  ; Double quotes around $dofile needed in case path contains blanks
  ClipPut("do " & '"' & $dofile & '"')
  ; Pause avoids problem with clipboard, may be AutoIt or Windows bug
  Sleep($clippause)
  Send("^v" & "{Enter}")
EndIf

3 个回答

0

我用VI的map功能来定义一些快捷键,这样我就可以把文件发送到C编译器,并获取结果。虽然这个方法不太复杂(没有条件判断),但实现起来很简单,而且我有很多常用的快捷键。例如,&T可以把我当前所在的行变成大写,而&t则可以变成小写。我还用&S来运行拼写检查工具(gspell)等等。其实你不一定要用&符号开头来定义快捷键,但这样我就能知道这是一组不太可能随便输入的字母组合。

设置一个快捷键映射其实很简单。你只需要输入:map命令,接着空格,再输入一个单词来调用这个映射,再空格,然后输入你想执行的按键。如果你需要插入一些特殊字符,比如回车或退出,可以在前面加上Ctrl-V。

你还可以使用map!来定义一个可以在插入模式或替换模式下执行的快捷键。

1

也许你可以使用一个类似于这个vim插件的机制,它可以完成类似的任务:

R.vim : 从VIM缓冲区发送R代码到R

这个插件可以把R代码发送到R工具上,支持unix和windows系统(R编程语言在统计软件开发和数据分析中被广泛使用)。

我对Stata或R语言不太了解,但看起来你可以通过R来控制Stata,正如在为什么使用R?中提到的:

你可以在任何地方轻松使用它。它是平台无关的,所以你可以在任何操作系统上使用。而且它是免费的,所以你可以在任何公司使用,而不需要说服老板购买许可证。


R允许你与其他语言(C/C++、Java、Python)集成,并且可以与许多数据源进行交互:ODBC兼容的数据库(Excel、Access)和其他统计软件包(SAS、Stata、SPSS、Minitab)。

一些Stata命令翻译成R:

Stata还是R

如果你能通过R完成你想要的任务,那么你可能可以直接使用上面的Vim插件。

3

IronAHK 是一个用 Linux/Mono 重写的 AutoHotKey 脚本语言,它和 AutoIt 类似(都是用来自动化图形界面和重新映射键盘的工具)。我自己没有用过 IronAHK,但 AutoHotkey 可以运行 AutoIt v2 的脚本。

你还可以看看 Sikuli 项目: “Sikuli 是一种视觉技术,用于通过图像(截图)来自动化和测试图形用户界面(GUI)。Sikuli 包含 Sikuli Script,这是一个用于 Jython 的视觉脚本 API,还有 Sikuli IDE,这是一个集成开发环境,可以轻松编写带有截图的视觉脚本。”(摘自 Sikuli 的主页)

另一个不错的选择是 Linux 桌面测试项目(LDTP),它可以用 Python 编写脚本:

示例:

from ldtp import *
from ldtputils import *

try:
    launchapp("gedit")
    if waittillguiexist("*.gedit")==0:
        raise LdtpExecutionError("Gedit window does not exist")

    selectmenuitem("*-gedit", "mnuFile;mnuOpen")
    selectrow("dkgOpenFiles...", "tblFiles", fileName[0])
    ...

撰写回答