aboutsummaryrefslogtreecommitdiff
path: root/docs/index.xml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/index.xml')
-rw-r--r--docs/index.xml198
1 files changed, 198 insertions, 0 deletions
diff --git a/docs/index.xml b/docs/index.xml
index 9245aba..f8b2aeb 100644
--- a/docs/index.xml
+++ b/docs/index.xml
@@ -12,6 +12,204 @@
12 <language>en-us</language> 12 <language>en-us</language>
13 <copyright>Creative Commons BY-NC-SA 4.0</copyright> 13 <copyright>Creative Commons BY-NC-SA 4.0</copyright>
14 <item> 14 <item>
15<title>OSC-52</title>
16<description>&lt;p&gt;I use &lt;code&gt;ssh&lt;/code&gt; a lot. Copying text from the remote machine to
17the host machine always sucked. But OSC-52 makes that easy.&lt;/p&gt;
18&lt;p&gt;OSC-52 is an ANSI escape sequence to write text to the terminal
19emulator. The terminal emulator, if it understands what is going on,
20will in turn write this text to the system clipboard.&lt;/p&gt;
21&lt;p&gt;What this means is some &lt;code&gt;printf&lt;/code&gt; magic can send text to
22your clipboard. I store this one-liner in a script called
23&lt;code&gt;oclip&lt;/code&gt;:&lt;/p&gt;
24&lt;div class="sourceCode" id="cb1"&gt;&lt;pre
25class="sourceCode bash"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="bu"&gt;printf&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;\033]52;c;%s\007&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="fu"&gt;base64&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;0&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
26&lt;p&gt;and I run it with:&lt;/p&gt;
27&lt;div class="sourceCode" id="cb2"&gt;&lt;pre
28class="sourceCode bash"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;remote&lt;/span&gt; $ cat some_file.txt &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="ex"&gt;oclip&lt;/span&gt;&lt;/span&gt;
29&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
30&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# some_file.txt&amp;#39;s contents are now the host&amp;#39;s clipboard&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
31&lt;h3 id="the-catch"&gt;The catch&lt;/h3&gt;
32&lt;p&gt;Your terminal emulator must support OSC-52, &lt;code&gt;alacritty&lt;/code&gt;
33and &lt;code&gt;termux&lt;/code&gt; seem to support this out of the box. In
34&lt;code&gt;st&lt;/code&gt;, OSC-52 works with this change to
35&lt;code&gt;config.h&lt;/code&gt;:&lt;/p&gt;
36&lt;pre&gt;&lt;code&gt;int allowwindowops = 1;&lt;/code&gt;&lt;/pre&gt;
37&lt;p&gt;If you are using &lt;code&gt;tmux&lt;/code&gt;, you need to flip this switch
38on:&lt;/p&gt;
39&lt;pre&gt;&lt;code&gt;set -s set-clipboard on&lt;/code&gt;&lt;/pre&gt;
40&lt;p&gt;If you are inside &lt;code&gt;nvim&lt;/code&gt;, it may work as expected as long
41as &lt;code&gt;$SSH_TTY&lt;/code&gt; is set. I sometimes physically start a session,
42and &lt;code&gt;ssh&lt;/code&gt; into the same session later from another machine,
43and &lt;code&gt;$SSH_TTY&lt;/code&gt; remains unset, so I force OSC-52 in
44&lt;code&gt;nvim&lt;/code&gt; at all times (see &lt;a
45href="https://neovim.io/doc/user/provider.html#clipboard-osc52"&gt;nvimdoc&lt;/a&gt;):&lt;/p&gt;
46&lt;div class="sourceCode" id="cb5"&gt;&lt;pre
47class="sourceCode lua"&gt;&lt;code class="sourceCode lua"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;vim&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="va"&gt;g&lt;/span&gt;&lt;span class="op"&gt;.&lt;/span&gt;&lt;span class="va"&gt;clipboard&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
48&lt;span id="cb5-2"&gt;&lt;a href="#cb5-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="va"&gt;name&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;OSC 52&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
49&lt;span id="cb5-3"&gt;&lt;a href="#cb5-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="va"&gt;copy&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
50&lt;span id="cb5-4"&gt;&lt;a href="#cb5-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;+&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;]&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;require&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;vim.ui.clipboard.osc52&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;).&lt;/span&gt;copy&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;+&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;),&lt;/span&gt;&lt;/span&gt;
51&lt;span id="cb5-5"&gt;&lt;a href="#cb5-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;]&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;require&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;vim.ui.clipboard.osc52&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;).&lt;/span&gt;copy&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;),&lt;/span&gt;&lt;/span&gt;
52&lt;span id="cb5-6"&gt;&lt;a href="#cb5-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="op"&gt;},&lt;/span&gt;&lt;/span&gt;
53&lt;span id="cb5-7"&gt;&lt;a href="#cb5-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="va"&gt;paste&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
54&lt;span id="cb5-8"&gt;&lt;a href="#cb5-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;+&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;]&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;require&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;vim.ui.clipboard.osc52&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;).&lt;/span&gt;paste&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;+&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;),&lt;/span&gt;&lt;/span&gt;
55&lt;span id="cb5-9"&gt;&lt;a href="#cb5-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="op"&gt;[&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;]&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="fu"&gt;require&lt;/span&gt;&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;vim.ui.clipboard.osc52&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;).&lt;/span&gt;paste&lt;span class="op"&gt;(&lt;/span&gt;&lt;span class="st"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;),&lt;/span&gt;&lt;/span&gt;
56&lt;span id="cb5-10"&gt;&lt;a href="#cb5-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt; &lt;span class="op"&gt;},&lt;/span&gt;&lt;/span&gt;
57&lt;span id="cb5-11"&gt;&lt;a href="#cb5-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
58&lt;p&gt;If you are inside &lt;code&gt;nvim&lt;/code&gt; inside &lt;code&gt;tmux&lt;/code&gt; inside
59an &lt;code&gt;ssh&lt;/code&gt; session inside &lt;code&gt;st&lt;/code&gt;, you neeed all of the
60above tweaks. &lt;code&gt;nvim&lt;/code&gt; will pass the contents around to
61&lt;code&gt;tmux&lt;/code&gt;, which in turn will pass the contents to
62&lt;code&gt;st&lt;/code&gt;, which should pass it to your system clipboard.&lt;/p&gt;</description>
63<link>https://peppe.rs/posts/OSC-52/</link>
64<pubDate>Wed, 27 Nov 2024 22:56:00 +0000</pubDate>
65<guid>https://peppe.rs/posts/OSC-52/</guid>
66</item>
67<item>
68<title>Introducing Tablespoon</title>
69<description>&lt;p&gt;&lt;a href="https://git.peppe.rs/languages/tbsp"&gt;tbsp&lt;/a&gt; (tree-based
70source-processing language) is an awk-like language that operates on
71tree-sitter syntax trees. To motivate the need for such a program, we
72could begin by writing a markdown-to-html converter using
73&lt;code&gt;tbsp&lt;/code&gt; and &lt;a
74href="https://github.com/tree-sitter-grammars/tree-sitter-markdown"&gt;tree-sitter-md&lt;/a&gt;.
75We need some markdown to begin with:&lt;/p&gt;
76&lt;pre&gt;&lt;code&gt;# 1 heading
77
78content of first paragraph
79
80## 1.1 heading
81
82content of nested paragraph&lt;/code&gt;&lt;/pre&gt;
83&lt;p&gt;For future reference, this markdown is parsed like so by
84tree-sitter-md (visualization generated by &lt;a
85href="https://git.peppe.rs/cli/tree-viz"&gt;tree-viz&lt;/a&gt;):&lt;/p&gt;
86&lt;pre&gt;&lt;code&gt;document
87| section
88| | atx_heading
89| | | atx_h1_marker &amp;quot;#&amp;quot;
90| | | heading_content inline &amp;quot;1 heading&amp;quot;
91| | paragraph
92| | | inline &amp;quot;content of first paragraph&amp;quot;
93| | section
94| | | atx_heading
95| | | | atx_h2_marker &amp;quot;##&amp;quot;
96| | | | heading_content inline &amp;quot;1.1 heading&amp;quot;
97| | | paragraph
98| | | | inline &amp;quot;content of nested paragraph&amp;quot;&lt;/code&gt;&lt;/pre&gt;
99&lt;p&gt;Onto the converter itself. Every &lt;code&gt;tbsp&lt;/code&gt; program is written
100as a collection of stanzas. Typically, we start with a stanza like
101so:&lt;/p&gt;
102&lt;pre&gt;&lt;code&gt;BEGIN {
103 int depth = 0;
104
105 print(&amp;quot;&amp;lt;html&amp;gt;\n&amp;quot;);
106 print(&amp;quot;&amp;lt;body&amp;gt;\n&amp;quot;);
107}&lt;/code&gt;&lt;/pre&gt;
108&lt;p&gt;The stanza begins with a “pattern”, in this case, &lt;code&gt;BEGIN&lt;/code&gt;,
109and is followed a block of code. This block specifically, is executed
110right at the beginning, before traversing the parse tree. In this
111stanza, we set a “depth” variable to keep track of nesting of markdown
112headers, and begin our html document by printing the
113&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
114&lt;p&gt;We can follow this stanza with an &lt;code&gt;END&lt;/code&gt; stanza, that is
115executed after the traversal:&lt;/p&gt;
116&lt;pre&gt;&lt;code&gt;END {
117 print(&amp;quot;&amp;lt;/body&amp;gt;\n&amp;quot;);
118 print(&amp;quot;&amp;lt;/html&amp;gt;\n&amp;quot;);
119}&lt;/code&gt;&lt;/pre&gt;
120&lt;p&gt;In this stanza, we close off the tags we opened at the start of the
121document. We can move onto the interesting bits of the conversion
122now:&lt;/p&gt;
123&lt;pre&gt;&lt;code&gt;enter section {
124 depth += 1;
125}
126leave section {
127 depth -= 1;
128}&lt;/code&gt;&lt;/pre&gt;
129&lt;p&gt;The above stanzas begin with &lt;code&gt;enter&lt;/code&gt; and
130&lt;code&gt;leave&lt;/code&gt; clauses, followed by the name of a tree-sitter node
131kind: &lt;code&gt;section&lt;/code&gt;. The &lt;code&gt;section&lt;/code&gt; identifier is
132visible in the tree-visualization above, it encompasses a
133markdown-section, and is created for every markdown header. To
134understand how &lt;code&gt;tbsp&lt;/code&gt; executes above stanzas:&lt;/p&gt;
135&lt;pre&gt;&lt;code&gt;document ... depth = 0
136| section &amp;lt;-------- enter section (1) ... depth = 1
137| | atx_heading
138| | | inline
139| | paragraph
140| | | inline
141| | section &amp;lt;----- enter section (2) ... depth = 2
142| | | atx_heading
143| | | | inline
144| | | paragraph
145| | | | inline
146| | | &amp;lt;----------- leave section (2) ... depth = 1
147| | &amp;lt;-------------- leave section (1) ... depth = 0 &lt;/code&gt;&lt;/pre&gt;
148&lt;p&gt;The following stanzas should be self-explanatory now:&lt;/p&gt;
149&lt;pre&gt;&lt;code&gt;enter atx_heading {
150 print(&amp;quot;&amp;lt;h&amp;quot;);
151 print(depth);
152 print(&amp;quot;&amp;gt;&amp;quot;);
153}
154leave atx_heading {
155 print(&amp;quot;&amp;lt;/h&amp;quot;);
156 print(depth);
157 print(&amp;quot;&amp;gt;\n&amp;quot;);
158}
159
160enter inline {
161 print(text(node));
162}&lt;/code&gt;&lt;/pre&gt;
163&lt;p&gt;But an explanation is included nonetheless:&lt;/p&gt;
164&lt;pre&gt;&lt;code&gt;document ... depth = 0
165| section &amp;lt;-------- enter section (1) ... depth = 1
166| | atx_heading &amp;lt;- enter atx_heading ... print &amp;quot;&amp;lt;h1&amp;gt;&amp;quot;
167| | | inline &amp;lt;--- enter inline ... print ..
168| | | &amp;lt;----------- leave atx_heading ... print &amp;quot;&amp;lt;/h1&amp;gt;&amp;quot;
169| | paragraph
170| | | inline &amp;lt;--- enter inline ... print ..
171| | section &amp;lt;----- enter section (2) ... depth = 2
172| | | atx_heading enter atx_heading ... print &amp;quot;&amp;lt;h2&amp;gt;&amp;quot;
173| | | | inline &amp;lt;- enter inline ... print ..
174| | | | &amp;lt;-------- leave atx_heading ... print &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;
175| | | paragraph
176| | | | inline &amp;lt;- enter inline ... print ..
177| | | &amp;lt;----------- leave section (2) ... depth = 1
178| | &amp;lt;-------------- leave section (1) ... depth = 0 &lt;/code&gt;&lt;/pre&gt;
179&lt;p&gt;The &lt;a
180href="https://git.peppe.rs/languages/tbsp/tree/examples"&gt;examples&lt;/a&gt;
181directory contains a complete markdown-to-html converter, along with a
182few other motivating examples.&lt;/p&gt;
183&lt;h3 id="usage"&gt;Usage&lt;/h3&gt;
184&lt;p&gt;The &lt;code&gt;tbsp&lt;/code&gt; evaluator is written in rust, use cargo to
185build and run:&lt;/p&gt;
186&lt;pre&gt;&lt;code&gt;cargo build --release
187./target/release/tbsp --help&lt;/code&gt;&lt;/pre&gt;
188&lt;p&gt;&lt;code&gt;tbsp&lt;/code&gt; requires three inputs:&lt;/p&gt;
189&lt;ul&gt;
190&lt;li&gt;a &lt;code&gt;tbsp&lt;/code&gt; program, referred to as “program file”&lt;/li&gt;
191&lt;li&gt;a language&lt;/li&gt;
192&lt;li&gt;an input file or some input text at stdin&lt;/li&gt;
193&lt;/ul&gt;
194&lt;p&gt;You can run the interpreter like so (this program prints an overview
195of a rust file):&lt;/p&gt;
196&lt;pre&gt;&lt;code&gt;$ ./target/release/tbsp \
197 -f./examples/code-overview/overview.tbsp \
198 -l rust \
199 src/main.rs
200module
201 └╴struct Cli
202 └╴trait Cli
203 └╴fn program
204 └╴fn language
205 └╴fn file
206 └╴fn try_consume_stdin
207 └╴fn main&lt;/code&gt;&lt;/pre&gt;</description>
208<link>https://peppe.rs/posts/introducing_tablespoon/</link>
209<pubDate>Thu, 01 Aug 2024 19:18:00 +0000</pubDate>
210<guid>https://peppe.rs/posts/introducing_tablespoon/</guid>
211</item>
212<item>
15<title>Snip Snap</title> 213<title>Snip Snap</title>
16<description>&lt;p&gt;I regularly switch between exactly two things while working, a 214<description>&lt;p&gt;I regularly switch between exactly two things while working, a
17“current” and an “alternate” item; a lot of tools I use seem to support 215“current” and an “alternate” item; a lot of tools I use seem to support