-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelisp-insert-code-block.html
More file actions
224 lines (182 loc) · 10.9 KB
/
elisp-insert-code-block.html
File metadata and controls
224 lines (182 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2022-05-18 三 21:42 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>elisp 杂记</title>
<meta name="generator" content="Org Mode" />
<link rel="stylesheet" type="text/css" href="org-html-themes/src/bigblow_theme/css/htmlize.css"/>
<link rel="stylesheet" type="text/css" href="org-html-themes/src/bigblow_theme/css/bigblow.css"/>
<link rel="stylesheet" type="text/css" href="org-html-themes/src/bigblow_theme/css/hideshow.css"/>
<script type="text/javascript" src="org-html-themes/src/bigblow_theme/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="org-html-themes/src/bigblow_theme/js/jquery-ui-1.10.2.min.js"></script>
<script type="text/javascript" src="org-html-themes/src/bigblow_theme/js/jquery.localscroll-min.js"></script>
<script type="text/javascript" src="org-html-themes/src/bigblow_theme/js/jquery.scrollTo-1.4.3.1-min.js"></script>
<script type="text/javascript" src="org-html-themes/src/bigblow_theme/js/jquery.zclip.min.js"></script>
<script type="text/javascript" src="org-html-themes/src/bigblow_theme/js/bigblow.js"></script>
<script type="text/javascript" src="org-html-themes/src/bigblow_theme/js/hideshow.js"></script>
<script type="text/javascript" src="org-html-themes/src/lib/js/jquery.stickytableheaders.min.js"></script>
</head>
<body>
<div id="content" class="content">
<h1 class="title">elisp 杂记</h1>
<div id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orga9c66a9">在org模式下快速插入代码块</a></li>
<li><a href="#org1f8e3e4">生成相对路径来指向org的主题</a></li>
</ul>
</div>
</div>
<div id="outline-container-orga9c66a9" class="outline-2">
<h2 id="orga9c66a9">在org模式下快速插入代码块</h2>
<div class="outline-text-2" id="text-orga9c66a9">
<p>
在org中插入一个代码块比起markdown要麻烦不少:
</p>
<p>
<code>#+begin_src xx</code>
<code>#+end_src</code>
</p>
<p>
为了快速插入代码块, 我们要写两个函数:
</p>
<ol class="org-ol">
<li><code>insert-empty-code-block</code> : 插入指定语言的代码块.
先输入代码类型,例如cpp, 然后 <code>M-x insert-empty-code-block</code>, 这样就能生成指定类型的代码块.</li>
<li><code>insert-code-block</code> : 将选中文本用代码块包裹起来
先选中某段文本,然后 <code>M-x insert-code-block</code>, 然后输入可选参数: 代码类型. (eg: cpp)</li>
</ol>
<p>
首先来分析第一个函数的实现. 这个功能类似于idea的.var, 首先要读取光标处的"单词", 比如 <code>cpp</code>, 通过学习李杀的教程,发现可以使用 <code>thing-at-point</code> 来获取光标处的单词,
(thing-at-point '选择范围 )
这个选择范围有:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">'word : 一个单词, <span style="color: #7bc275;">"emacs-lisp"</span>不是一个单词
'symbol : 一个符号, 比如 emacs-lisp
'line : 一行
更多的范围可以查询 c-h f
</pre>
</div>
<p>
成功读取代码块的类型后,还需要将其删掉并添加代码块。删掉某个范围的文本可以使用 <code>(delete-region start end)</code> , 因此我们需要知道刚才拿到的文本的开始和结束位置, 这需要函数(bounds-of-thing-at-point '范围)
它会返回一个list = (start end).
</p>
<p>
第二个函数的实现难处在于, 需要能操纵用户选中的文本, 并且在minibuffer中传入一个可选参数作为代码块的类型. 可选参数可以用 <code>&optional args</code> ,以及 <code>(interactive "s-->:")</code> 来接收. 剩下的问题就是如何操作用户选中的文本了.
首先要先保存并删除选中的文本, 然后在前后加上代码块的开始和结束代码后再插入回去. 先来看如何保存选中文本, 要保存这些文本, 首先要知道其位置: 开始和结束, 可以用两个函数来获取选中区域的开始和结束位置:
</p>
<p>
<code>(region-beginning )</code>
<code>(region-end )</code>
</p>
<p>
然后要从这个位置将文本保存到一个变量中, <code>(buffer-substring-no-properties start end)</code> 这个函数可以将buffer的一部分不保留属性地拷贝到变量中. 删除选中区域在有了开始和结束位置后就能用 <code>(delete-region start end)</code> 实现了.
</p>
<p>
这里需要注意的是输入的可选参数需要转换一下才能作为字符串类型来使用.这里正好用 <code>concat</code> 连接了一个空格, 从而将它看做字符串.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #62686E;">;;;;;;;;;;;;;</span><span style="color: #62686E;">Org模式下将选中文本放入代码块;;;;;;;;;;;;;</span>
(<span style="color: #51afef;">setq</span> previous-type <span style="color: #7bc275;">""</span>)
(<span style="color: #51afef;">defun</span> <span style="color: #5cEfFF;">insert-and-update-type-str</span> (type-str)
(<span style="color: #51afef;">if</span> (string-equal <span style="color: #7bc275;">" "</span> type-str)
(insert previous-type)
(insert type-str)
(<span style="color: #51afef;">setq</span> previous-type type-str))
)
(<span style="color: #51afef;">defun</span> <span style="color: #5cEfFF;">insert-code-block</span>(<span style="color: #FCCE7B;">&optional</span> type)
(<span style="color: #51afef;">interactive</span> <span style="color: #7bc275;">"sEnter code type: "</span> )
(<span style="color: #51afef;">let*</span> ((type-str (concat <span style="color: #7bc275;">" "</span> type))
(s (region-beginning))
(e (region-end))
(code-block (buffer-substring-no-properties s e)))
(delete-region s e)
(insert <span style="color: #7bc275;">"#+begin_src"</span>)
(insert-and-update-type-str type-str)
(insert <span style="color: #7bc275;">"\n"</span>)
(insert code-block)
(insert <span style="color: #7bc275;">"\n#+end_src\n"</span>)
)
)
<span style="color: #62686E;">;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;</span>
(<span style="color: #51afef;">defun</span> <span style="color: #5cEfFF;">insert-empty-code-block</span>()
(<span style="color: #51afef;">interactive</span>)
(<span style="color: #51afef;">let*</span> ((type-str (concat <span style="color: #7bc275;">" "</span> (thing-at-point 'symbol)))
(bounds (bounds-of-thing-at-point 'symbol))
(s (car bounds))
(e (cdr bounds))
)
(<span style="color: #51afef;">if</span> (not (eq s e ))
(delete-region s e)
)
(insert <span style="color: #7bc275;">"#+begin_src"</span>)
(insert-and-update-type-str type-str)
(insert <span style="color: #7bc275;">"\n"</span>)
(insert <span style="color: #7bc275;">"\n#+end_src\n"</span>)
)
)
(global-set-key (kbd <span style="color: #7bc275;">"<f1>"</span> ) 'insert-empty-code-block)
<span style="color: #62686E;">;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;</span>
</pre>
</div>
<p>
<b>参考</b>
</p>
<ul class="org-ul">
<li><a href="https://segmentfault.com/a/1190000039313306">https://segmentfault.com/a/1190000039313306</a></li>
<li><a href="https://www.jianshu.com/p/65b271c1dabf">https://www.jianshu.com/p/65b271c1dabf</a></li>
<li><a href="http://xahlee.info/emacs/emacs/elisp_thing-at-point.html">http://xahlee.info/emacs/emacs/elisp_thing-at-point.html</a></li>
</ul>
</div>
</div>
<div id="outline-container-org1f8e3e4" class="outline-2">
<h2 id="org1f8e3e4">生成相对路径来指向org的主题</h2>
<div class="outline-text-2" id="text-org1f8e3e4">
<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #62686E;">;;;;;;;;;;;;;;;</span><span style="color: #62686E;">用相对路径从当前目录访问项目根目录;;;;;;;;;;;;;;;;;</span>
(<span style="color: #51afef;">setq</span> org-confirm-babel-evaluate nil) <span style="color: #62686E;">;; </span><span style="color: #62686E;">org模式下运行代码无需手动确认</span>
(<span style="color: #51afef;">require</span> '<span style="color: #a991f1;">project</span>)
(<span style="color: #51afef;">defun</span> <span style="color: #5cEfFF;">count-dir</span> (str)
<span style="color: #7e7e87;">"Count the number of '</span><span style="color: #a991f1;">/</span><span style="color: #7e7e87;">' in the STR."</span>
(<span style="color: #51afef;">let*</span> ( (clist (mapcar #'char-to-string str) )
(cnt 0) )
(<span style="color: #51afef;">dolist</span> (ch clist cnt)
(<span style="color: #51afef;">if</span> (string= ch <span style="color: #7bc275;">"/"</span> )
(<span style="color: #51afef;">setq</span> cnt (+ 1 cnt))
))))
(<span style="color: #51afef;">defun</span> <span style="color: #5cEfFF;">path-diff</span> ()
<span style="color: #7e7e87;">"The current directory position is from the depth of the root directory of the project."</span>
(<span style="color: #51afef;">let*</span> ( (current (expand-file-name(concat <span style="color: #7bc275;">""</span> (format default-directory))))
(root (expand-file-name (locate-dominating-file <span style="color: #7bc275;">"."</span> <span style="color: #7bc275;">"mytheme.setup"</span> ))))
(message <span style="color: #7bc275;">"%s\n"</span> current)
(message <span style="color: #7bc275;">"%s\n"</span> root)
(- (count-dir current) (count-dir root) )
)
)
(<span style="color: #51afef;">defun</span> <span style="color: #5cEfFF;">rel-path</span> ()
<span style="color: #7e7e87;">"Return to the relative path to the root directory of the project."</span>
(<span style="color: #51afef;">let*</span> ( (cnt (path-diff))
(path <span style="color: #7bc275;">""</span> ) )
(<span style="color: #51afef;">while</span> (> cnt 0)
(<span style="color: #51afef;">setq</span> path (concat path <span style="color: #7bc275;">"../"</span> ) )
(<span style="color: #51afef;">setq</span> cnt (- cnt 1 )))
(concat path <span style="color: #7bc275;">""</span>)
)
)
(<span style="color: #51afef;">defun</span> <span style="color: #5cEfFF;">org-setup-mytheme</span>( )
(<span style="color: #51afef;">interactive</span>)
(insert (concat <span style="color: #7bc275;">"#+include: "</span> (rel-path) <span style="color: #7bc275;">"mytheme.setup \n"</span>))
)
</pre>
</div>
</div>
</div>
</div>
</body>
</html>