elisp生成渐变XPM图片


无意中看到 telephone-line 有一种渐变颜色的效果,看起来很棒,但telephone-line的源码有些难懂,所以自己动手实现类似的效果

渐变颜色

渐变颜色的实现可使用color-gradient

(color-gradient
 '(0 0 0)
 (color-name-to-rgb "red") 10)

实现原理是对红(R)、绿(G)、蓝(B)三个颜色通道分别取 n + 2 个过渡值,n 为中间颜色过渡状态,所以对于red#000#a0a0a0等颜色需要转化为RGB色彩模式

生成XPM图片

XPM图片格式参考 https://en.wikipedia.org/wiki/X_PixMap(XPM3)

大概是这样的

/* XPM */
static char * XFACE[] = {
/* <Values> */
/* <width/columns> <height/rows> <colors> <chars per pixel …

关于ivy的使用技巧


ivy默认的配置已经足够了,但还是可以通过一些技巧来提升使用体验

ivy中的tab

ivy提供了好几个有关补全的命令,分别是ivy-done, ivy-partial-or-done, ivy-immediate-done, ivy-dispatching-done, 但不幸,想要获得高效的补全,我不得不记住这n多个命令,这常常使效率变得更低, 所以,我自定义了一个 maple/ivy-done, 仅使用 tab 这一个按键就可以获得以上所有的体验

(defun maple/ivy-done()
  (interactive)
  (let ((dir ivy--directory))
    (ivy-partial-or-done)
    (when (string= dir ivy--directory)
      (ivy-insert-current)
      (when (and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
                 (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last))))
        (ivy--cd dir)
        (setq this-command 'ivy-cd)))))
  • 预设场景一 …

emacs窗口管理


init-window.el

基础设置

;; 设置默认为左右分屏
(setq split-width-threshold 1)
(evil-leader/set-key
  "ws"  'split-window-below  ;; 上下分屏
  "wv"  'split-window-right) ;; 左右分屏

使用shackle管理窗口

当设置了 (setq split-width-threshold 1) 后所有的窗口都会变成左右分屏,所以需要 shacklepopwin package对窗口进行管理, 对一些特殊的窗口或 buffer 比如 *Help*flycheck error list 需要设置为显示在下方,并且默认选中

(setq shackle-rules
      '(("*Help*" :select t :align 'below :autoclose t)
        (flycheck-error-list-mode :select t :align 'below :autoclose t)))

设置默认的参数

(setq shackle-default-size 0.3 …

web-mode自定义fold函数以适应indent-region


web-mode有一个内置的web-mode-fold-or-unfold函数,但这个函数有一个问题,当存在fold时,使用indent-region会得到错误的缩进,想要得到正确的缩进,必须先 unfold, 比如

<div>
  <div class="col-xs-3 col-sm-3" id="sidebar" role="navigation">
    <button class="btn btn-primary">Submit</button> <br />
    <span>
        <button class="btn btn-primary">Submit</button> <br />
    </span>
    <span>
        <button class="btn btn-primary">Submit</button> <br />
    </span>
  </div>
</div>
<button class="btn btn-primary">Submit</button>
<br />
<a href="">as</a>

当把div …

maple-imenu——类似tagbar的emacs插件


这几天参考imenu-list重写了一个类似 vim 中tagbar的插件 maple-imenu, 其实之前我一直在使用另一个类似的插件—— imenu-list, 虽然imenu-list已经足够使用了, 但它和golden-ratio搭配起来很难受, golden-ratio 我是常开的, 但imenu-list也会偶尔使用(浏览及讲解代码必备,否则查找某个函数和变量时很难受的)

原本我想要自定义一下imenu-list,但看了源码之后, 发现很多地方都不符合我的需求, 而且需要改动的地方越来越多,最后不如自己重写

  • 如何使用

    下载文件复制到 $HOME/.emacs.d/site-lisp/maple-imenu 目录, 然后

    (use-package maple-imenu
      :load-path "site-lisp/maple-imenu"
      :commands (maple-imenu)
      :config
      (with-eval-after-load 'evil
        (evil-make-overriding-map maple-imenu-mode-map 'normal)))
    
    M-x maple-imenu
    
  • 相关变量
    • maple-imenu-buffer

      maple-imenu buffer name, default *maple-imenu*

    • maple-imenu-displayed-buffer

      displayed …

使用maple-note管理笔记


Table of Contents

更新于2019.04

  1. blog-mode 更新为 maple-note
  2. 新建 Git 仓库 emacs-maple-note

emacs-maple-note blog-mode, 一个基于tabulated-list的emacs笔记管理插件

前言

很早之前我一直在使用blog-admin作为博客笔记的管理工具, 虽然没有用社区维护的 CodeFalling/blog-admin, 而是用我自己修改的honmaple/blog-admin, 毕竟我使用的pelican, 是一个很小众的静态博客生成工具, 为了适应pelican, 也为了适应自己平时的使用, 所以自己修改了一个版本

但最近一是闲来没事,二是blog-admin使用的是ctable,中英文对齐上有些问题(虽然早就解决了), 三是觉得blog-admin有很多我不需要的代码, 而且看到那一长串的配置。。。

(setq blog-admin-backend-type 'pelican
      blog-admin-backend-new-post-in-drafts t ;; create new post in drafts by default
      blog-admin-backend-new-post-with-same-name-dir nil ;; create …

自定义helm式的ivy


n 个月前, 我曾写过 helm与ivy简单对比, 并吐嘈了ivy细节打磨不够,以至于我切换到ivy不到几天后, 又回到了helm的拥抱, 但在n个月后,本着生命不止,折腾不息的精神, “狠狠地”的折腾了一把ivy, 让ivy也能像helm一样“如丝般润滑”,适应我平时的操作

吐嘈一: counsel-find-file

我在dired中移动文件, 即使已经设置了

:map …

emacs自动更新文件头


前面已经说过,可以使用auto-insert自动添加文件头,今天来说一说自动更新文件头,比如说每次保存时自动更新last updated字段

自动更新Last Updated

如果使用的是header2,直接设置相关的变量就可,假如使用的是auto-insert,同样也可以使用emacs内置的time-stamp对Last Updated进行自动更新

time-stamp默认使用Time-stamp:,如果要对Last Updated进行自动更新,只需要简单的设置

(setq time-stamp-active t)
(setq time-stamp-line-limit 11)
(setq time-stamp-start "[lL]ast[ -][uU]pdate[ \t]*:?")
(setq time-stamp-end "\n")
(setq time-stamp-format " %#A %Y-%02m-%02d %02H:%02M:%02S (%Z)")

然后添加

(add-hook 'before-save-hook 'time-stamp)

这样就能在每次保存时自动更新相应的字段了 …

emacs自动添加文件头


想要在emacs中添加文件头有好几种方法:

  • 直接手打
  • 使用模板yasnippet
  • 使用header2
  • 使用内置的package auto-insert

header2可能是最方便的一种自动添加文件头的方式,但我之前使用过,想要自定义自己想要的内容很难,而且白白浪费header2的功能

今天主要说一说emacs内置里auto-insert,使用它在创建文件时自动添加文件头信息

基础使用

直接(auto-insert-mode) 并且设置

(setq auto-insert-query nil) ;; 不提醒

自定义文件头

(setq auto-insert-alist
      '(((python-mode . "Python program") nil
         "#!/usr/bin/env python\n"
         "# -*- coding: utf-8 -*-\n"
         "# **************************************************************************\n"
         "# Copyright © " (substring (current-time-string) -4) " " (user-full-name) "\n"
         "# File Name: " (file-name-nondirectory buffer-file-name) "\n"
         "# Author: " (user-full-name)"\n"
         "# Email: " user-mail-address "\n"
         "# Created: " (format-time-string "%Y-%m- …

helm与ivy简单对比


我为什么放弃ivy回到了helm

说一说ivy用的不爽的地方吧

counsel-find-file

counsel-find-file作为最常用的命令,ivy竟然没有把默认的find-file进行覆写,比如我在dired中想要复制文件,我习惯使用C-h退回上一个目录,但即使我之前已经设置了

:map counsel-find-file-map
("C-h" . counsel-up-directory)

但只有在使用counsel-find-file时有效,类似dired中是无效的,相比较于helm-find-filesfind-file进行覆写,无论何时都能使用自己自定义的按键,这很不爽

tab键

helm中,tab仅作为补全使用,想要打开选中项,则需要按一下enter键,而在ivy中,我不知道开发者怎么想的, 我需要记住两个或两个以上的按键

在ivy中,tab键就像命令名称ivy-alt-done一样,意味着按一下tab,就能得到helm中tab and enter的效果。

这很方便是不是?

但是,如果我要在emacs中重命名一个文件,把aaa …