将代码从 Vim 发送到外部应用程序以执行

问题描述 投票:0回答:3

我在工作中经常使用 Stata。我选择的文本编辑器是 (g)vim

我一直在使用herehere提供的脚本将代码从Vim发送到Stata。这个功能非常实用,而且几乎是唯一阻止我完全转向 Linux 的原因。这些脚本是用 AutoIt 编写的,所以我无法在 Linux 中使用它们。它们也基本上独立于文本编辑器的选择;编写它们的人正在使用 Notepad++

本质上,这些脚本以及我的 .vimrc 文件中的几行,允许我将选择或整个文件发送到正在运行的 Stata 窗口(如果没有打开,则首先启动 Stata)。

我正在寻找一种在 Linux 中执行此操作的解决方案,但我不知道从哪里开始。在Linux中,有两个不同的Stata版本,Stata用于命令行,xstata是GUI版本。不幸的是,我需要使用 GUI 版本,因为命令行版本的功能有限,因此排除了 Screentmux

如果这是微不足道的,我真的很抱歉错过了它,并且将非常感谢您提供解决方案。我也无法找到我可以使用的 Vim 现有插件。如果没有,我愿意投入一些时间并找出如何实施解决方案。然而,指向正确方向的指针将非常有帮助。我对 Linux 和一般编程都比较陌生,但我愿意学习。

关于工具:我不知道Bash,但无论如何,我想在某个时候研究一下它。我已经涉足了一点Python,所以那也没关系。如果还有其他绝对胜任这项任务的东西,请告诉我。

AutoIt 脚本托管在网站上,但如果需要,我可以在此处发布我的 Windows 设置。

这是我需要翻译的基本 AutoIt 脚本。 (我更喜欢一个不会每次都覆盖系统剪贴板内容的解决方案。)

我猜这就是脚本的本质:它检查是否有打开的 Stata 窗口,选择它(或执行一个),将要执行的内容粘贴到临时文件中,切换到 Stata 窗口,选择命令行使用 Ctrl + 1 (以及可能已经使用 Ctrl + A 写入的任何内容),然后将 do “tempfile” 粘贴到命令行中,然后执行发送的代码。至少我是这么理解的。


我不久前在 Bash 中制定了一个解决方案,并将其发布在 here 作为此问题先前版本的答案。

; 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
python bash vim autoit stata
3个回答
3
投票

IronAHKAutoHotKey 脚本语言的 Linux/Mono 重写,类似于 AutoIt(一种 GUI 自动化/键盘重新映射工具)。我没有使用过 IronAHK,但 AutoHotkey 可以运行 AutoIt v2 脚本。

您还可以查看@Sikuli项目:“Sikuli是一种使用图像(屏幕截图)来自动化和测试图形用户界面(GUI)的可视化技术。Sikuli包括Sikuli脚本(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])
    ...

1
投票

也许您可以使用类似于此 vim 插件所使用的机制,它执行类似的任务:

http://www.vim.org/scripts/script.php?script_id=1048

此插件将 R 代码发送到 unix 和 windows 下的 R 工具(R 编程语言 广泛用于统计软件开发和数据分析)。

我不知道Stata或R语言,但似乎你可以使用R来控制Stata,如中所述 http://www.r-bloggers.com/why-use-r/ :

You can easily use it anywhere.  It's  platform-independent, so you can use it
on any operating system.  And it's free, so you can use it at any employer
without having to persuade your boss to purchase a license.
:
:
R allows you to integrate with other languages (C/C++, Java, Python) and
enables you to interact with many data sources: ODBC-compliant databases
(Excel, Access) and other statistical packages (SAS, Stata,  SPSS,
Minitab).

一些 Stata 命令翻译为 R:

http://www.r-bloggers.com/stata-or-r/

如果您可以通过 R 执行所需的任务,那么您可能可以不加更改地使用上面的 vim 插件。

希望这有帮助。


0
投票

我使用 VI map 函数定义宏,将我的文件发送到 C 编译器,并检索结果。它不是很健壮(没有 if/then 编程),但实现起来非常简单,而且我使用了很多标准映射。例如,

&T
将我所在的行大写,而
&t
将其小写。我使用
&S
来运行我的拼写检查器 (gspell) 等。您不需要以 & 符号开始宏,但这样我就知道这不太可能是我要输入的字母组合。

设置地图非常简单。您使用 :map ex 命令、空格、用于调用地图的 word、空格,然后是要执行的击键。如果您需要插入诸如回车符或转义符之类的内容,请在其前面加上 Ctrl-V。

您可以使用

map!
映射可在插入或替换模式下执行的宏。

© www.soinside.com 2019 - 2024. All rights reserved.