fdaf
2024 年11 月 21 日 03:59
1
Android 的 Emacs 好像没法在 termux 环境下调用 emacsclient,但是可以使用 adb 打开文件:
am start -a android.intent.action.VIEW -n org.gnu.emacs/.EmacsOpenActivity -d file:///storage/emulated/0/1.txt org.gnu.emacs
因此也可以调用 org-protocol:
am start -a android.intent.action.VIEW -n org.gnu.emacs/.EmacsOpenActivity -d org-protocol://test?a=a org.gnu.emacs
但是要先 advice 以下函数,因为传给 emacs 的参数前面会加上 emacs 的家目录导致 org-protocol 识别不了
(with-eval-after-load 'org-protocol
(define-advice org-protocol-check-filename-for-protocol
(:filter-args (args) compat-android)
"Remove prefix when called by intent."
(let ((h (getenv "HOME"))
(f (car args)))
(when (string-prefix-p (format "%s/%s:/" h org-protocol-the-protocol) f)
(setcar args (substring f (1+ (length h)))))
args)))
也就可以使用 Tasker 或者 Fooview 这种自动化或手势软件方便地执行命令:
但有个问题就是每次运行,Emacs 都会弹到前台来,假如我想后台执行命令大伙有什么想法吗,另外我没搞懂怎么使用 termux 普通的权限执行 am 命令,理论上应该是可以的
(用这个开 http 服务器能实现后台执行还能方便地返回数据,但还是想用自带的功能GitHub - skeeto/emacs-web-server: Extensible Emacs HTTP 1.1 server
我写个完整的配置,可能上面没说清楚,Android 需要执行上面的 advice:
(progn
(require 'server)
(unless server-process
(server-start))
(require 'org-protocol)
(defun my/test-org (info) (message "yes") t)
(add-to-list 'org-protocol-protocol-alist '("test-org" :protocol "test" :function my/test-org :kill-client t)))
然后在 termux 运行这个就能 “yes” 了
am start -a android.intent.action.VIEW -n org.gnu.emacs/.EmacsOpenActivity -d org-protocol://test?a=a org.gnu.emacs
主要场景是在没法运行 emacsclient 的情况下调用 elisp,比如浏览器使用 Tampermonkey、安卓启动 Activity 等(大伙都没这需求的吗,还是我这方式有点邪门
emui8
2024 年11 月 21 日 05:06
2
可能原因和adb类似,如果要后台调用不显示界面,需要用adb shell service call这种形式,但是就要求应用本身提供了对应功能的service才行,直接用am是会打开对应的activity
另外用termux执行打开应用是不需要什么特殊权限吧,还是我没有明白你的意思
fdaf
2024 年11 月 21 日 05:20
3
你没理解错,是我描述错了,termux 里没有问题,我是拿 Fooview 里的 shell 运行的 am 报这个错导致我以为 termux 里的 am 也有这个权限问题
emui8
2024 年11 月 21 日 05:51
4
你要是想在其它应用的命令行接口调用am,我知道的办法就是像emacs一样,androidmanifest.xml声明里面加上这个
android:sharedUserId="com.termux"
再重新编译,可能还要注意签名一致的问题,如果没记错的话
然后就可以正常使用了
fdaf
2024 年11 月 21 日 07:22
5
这个应用是闭源的,可能没法改 androidmanifest.xml ,但其实主要想后台执行 emacs 的命令,听你上一条回复好像目前是没法的,大概只能通过 http 了
emui8
2024 年11 月 21 日 08:12
6
可以用一些“曲线”工具来解决编译的问题,如果一定要使用的话
我也不知道emacs是不是提供了你需要的service,可以先用adb shell service list看看有没有emacs相关的内容
1 个赞
fdaf
2024 年11 月 21 日 11:35
7
adb shell "service list | grep -i emacs"
并没有输出
拿其他工具看了下也只有这个,感觉应该是没有提供的
emui8
2024 年11 月 21 日 11:44
8
那看来就很难满足你的需求了,或者问一下emacs的开发者,他在论坛里面,看能不能有办法,或者你可以自己克隆一下源码魔改,不过感觉不是那么容易了
emui8
2024 年11 月 21 日 12:01
11
我的锅,你那样写应该是对的,可能emacs确实没有相关的service,而且adb shell service本身应该只能查看系统的,这第三方的要不去看源码,要不你去问开发者才行,他的用户名是oldosfan这个
我明天在手机上也试试看
fdaf
2024 年11 月 21 日 12:41
12
@oldosfan 老哥问一下,Android 的外部应用执行 Emacs 内部的命令有哪些比较好的方式吗,比如系统广播、Service 这些,或者浏览器打开特定格式的 url 如电脑上的 org-protocol。 (不太懂安卓开发可能问题有点蠢
1 个赞
emui8
2024 年11 月 21 日 22:00
13
查了一下androidmanifest.xml,里面是带了一个service,具体名称是org.gnu.emacs.EmacsService
emui8
2024 年11 月 22 日 01:06
15
能不能给一个具体的使用场景,我周末试试看
仔细看了一下帖子,大概了解了,今晚尝试一下看行不行
1 个赞
这个目前不支持,不过可以通过 shared user ID 调用 emacsclient。
1 个赞
刚刚看到了 OP 说在调用 emacsclient 时遇到了困难。Emacs server 的 socket 默认会在 /data/data/org.gnu.emacs/cache/emacsNNNN 开启,这里的 NNNN 可以用 termux 应用的 UID。
1 个赞
fdaf
2024 年11 月 28 日 00:28
19
能问一下 emacsclient 的路径吗,还是说要在 termux 里面装一个 emacs,用termux 的 emacsclient 指定这个 socket
/data/data/org.gnu.emacs/lib/libemacsclient.so 是 Emacsclient,在 termux 中可能需要手动指定 socket。
注意,虽然命名为 .so,这个照样是可执行文件。
1 个赞
fdaf
2024 年11 月 28 日 01:33
22
function setup_emacsclient(){
local emacsclient_path="${PREFIX}/bin/emacsclient"
if ! [ -f "$emacsclient_path" ]; then
ln -s /data/data/org.gnu.emacs/lib/libemacsclient.so "$emacsclient_path"
fi
export EMACS_SOCKET_NAME="/data/data/org.gnu.emacs/cache/emacs10$(whoami | tail -c 4)/server"
}
setup_emacsclient
在 termux 的 .bashrc 加了这个就能正常 emacsclient -e "(message \"aaa\")"
了
1 个赞