经常会边写代码边看网页, 在编辑器和浏览器之间不停地切换.
写了几个小函数, 让我可以在 Emacs 中控制 Firefox 进行翻页和关闭当前 tab 等操作.
1 使用方式
功能 | 函数名 | 快捷键 |
---|---|---|
刷新页面 | moz-reload-browser | C-c m g |
向下翻页 | moz-page-down | C-c m n |
向上翻页 | moz-page-up | C-c m p |
关闭当前页面 | moz-tab-close | C-c m k |
2 Elisp 代码和 Firefox 插件
把以下代码放到 init.el 中:
(defun moz-send-command (command) "Send COMMAND to *MozRepl* process. If the process doesn't exist, create one." (comint-send-string (inferior-moz-process) command)) (defun moz-reload-browser () "Refresh current page" (interactive) (moz-send-command "setTimeout(function(){content.document.location.reload(true);}, '500');") ) (defun moz-page-down () "Scroll down the current window by one page." (interactive) (moz-send-command "content.window.scrollByPages(1);") ) (defun moz-page-up () "Scroll up the current window by one page." (interactive) (moz-send-command "content.window.scrollByPages(-1);") ) (defun moz-tab-close () "Close current tab" (interactive) (moz-send-command "content.window.close();") ) (global-set-key (kbd "C-c m g") 'moz-reload-browser) (global-set-key (kbd "C-c m n") 'moz-page-down) (global-set-key (kbd "C-c m p") 'moz-page-up) (global-set-key (kbd "C-c m k") 'moz-tab-close)
然后:
3 Hack 过程
边读 Caching with Rails 边写代码, 在 Emacs 和 Firefox 中不停切换, 麻烦, 能不能在 Emacs 中控制 Firefox 翻页呢?
之前看过别人写的在 Emacs 中通过 mozrepl 来刷新 Firefox 页面的函数:
(defun moz-reload-browser () (interactive) (comint-send-string (inferior-moz-process) "setTimeout(function(){content.document.location.reload(true);}, '500');"))
如果翻页也能用 mozrepl 控制的话, 那我想要的函数应该很容易写. 切到 Firefox, duckduckgo 搜索一下 “firefox console scroll down this page”, 扫一眼搜索结果, 感觉应该是 window.scroll.. 之类的.
F12 打开 Firebug, 切到 Console, 然后输入 window.scroll 看补全中有个非常非常可疑的 scrollByPages.
试一下, 在 console 中输入, window.scrollByPages, 返回: scrollByPages()
加个参数试试: scrollByPages(1), 往下翻了一页, 成了!
再试试负数参数: scrollByPages(-1), 这次往上翻了.
下面写函数:
(defun moz-page-down () "Scroll down the current window by one page." (interactive) (comint-send-string (inferior-moz-process) "content.window.scrollByPages(1);") )
不好使, 直接在 Emacs 中的 MozRepl 里运行 window.scrollByPages(1);
也不成.
在自己的 init.el 里翻翻, 找到另外一个函数:
(defun moz-update (&rest ignored) "Update the remote mozrepl instance" (interactive) (comint-send-string (inferior-moz-process) (concat "content.document.body.innerHTML=" (json-encode (buffer-string)) ";")))
它用 content.document 来获得 document, 我也加个试试, 在 MozRepl 里输入 content.window.scrollByPages(1);
, 好使.
改写我的函数:
(defun moz-page-down () "Scroll down the current window by one page." (interactive) (comint-send-string (inferior-moz-process) "content.window.scrollByPages(1);") )
再试, 好用了!
再写个往上翻页的:
(defun moz-page-up () "Scroll up the current window by one page." (interactive) (comint-send-string (inferior-moz-process) "content.window.scrollByPages(-1);") )
绑定快捷键:
(global-set-key (kbd "C-c m n") 'moz-page-down) (global-set-key (kbd "C-c m p") 'moz-page-up)
顺手写个关闭当前 tab 的函数:
(defun moz-tab-close () "Close current tab" (interactive) (comint-send-string (inferior-moz-process) "content.window.close();") ) (global-set-key (kbd "C-c m k") 'moz-tab-close)
代码比较脏, 几个函数大体相同, 简化一下:
(defun moz-send-command (command) "Send COMMAND to *MozRepl* process. If the process doesn't exist, create one." (comint-send-string (inferior-moz-process) command)) (defun moz-reload-browser () "Refresh current page" (interactive) (moz-send-command "setTimeout(function(){content.document.location.reload(true);}, '500');") ) (defun moz-page-down () "Scroll down the current window by one page." (interactive) (moz-send-command "content.window.scrollByPages(1);") ) (defun moz-page-up () "Scroll up the current window by one page." (interactive) (moz-send-command "content.window.scrollByPages(-1);") ) (defun moz-tab-close () "Close current tab" (interactive) (moz-send-command "content.window.close();") )
完成!
我在 Firefox 中用 Keysnail 的一个插件,可以按 “e” 将所有的链接用字母标注出来,按相应的字母就会点击相应的链接。类似于 Emacs 里的 ace-jump。
moz-controller 还没实现这个功能,理论上可以调用 Keysnail 的这个插件来实现
就是如果你在浏览一个网页,你需要点一个链接,是需要鼠标点击吗?还是可以直接键盘操作呢?
能说具体一点儿吗?我没有用过 vimperator
有没有可能做到像vimperator那样还可以打开链接呢?