wsug
1
感谢 @xuchunyang 在我另一贴 elisp如何解析http响应头 的回复, 我用elisp解析了http响应头,并自定义了http响应头,自定义的内容大致如下:
Buffer: cms.org
Elisp: (next-line 3)(org-end-of-line)(org-cycle)
这里Buffer
名字是因为emacs获取http响应结果并加载这一过程是异步的,要不响应当前操作;加Elisp
代码是要在buffer
中加载完org文本后触发执行。
这里就出现了需要将字符串转为elisp代码执行的问题,且必须是在指定的buffer
中不能是其它地方,我用了网上找到的这一段代码:(eval (car (read-from-string (format "(progn %s)" string))))
。
这样可以解决问题,但是返回的org文本是表格形式,最后的 (org-cycle)
将文本渲染成表格本来速度很快的,用上eval
后就肉眼可见的卡那么一下。我感觉应该是eval这个方法有性能问题。
想问一下这个问题是否有办法解决,或者说emacs在指定buffer中执行服务端返回的elisp代码有什么好的形式没有,如果能做到像浏览器中执行服务端发回的js一样就在好不过了。 安全问题 就暂不考虑了
如果这个问题解决不了,我就不把elisp代码写在http响应头里了,换其它办法
一次 eval 还不至于产生肉眼可见的问题:
(benchmark-run 100000 (1+ 1))
;; => (0.0017700000000000007 0 0.0)
(benchmark-run 100000 (eval '(1+ 1)))
;; => (0.026227000000000004 0 0.0)
(benchmark-run 100000 (eval (car (read-from-string "(1+ 1)"))))
;; => (0.077767 0 0.0)
否则也不可能被如此大量使用:
$ rg '\(eval\s' ~/.emacs.d/elpa/ -g '*.el' | wc -l
371
$ rg '\(eval\s' ~/emacs-repo/lisp -g '*.el' | wc -l
672
应该检查一下你传给 eval 的语句是不是有问题,在执行 eval 的前后做了什么。
wsug
3
写了一段测试代码,最后发现你的看法是对的,一次eval还不至于产生肉眼可见的问题,产生卡顿应该是在执行eval的前后做了什么,但我却发现复现不了这个情况了,包含大量链接的org表格渲染时也没卡
测试代码没找出问题,但写了就发在这里做个备份吧;要先创建一个temp.org的buffer,在运行elisp代码
(let ((url-request-method "POST")
(url-request-extra-headers `(("Content-Type" . "Content-type:application/json")))
(url-request-data (json-serialize '(buffer "temp.org")) ) )
(url-retrieve
"http://localhost/t/测试.php"
(lambda (status)
(forward-line 1);http状态码
(let (org-buf (elisp "(next-line 3)(org-end-of-line)") body)
(while (re-search-forward "^\\([^:]*\\): \\(.+\\)"
url-http-end-of-headers t)
(cond ((equal "Buffer" (match-string 1))
(progn (setq org-buf (match-string 2))))
((equal "Elisp" (match-string 1))
(progn (setq elisp (match-string 2)))) ))
(delete-region (+ (point) 2)(point-min))
(setq body (decode-coding-string (buffer-string) 'utf-8-auto-dos))
(with-current-buffer org-buf
(erase-buffer) (save-excursion (insert body))
(eval (car (read-from-string (format "(progn %s)" elisp))))
;;(save-buffer)
)
))))
服务器端的代码为:
header_remove();
header("Content-Type: text/org");
$json=json_decode(file_get_contents("php://input"),1);
header("Buffer: ".$json["buffer"]);
header("Elisp: (next-line 3)(org-end-of-line)(org-cycle)");
echo "|分类|数量|分类|数量|分类|数量\n";
for($i=0;$i<30;$i++){
echo "|classify|".$i."|classify|".$i."|classify|".$i."\n";
}
1 个赞
动态执行代码,你可以写成函数,intern动态查找并执行。
emacs的表现力比web差的太远,org-roam已经开了个好头。
wsug
5
对笔记工具感觉文本编辑功能更重要,表现力其次。
html表现力强大,但编辑html时感觉关注点会不在笔记内容本身,会去想在另一个界面的展现效果是怎样的,怎么去完善,然后又加css、又加js.
而编辑org文本比编辑html舒服多了,不仅所见即所得还是当前页面立即得到,编辑与展现在同一个页面不需要分开(markdown也是分开的),关注点也能保持在笔记内容本身上
wsug
6
对markdown的编辑器不太熟悉,不知道是否有也能做到文本编辑与展现是在同一页面的
1 个赞
cireu
8
不如直接在HTTP reponse发送数据,然后Elisp一边处理
比如数据格式
(:action scroll :data '())
然后Elisp这边先用read
提取数据,然后根据action的值dispatch代码(通过pcase的模式匹配)
1 个赞
wsug
9
看了一下typora
,感觉这个就是,不喜欢markdown的文本编辑和预览页面分开,现在这个理由也没有了,markdown也是所见即所得了。
如果这个也能自定义链接以及链接中运行任意代码,那这个和org-mode几乎没有多少区别了。表现力上还比org更强大一些。
感觉仿佛看到了文本编辑器取代office的希望,RMS的愿望 也有了实现的可能
1 个赞