用 Python写EmEditor脚本

用 Python脚本独立处理文件的一个缺点是没法实时查看文件内容并方便地 Undo/Redo,大文件更是如此。要克服这个缺点,可以用一个EmEditor的python壳调用独立的python脚本,并把结果实时显示在 EmEditor窗口中,相当于给那些不依赖于 EmEditor 的独立 Python 脚本加了个WYSWYG的图形界面。

准备:(参考)

  1. 安装 pywin32 包
  2. 运行文件 /PythonXXX/Lib/site-packages/win32comext/axscript/clientpyscript.py

测试:

  1. 编写 test.py
#language = "Python"
#title=""
#tooltip="EmEditor Macro in Python"
#icon="..\zzz\image.ico"

import sys
Window.document.write(sys.version)
  1. 在 EmEditor > Macros > Customize 中把 test.py 添加为一个宏
    (注意:test.py 使用了EmEditor的专属宏API,所以不能直接运行,只能在 EmEditor中作为宏脚本运行)

EmEditor 的宏API手册:Macro Reference 也有.chm格式可下载
用到也就几个主要的对象 Window, document, editor, selection, popupmenu

可通过录制脚本获得 javascript 格式的例子,稍加变化就成为 python 的写法,比如:
原js格式:document.selection.Text=“adsfasd”;
python格式: Window.document.selection.Text=“adsfasd”
更多实例可查看EmEditor安装目录下 Macros 中的官方脚本 以及官网更多
(标题有点歧义,代码当然还是要在IDE中写)

我也来推荐一个最近发现的有趣小玩意

Yank Note - 一款面向程序员的Markdown 笔记应用

这个笔记软件,安装了名为 Code Runner 扩展插件后,就可以在笔记右侧预览区运行代码片段了
当然它本身也支持快速打开命令窗口运行

用 python 写 EmEditor 脚本还是很实用的,毕竟如果要从头实现 EmEditor 的全部功能相当不容易,而且 python 的代码可以直接在 VSCode 中写,虽然 EmEditor 中也有语法标记,但毕竟不如 IDE 中方便

如果一直用 JS 写 EmEditor 脚本,一个小技巧是,脚本文件的扩展名不要用 EmEditor 规定的 .jsee,直接用 .js 就好,这样就可以在你常用的 IDE 中获得编辑js代码的所有便利。屏幕左边窗口开 EmEditor,右边开 IDE,调试非常方便

1 个赞

EmEditor脚本有个缺陷,要获取当前文档的全部内容,必须先全选然后用 document.selection.Text,这样做的问题是把当前的光标状态和选中状态丢失了,恢复稍微麻烦

下面这个函数虽然效率低点,还是比全选的办法好:

function funcContent() {
    var content = document.GetLine(1);
    for (i = 2; i < document.GetLines() + 1; i++) {
        content = content + "\r\n" + document.GetLine(i);
    }
    return content;
}

一个 EmEditor 的空白 js脚本模板供参考

#title = ""
#tooltip = "Blank template"
#icon = "..\zzz\myIcon.ico"
// ----------------------------------------
// ----------------------------------------
var xPos = document.selection.GetActivePointX(eePosView);
var yPos = document.selection.GetActivePointY(eePosView);

var content = funcContent();
var content2 = content;
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

content = content.replace(/a/gi, 'XXX');    // content 代表当前活动窗口内容,处理代码放在此段

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
if (content != content2) {
    document.selection.SelectAll();
    document.selection.Text = content;
    document.selection.SetActivePoint(eePosView, xPos, yPos)
}
// ----------------------------------------
function funcContent() {
    var tmpStr = document.GetLine(1);
    for (i = 2; i < document.GetLines() + 1; i++) {
        tmpStr = tmpStr + "\r\n" + document.GetLine(i);
    }
    return tmpStr;
}

这儿有个免费的图标库下载 <>https://p.yusukekamiyamane.com/<>

我怎么感觉这个需求可以完全靠 Juypter Notebook 解决。它最擅长的场景就是用 Python 来分步处理大数据集。以块为单位,你可以用它有条有理地写非常复杂的脚本,每一个块都可以独立执行和调试。

1 个赞

对 Juypter Notebook 一无所知,你说的大概是比较复杂的情况吧。我这里指的只是把用于文档处理的 python 脚本挂靠在 EmEditor 编辑器里运行而已,这样方便随时查看处理结果,有点像 Office 的 VBA

我说的就是针对你这种场景

你的意思是抛开 EmEditor 直接用 Juypter Notebook ?

这个的确是我长期追求的目标

是啊,在自然语言处理里这类活就是语料预处理,直接写 Python,用不着 EmEditor 绕一圈。

我想你可能不太用 EmEditor 这种小玩意儿,它只是个有点独特功能的小巧编辑器而已。我这里基本上只是在 EmEditor中做了个菜单把那些本可不依赖于 EmEditor 的脚本(写脚本时也基本上避开编辑器的专用API)列出来了,目的是在使用 EmEditor 手动操作时方便随时调用那些脚本,只是一个简易的workflow 而已,不涉及什么编程上的额外劳动

啊不,我还是用过几年 EmEditor 的。

这个脚本菜单放到纯 Python 里,就是把自己的常用脚本包装成一个 utils 库,也不会多难。

总之,看需求有多复杂了。

1 个赞

我大概明白你的意思了,你这个是比较专业的做法,就是说用 Juypter Notebook 管理自己的脚本库,包括哪些和 EmEditor完全不相干的脚本。我开始也找过一下这种通用的解决方案。后来发现文本编辑器对我来说是个最常用的东西,就索性把脚本都挂在它里面得了,反正脚本也不用它的API只是寄存一下。一直不知道 Juypter Notebook 是个什么玩意儿,现在好像有点知道了,谢谢!

1 个赞

Jupyter Notebook 可不是管理脚本的,它是一个很特别的编辑器。翻翻相关教程你就会发现为什么它在数据处理上如此流行了。

1 个赞

这个东西这么好,我倒是要去好好研究一下,谢谢!

用过 EmEditor 中的官方宏脚本 PopupMacros 的应该会喜欢这个修改版,可对一个文件夹下的所有文件运行任一指定的宏,效果还行。可以和官方版共存,共享宏文件夹的位置设定。(好像说新版加了这个功能,但应该不会比这里这个更方便)

Popup_for_Scripts_files (v.2.0).zip (3.2 KB)

之前对官方版也进行过一点小改也可以看看

你直接做成EmEditor的dll插件多好,毕竟有很多人没学过编程。