学习使用elisp给emacs写一个px转换成vw的插件
因为emacs缺少一个插件已经影响了前端同学对emacs的兴趣了,这有点尴尬,其实emacs很强大的。
对标vs code的px2vw插件,今天花半天实现了一个简易的相似功能的emacs插件。
配置
参考px2vw-px2vw-emacs-plugin上中式英文说明也能看懂。
下载px2vw.el到本地~/emacs.d/lisp/
目录下。
或在~/emacs.d/lisp/
自件一个名为px2vw.el
文件,将代码复制进去,保存。
在~/.emacs.d/custom.el
文件里添加如下代码:
(require 'px-to-vw-vh)
(global-set-key (kbd "C-c w") 'px->vw)
如果这个操作很常用的话,也可以定义一个更简洁的快捷键,比如F9
,那就将上面的第二行换成
(global-set-key [f9] 'px->vw)
重启emacs。
使用
在px代码出,按下你设置的快捷键,将执行绑定的函数,这会把比如200px;
换算成13.8889vw
保留了4位小数点,替换掉原来的以px为单位的代码。
局限说明
- 目前插件内置了宽度是1440,如果需要修改,可以在下载下来的
px2vw.el
里把第一行定义的常量viewpoint-width
改成你需要的值。 - 鉴于vh很少用到,因此还没有做适应,需要的时候手动计算下。
参考文档
px2vw.el附件
(defvar viewpoint-width 1440)
(defvar viewpoint-height 900)
(defun kill-thing-at-point (thing)
"Kill the `thing-at-point' for the specified kind of THING."
(let ((bounds (bounds-of-thing-at-point thing)))
(if bounds
(kill-region (car bounds) (cdr bounds))
(error "No %s at point" thing))))
(defun kill-word-at-point ()
"Kill the word at point."
(interactive)
(kill-thing-at-point 'word))
(defun convert-to-vw (px-v)
(format "%.2f" (/ (float (* (string-to-number px-v) 100)) viewpoint-width)))
(defun convert-to-vh (px-v)
(format "%.2f" (/ (float (* (string-to-number px-v) 100)) viewpoint-height )))
(defun px->vw ()
"Convert word at point (or selected region) from px to vw."
(interactive)
(let* ((char (if (use-region-p)
(cons (region-beginning) (region-end))
(thing-at-point 'symbol))))
(when (and char (not (string-blank-p char)) )
(if (string-match "px" char)
(progn
(setq word (current-word char))
(setq px-v (substring word 0 (- (length word) 2)))
(kill-word-at-point)
(insert (concat (convert-to-vw px-v) "vw")))
(print "there's no px value to converting")))))
;;(global-set-key (kbd "C-c w") 'px->vw)
;;(global-set-key [f9] 'px->vw)
(provide 'px2vw)
大神加强版
上面的plugin不支持整个文件或者选中区域一次性操作是个硬伤。大神版优化的同时,同时解决了这个问题。
写的代码有长又烂的原因只有一个,那就是学的太浅。
(defun k-test (string &optional posBegin posEnd)
"支持当前段落和选中区域(region)."
(interactive
(if (use-region-p)
(list nil (region-beginning) (region-end))
(let ((bds (bounds-of-thing-at-point 'paragraph)))
(progn
(goto-char (car bds))
(list nil (car bds) (cdr bds))))))
(while (re-search-forward "\\([0-9.]+\\)\\(px\\)" posEnd t)
(let* ((px-digit-str (match-string 1))
(px-digit (string-to-number px-digit-str))
(vw-digit (format
"%.2f"
(/
(* 100.0 px-digit)
1400.0))))
(replace-match (concat vw-digit "vw") t nil)
)))