-
Notifications
You must be signed in to change notification settings - Fork 1
/
elisp-snippets.html
41 lines (41 loc) · 17.7 KB
/
elisp-snippets.html
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
<!doctype html><html lang=en-uk><head><script data-goatcounter=https://ruivieira-dev.goatcounter.com/count async src=//gc.zgo.at/count.js></script><script src=https://unpkg.com/@alpinejs/intersect@3.x.x/dist/cdn.min.js></script><script src=https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js></script><script type=module src=https://ruivieira.dev/js/deeplinks/deeplinks.js></script><link rel=preload href=https://ruivieira.dev/lib/fonts/fa-brands-400.woff2 as=font type=font/woff2 crossorigin=anonymous><link rel=preload href=https://ruivieira.dev/lib/fonts/fa-regular-400.woff2 as=font type=font/woff2 crossorigin=anonymous><link rel=preload href=https://ruivieira.dev/lib/fonts/fa-solid-900.woff2 as=font type=font/woff2 crossorigin=anonymous><link rel=preload href=https://ruivieira.dev/fonts/firacode/FiraCode-Regular.woff2 as=font type=font/woff2 crossorigin=anonymous><link rel=preload href=https://ruivieira.dev/fonts/vollkorn/Vollkorn-Regular.woff2 as=font type=font/woff2 crossorigin=anonymous><link rel=stylesheet href=https://ruivieira.dev/css/kbd.css type=text/css><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>Elisp snippets · Rui Vieira</title>
<link rel=canonical href=https://ruivieira.dev/elisp-snippets.html><meta name=viewport content="width=device-width,initial-scale=1"><meta name=robots content="all,follow"><meta name=googlebot content="index,follow,snippet,archive"><meta property="og:title" content="Elisp snippets"><meta property="og:description" content="SnippetsExecute command in shell buffercomint-send-string is the function we’re looking for.1
It takes a PROCESS and a STRING. You can get the process from the shell buffer, and conveniently the shell function returns the buffer, so you can streamline it all into something like:
(defun my-server () "SSH to my.server.com in `shell' buffer." (interactive) (comint-send-string (get-buffer-process (shell)) "ssh my.server.com\n")) Where the (shell) call will take care of creating the shell buffer and/or process if necessary."><meta property="og:type" content="article"><meta property="og:url" content="https://ruivieira.dev/elisp-snippets.html"><meta property="article:section" content="posts"><meta property="article:modified_time" content="2023-05-28T11:45:56+01:00"><meta name=twitter:card content="summary"><meta name=twitter:title content="Elisp snippets"><meta name=twitter:description content="SnippetsExecute command in shell buffercomint-send-string is the function we’re looking for.1
It takes a PROCESS and a STRING. You can get the process from the shell buffer, and conveniently the shell function returns the buffer, so you can streamline it all into something like:
(defun my-server () "SSH to my.server.com in `shell' buffer." (interactive) (comint-send-string (get-buffer-process (shell)) "ssh my.server.com\n")) Where the (shell) call will take care of creating the shell buffer and/or process if necessary."><link rel=stylesheet href=https://ruivieira.dev/css/styles.css><!--[if lt IE 9]><script src=https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js></script><script src=https://oss.maxcdn.com/respond/1.4.2/respond.min.js></script><![endif]--><link rel=icon type=image/png href=https://ruivieira.dev/images/favicon.ico></head><body class="max-width mx-auto px3 ltr" x-data="{currentHeading: undefined}"><div class="content index py4"><div id=header-post><a id=menu-icon href=#><i class="fas fa-eye fa-lg"></i></a>
<a id=menu-icon-tablet href=#><i class="fas fa-eye fa-lg"></i></a>
<a id=top-icon-tablet href=# onclick='$("html, body").animate({scrollTop:0},"fast")' style=display:none aria-label="Top of Page"><i class="fas fa-chevron-up fa-lg"></i></a>
<span id=menu><span id=nav><ul><li><a href=https://ruivieira.dev/>Home</a></li><li><a href=https://ruivieira.dev/blog/>Blog</a></li><li><a href=https://ruivieira.dev/draw/>Drawings</a></li><li><a href=https://ruivieira.dev/map/>All pages</a></li><li><a href=https://ruivieira.dev/search.html>Search</a></li></ul></span><br><div id=share style=display:none></div><div id=toc><h4>Contents</h4><nav id=TableOfContents><ul><li><a href=#snippets :class="{'toc-h2':true, 'toc-highlight': currentHeading == '#snippets' }">Snippets</a></li><li><a href=#execute-command-in-shell-buffer :class="{'toc-h3':true, 'toc-highlight': currentHeading == '#execute-command-in-shell-buffer' }">Execute command in shell buffer</a></li><li><a href=#free-variables :class="{'toc-h3':true, 'toc-highlight': currentHeading == '#free-variables' }">Free variables</a></li><li><a href=#lists-to-arrays :class="{'toc-h3':true, 'toc-highlight': currentHeading == '#lists-to-arrays' }">Lists to arrays</a></li><li><a href=#list-of-lists :class="{'toc-h4':true, 'toc-highlight': currentHeading == '#list-of-lists' }">List of lists</a></li><li><a href=#lists-conversion :class="{'toc-h4':true, 'toc-highlight': currentHeading == '#lists-conversion' }">Lists conversion</a></li><li><a href=#reference :class="{'toc-h2':true, 'toc-highlight': currentHeading == '#reference' }">Reference</a></li><li><a href=#defcustom :class="{'toc-h3':true, 'toc-highlight': currentHeading == '#defcustom' }">defcustom</a></li><li><a href=#footnotes :class="{'toc-h2':true, 'toc-highlight': currentHeading == '#footnotes' }">Footnotes</a></li><li><a href=#sqlite :class="{'toc-h2':true, 'toc-highlight': currentHeading == '#sqlite' }">SQLite</a></li></ul></nav><h4>Related</h4><nav><ul><li class="header-post toc"><span class=backlink-count>1</span>
<a href=https://ruivieira.dev/elisp.html>Elisp</a></li></ul></nav></div></span></div><article class=post itemscope itemtype=http://schema.org/BlogPosting><header><h1 class=posttitle itemprop="name headline">Elisp snippets</h1><div class=meta><div class=postdate>Updated <time datetime="2023-05-28 11:45:56 +0100 BST" itemprop=datePublished>2023-05-28</time>
<span class=commit-hash>(<a href=https://ruivieira.dev/log/index.html#1454e0a>1454e0a</a>)</span></div></div></header><div class=content itemprop=articleBody><h2 id=snippets x-intersect="currentHeading = '#snippets'">Snippets</h2><h3 id=execute-command-in-shell-buffer x-intersect="currentHeading = '#execute-command-in-shell-buffer'">Execute command in shell buffer</h3><p><code>comint-send-string</code> is the function we’re looking for.<sup id=fnref:1><a href=#fn:1 class=footnote-ref role=doc-noteref>1</a></sup></p><p>It takes a <code>PROCESS</code> and a <code>STRING</code>.
You can get the process from the shell buffer, and conveniently the shell function returns the buffer, so you can streamline it all into something like:</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#999>defun</span> <span style=color:teal>my-server</span> ()
</span></span><span style=display:flex><span> <span style=color:#b84>"SSH to my.server.com in `shell' buffer."</span>
</span></span><span style=display:flex><span> (<span style=color:teal>interactive</span>)
</span></span><span style=display:flex><span> (<span style=color:teal>comint-send-string</span>
</span></span><span style=display:flex><span> (<span style=color:teal>get-buffer-process</span> (<span style=color:teal>shell</span>))
</span></span><span style=display:flex><span> <span style=color:#b84>"ssh my.server.com\n"</span>))
</span></span></code></pre></div><p>Where the (shell) call will take care of creating the shell buffer and/or process if necessary.<sup id=fnref:2><a href=#fn:2 class=footnote-ref role=doc-noteref>2</a></sup></p><h3 id=free-variables x-intersect="currentHeading = '#free-variables'">Free variables</h3><p>In some situations, for instance when setting a variable in a <a href=https://ruivieira.dev/doom-emacs.html>DOOM Emacs</a> like</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=font-weight:700>setq</span> <span style=color:teal>my/variable</span> <span style=color:#b84>"value"</span>)
</span></span></code></pre></div><p>You might get the warning</p><pre tabindex=0><code>Warning: assignment to free variable `er/try-expand-list'
</code></pre><p>This is because <code>set</code> and <code>setq</code> do not declare lexical variables<sup id=fnref:3><a href=#fn:3 class=footnote-ref role=doc-noteref>3</a></sup>.
The solution is to use<sup id=fnref:4><a href=#fn:4 class=footnote-ref role=doc-noteref>4</a></sup></p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#999>defvar</span> <span style=color:teal>my/variable</span> <span style=color:#b84>"value"</span>)
</span></span></code></pre></div><h3 id=lists-to-arrays x-intersect="currentHeading = '#lists-to-arrays'">Lists to arrays</h3><h4 id=list-of-lists x-intersect="currentHeading = '#list-of-lists'">List of lists</h4><p>To convert a list of lists, <em>e.g.</em></p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#999>defvar</span> <span style=color:teal>mylist</span> ((<span style=color:#b84>"1"</span> <span style=color:#b84>"a"</span>) (<span style=color:#b84>"2"</span> <span style=color:#b84>"b"</span>) (<span style=color:#b84>"3"</span> <span style=color:#b84>"c"</span>)))
</span></span></code></pre></div><p>The method to convert a <em>single element</em> from the list is</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#900;font-weight:700>require</span> <span style=color:#b84>'cl</span>)
</span></span><span style=display:flex><span> (<span style=color:#900;font-weight:700>coerce</span> (<span style=color:#900;font-weight:700>nth</span> <span style=color:#099>0</span> <span style=color:teal>mylist</span>) <span style=color:#b84>'vector</span>)
</span></span><span style=display:flex><span> <span style=color:#998;font-style:italic>;; ["1" "a"]</span>
</span></span></code></pre></div><p>We now just need to map this for all the list</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#900;font-weight:700>mapcar</span> (<span style=color:#999>lambda</span> (<span style=color:teal>arg</span>) (<span style=color:#900;font-weight:700>coerce</span> <span style=color:teal>arg</span> <span style=color:#b84>'vector</span>)) <span style=color:teal>mylist</span>)
</span></span></code></pre></div><h4 id=lists-conversion x-intersect="currentHeading = '#lists-conversion'">Lists conversion</h4><p>To convert a <code>vector</code> to <code>list</code>:</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#900;font-weight:700>coerce</span> <span style=color:teal>[1</span> <span style=color:#099>2</span> <span style=color:teal>3]</span> <span style=color:#b84>'list</span>)
</span></span><span style=display:flex><span><span style=color:#998;font-style:italic>;; (1 2 3)</span>
</span></span></code></pre></div><p>and to convert a <code>list</code> to <code>vector</code>:</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#900;font-weight:700>coerce</span> <span style=font-weight:700>'</span>(<span style=color:#099>1</span> <span style=color:#099>2</span> <span style=color:#099>3</span>) <span style=color:#b84>'vector</span>)
</span></span><span style=display:flex><span><span style=color:#998;font-style:italic>;; [1 2 3]</span>
</span></span></code></pre></div><h2 id=reference x-intersect="currentHeading = '#reference'">Reference</h2><h3 id=defcustom x-intersect="currentHeading = '#defcustom'"><code>defcustom</code></h3><p>You can specify variables using <code>defcustom</code> so that you and others can then use Emacs’s <code>customize</code> feature to set their values. (You cannot use <code>customize</code> to write function definitions; but you can write <code>defuns</code> in your <code>.emacs</code> file. Indeed, you can write any Lisp expression in your <code>.emacs~ file</code>.)<sup id=fnref:5><a href=#fn:5 class=footnote-ref role=doc-noteref>5</a></sup></p><h2 id=footnotes x-intersect="currentHeading = '#footnotes'">Footnotes</h2><h2 id=sqlite x-intersect="currentHeading = '#sqlite'">SQLite</h2><p>Emacs provides functionality to interact with SQLite databases. For these examples we will use the <a href=https://github.com/skeeto/emacsql>emacSQL</a> package.
To open a database file <code>/tmp/foo.sqlite</code> we issue:</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span>(<span style=color:#999>defvar</span> <span style=color:teal>db</span> (<span style=color:teal>emacsql-sqlite</span> <span style=color:#b84>"~/tmp/foo.sqlite"</span>))
</span></span></code></pre></div><p>We can then issue <code>SELECT</code> statements with</p><div class=highlight><pre tabindex=0 style=background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-lisp data-lang=lisp><span style=display:flex><span><span style=color:#998;font-style:italic>;; Query the database for results:</span>
</span></span><span style=display:flex><span> (<span style=color:teal>emacsql</span> <span style=color:teal>db</span> <span style=color:teal>[:select</span> <span style=color:teal>[name</span> <span style=color:teal>id]</span>
</span></span><span style=display:flex><span> <span style=color:#b84>:from</span> <span style=color:teal>people</span>
</span></span><span style=display:flex><span> <span style=color:#b84>:where</span> (<span style=color:#900;font-weight:700>></span> <span style=color:teal>salary</span> <span style=color:#099>62000</span>)<span style=color:teal>]</span>)
</span></span><span style=display:flex><span> <span style=color:#998;font-style:italic>;; => (("Susan" 1001))</span>
</span></span></code></pre></div><div class=footnotes role=doc-endnotes><hr><ol><li id=fn:1><p>shell is built on top of the comint library. <a href=#fnref:1 class=footnote-backref role=doc-backlink>↩︎</a></p></li><li id=fn:2><p>n.b. if there’s an existing one, shell will re-use that. <a href=#fnref:2 class=footnote-backref role=doc-backlink>↩︎</a></p></li><li id=fn:3><p>Only <code>let</code> does. <a href=#fnref:3 class=footnote-backref role=doc-backlink>↩︎</a></p></li><li id=fn:4><p>But not quote the symbol. <a href=#fnref:4 class=footnote-backref role=doc-backlink>↩︎</a></p></li><li id=fn:5><p>The docs for <code>defcustom</code>: <a href=https://www.gnu.org/software/emacs/manual/html_node/eintr/defcustom.html>https://www.gnu.org/software/emacs/manual/html_node/eintr/defcustom.html</a> <a href=#fnref:5 class=footnote-backref role=doc-backlink>↩︎</a></p></li></ol></div></div></article><div id=footer-post-container><div id=footer-post><div id=nav-footer style=display:none><ul><li><a href=https://ruivieira.dev/>Home</a></li><li><a href=https://ruivieira.dev/blog/>Blog</a></li><li><a href=https://ruivieira.dev/draw/>Drawings</a></li><li><a href=https://ruivieira.dev/map/>All pages</a></li><li><a href=https://ruivieira.dev/search.html>Search</a></li></ul></div><div id=toc-footer style=display:none><nav id=TableOfContents><ul><li><a href=#snippets>Snippets</a><ul><li><a href=#execute-command-in-shell-buffer>Execute command in shell buffer</a></li><li><a href=#free-variables>Free variables</a></li><li><a href=#lists-to-arrays>Lists to arrays</a></li></ul></li><li><a href=#reference>Reference</a><ul><li><a href=#defcustom><code>defcustom</code></a></li></ul></li><li><a href=#footnotes>Footnotes</a></li><li><a href=#sqlite>SQLite</a></li></ul></nav></div><div id=share-footer style=display:none></div><div id=actions-footer><a id=menu-toggle class=icon href=# onclick='return $("#nav-footer").toggle(),!1' aria-label=Menu><i class="fas fa-bars fa-lg" aria-hidden=true></i> Menu</a>
<a id=toc-toggle class=icon href=# onclick='return $("#toc-footer").toggle(),!1' aria-label=TOC><i class="fas fa-list fa-lg" aria-hidden=true></i> TOC</a>
<a id=share-toggle class=icon href=# onclick='return $("#share-footer").toggle(),!1' aria-label=Share><i class="fas fa-share-alt fa-lg" aria-hidden=true></i> share</a>
<a id=top style=display:none class=icon href=# onclick='$("html, body").animate({scrollTop:0},"fast")' aria-label="Top of Page"><i class="fas fa-chevron-up fa-lg" aria-hidden=true></i> Top</a></div></div></div><footer id=footer><div class=footer-left>Copyright © 2024 Rui Vieira</div><div class=footer-right><nav><ul><li><a href=https://ruivieira.dev/>Home</a></li><li><a href=https://ruivieira.dev/blog/>Blog</a></li><li><a href=https://ruivieira.dev/draw/>Drawings</a></li><li><a href=https://ruivieira.dev/map/>All pages</a></li><li><a href=https://ruivieira.dev/search.html>Search</a></li></ul></nav></div></footer></div></body><link rel=stylesheet href=https://ruivieira.dev/css/fa.min.css><script src=https://ruivieira.dev/js/jquery-3.6.0.min.js></script><script src=https://ruivieira.dev/js/mark.min.js></script><script src=https://ruivieira.dev/js/main.js></script></html>