WIP

xd

Table of Contents

1 emacs – Run flycheck on all buffers after save

To just see the working solution, scroll down to The Result. Flycheck only runs on current buffer. If you make a change in a file that effects another file, buffer of the second file will not get notified and thus flycheck is not going to run on that buffer. So what we need to do is add an after save hook which runs flycheck on other buffers, but only on file buffers. We don’t want to run flycheck on temporary buffers or so. It seems simple but it took some time for me to get there, because I know too little about elisp.

First, we need a function that runs flycheck on given buffer. There is a function called flycheck-buffer but it only checks current buffer. But it turns out this is how elisp functions generally work and there is a way to get around that. Using with-current-buffer buffer function we can run any function on given buffer. with-current-buffer changes current buffer to given buffer, runs the function and restores current buffer to old one. So:

(defun flycheck-buffer* (buffer)
  "Runs flycheck on given BUFFER."
  (with-current-buffer buffer
    (flycheck-buffer)))

Another thing we need is that a function that returns all buffers. It’s buffer-list. We need to remove temporary buffers and the current buffer from that list. Here it goes:

(defun other-file-buffer-list nil
  "Returns the list of all file buffers except currently open one and temporary buffers and stuff."
  (delq (current-buffer)
    (remove-if-not 'buffer-file-name (buffer-list))))

And the last function we need is this:

(defun flycheck-all-file-buffers nil
    "Simply run flycheck on all file buffers."
    (interactive)
    (mapc 'flycheck-buffer* (other-file-buffer-list)))

Lastly, we need to add this function to after-save-hook. But I want to be a able to disable/enable this feature whenever I want. Because if you have a lot of buffers open, this feature may cause some laggyness on save events.

(defun enable-flycheck-all-file-buffers-on-save nil
  (interactive)
  (add-hook 'after-save-hook 'flycheck-all-file-buffers))

(defun disable-flycheck-all-file-buffers-on-save nil
  (interactive)
  (remove-hook 'after-save-hook 'flycheck-all-file-buffers))

1.1 The Result

Run M-x then call enable-flycheck-all-file-buffers-on-save. From now on, when you save a file, other files will be flychecked too. To disable it, call disable-flycheck-all-file-buffers-on-save.

(defun flycheck-buffer* (buffer)
  "Runs flycheck on given BUFFER."
  (with-current-buffer buffer
    (flycheck-buffer)))

(defun other-file-buffer-list nil
  "Returns the list of all file buffers except currently open one and temporary buffers and stuff."
  (delq (current-buffer)
    (remove-if-not 'buffer-file-name (buffer-list))))

(defun flycheck-all-file-buffers nil
    "Simply run flycheck on all file buffers."
    (interactive)
    (mapc 'flycheck-buffer* (other-file-buffer-list)))

(defun enable-flycheck-all-file-buffers-on-save nil
  (interactive)
  (add-hook 'after-save-hook 'flycheck-all-file-buffers))

(defun disable-flycheck-all-file-buffers-on-save nil
  (interactive)
  (remove-hook 'after-save-hook 'flycheck-all-file-buffers))

2 Automatize your logins with gnome-keyring (and optionally with KeePassXC)

Storing passwords in plain-text is not an encouraged act but typing your password every time you start an application is also cumbersome. To solve this dilemma, the easiest solution I came up with is using gnome-keyring to store my passwords. I’m not using gnome either but gnome-keyring does not have much dependencies and a lot of applications already requires it. So I believe gnome-keyring is a good choice. The thing I want to achieve is something like this: – Store my passwords in gnome-keyring so that they are encrypted. – When I login to my computer, gnome-keyring automatically gets unlocked so that programs can get required passwords without hassling with me.

But there is a problem in this particular solution, at least for me. I’m using KeePassXC to manage my passwords, so copying all those passwords-or just the required ones, still a lot- to gnome-keyring is not feasible. So I need to do something about that too. Installing/configuring gnome-keyring

Skip this step if you already have a running gnome-keyring.

  • Just install these packages: gnome-keyring, libsecret and seahorse.
  • You need to create a keyring named login so that when you login, that particular keyring gets unlocked. To create that, open seahorse and follow File -> New -> Password Keyring. Name it as login and as password enter your login password. This method works with login managers generally, if you are not using one, you need to figure it out. But getting gnome-keyring unlocked at login is not a big deal, if its locked, the first time a program requests for a password, gnome-keyring will show a prompt and ask for your password to unlock that keyring. Subsequent password requests will go silently because you have unlocked that keyring.

2.1 Adding passwords to gnome-keyring

We need to create a Stored Password in login keyring that we’ve just created. But the problem is it is not possible to create Stored Passwords with attributes in seahorse, we need to attach attributes to passwords because the command-line tool secret-tool requires them while querying for a password. So what you need to do is, simply create your Stored Password using secret-tool:

secret-tool store --label=Mail name mail_password

Then it will ask for the password. name and mailpassword are key-value pairs. You can add more attributes like them or change them as you wish. Now you can see the added password in seahorse. (You may wonder why we did not specify keyring name while adding password. Because this command adds your password to your default keyring, which is the login keyring. If it’s not the default one, right-click on it in seahorse and set as default.)

If you are using KeePassXC like me, my advise would be instead of duplicating your passwords in gnome-keyring, only add your keepass password in gnome-keyring: secret-tool store --label=KeePass name keepass_password I’ll get to the usage later.

2.2 Querying for a password

So you have your passwords in gnome-keyring and you want to supply that passwords to some program. Of course every program has different method for storing/getting your password. I’m going to use mutt as an example (it’s a command-line mail client). But first, lets see how do we get our password:

secret-tool lookup name mail_password

This command will print your password. To configure mutt to use gnome-keyring, simply add this line to your muttrc:

set imap_pass=`secret-tool lookup name mail_password`

2.3 KeePassXC

To get a password from KeePassXC, use this command:

secret-tool lookup name keepass | keepassxc-cli show /path/to/keepass/db/file "/path/to/password/entry"

But this prints a lot of information. To just get the value of Password entry, use something like this:

secret-tool lookup name keepass | keepassxc-cli show /path/to/keepass/db/file "/path/to/password/entry" | grep "Password: " | head -n 1 | cut -c 11-

To see your database structure, use this command:

secret-tool lookup name keepass | keepassxc-cli ls /path/to/keepass/db/file

This will only list top level entries and directories, you can add, for example, “/email” to this command and it will print out entries under /email folder.

For your muttrc, you need to add this:

set imap_pass=`secret-tool lookup name keepass | keepassxc-cli show /path/to/keepass/db/file "/path/to/password/entry" | grep "Password: " | head -n 1 | cut -c 11-`

2.4 Security concerns

You may say that this kind of approach exposes all of our passwords to all user-level programs. Actually this is kind of behavior I’m trying to achieve here, so that I don’t need to type my passwords for each program. If you have a malicious program in your system, it will eventually get your passwords anyway. But gnome-keyring gives you a lot of flexibility. You can lock your keyring after your programs logged in or you can keep your keyring locked all the time(in that case, every time a program tries to use your password, gnome-keyring will ask for your user password. So you will just use one password for your every login which is also better than typing different passwords to different programs every time) etc. This is a much better solution than keeping your passwords as plain-text in your configuration files or typing them manually every time.

Also you can probably do the same things with kwallet if you are using KDE. Just search for equivalent commands for kwallet.

3 Nice little curl commands

Here are some curl friendly web services that you can use in your terminal:

3.1 Weather

  • curl wttr.in Displays a nice weather report.
    • You can also specify city-code like this: wttr.in/city_name
    • If the output is too long for your terminal, just use it with less: curl wttr.in | less -R

3.2 IP

  • curl https://api.ipify.org Simply shows your public ip.
  • curl ipinfo.io Prints a formatted JSON that contains information about your ip.

3.3 File/URL

  • curl -F'file=@yourfile.png' https://0x0.st Uploads specified file to 0x0.st and returns the url.
  • curl -F'shorten=http://example.com/some/long/url' https://0x0.st Shortens the given URL.
    • Just visit 0x0.st for more information.
  • curl --upload-file ./hello.txt https://transfer.sh/hello.txt Uploads specified file to transfer.sh and returns the url.
    • This service is more sophisticated, you can set some constraints to your files and stuff. Visit transfer.sh for more examples with curl.

3.4 Cheat sheets

  • curl http://cheat.sh/tar Shows a simple cheatsheet for specified command (in this case tar)
  • curl https://raw.githubusercontent.com/tldr-pages/tldr/master/pages/common/tar.md Same thing with above but this uses tldr. But there are some problems:

    • raw.githubusercontent.com/tldr-pages/tldr/master/pages/ common / tar .md

    The first bold part may be one of these: common, linux. The second bold part is the command itself. If the command is linux-spesific, its under the linux folder obviously and most of the other things goes to common. You can create a small script that takes command as input and checks the folders one by one and returns if it finds an existing page. This is left as an exercise for the reader. (or you may just simply install a client, visit tldr).

3.5 Translate

This is not really curl friendly but it works.

curl -s -A "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0" "https://translate.google.com/m?sl=FROM&tl=TO&ie=UTF-8" --data-urlencode "q=WORD_OR_SENTENCE" | grep -Po '<div dir="ltr" class="t0">\K[^<]*'
  • Change FROM to source language code, for example en for English.
  • Change TO to destination language code, for example tr for Turkish.
  • Change WORD_OR_SENTENCE to anything you want. You can use spaces.
  • Wrap this to a bash script and enjoy easy translations.

This example demonstrates how you can get the relevant information from an ordinary website. Always use the mobile versions if available because it is easier to parse them.

3.6 Cryptocurrency rates

  • curl rate.sx Shows the cryptocurrency rates.
    • Run curl rate.sx/:help for more information about usage.

3.7 ASCII QR Codes

  • curl qrenco.de/STRING Turns given string/url into an ASCII art QR code.

3.8 WebDAV

If you are using a service that supports WebDAV, you can use these simple curl commands to download/upload files to your service. You can also do more sophisticated things with curl but if you need more than just downloading/uploading files then it's better to use a client dedicated for that service.

  • Downloading:
    • curl -u LOGIN:PASSWORD https://WEBSITE.com/DAV_PATH/REMOTE_FILE --output FILE
    • Downloads the server_dav://REMOTE_FILE to FILE
  • Uploading:
    • curl -u LOGIN:PASSWORD -T FILE https://WEBSITE.com/DAV_PATH/REMOTE_FILE
    • Uploads FILE to server_dav://REMOTE_FILE

It's better not to write your password while using these commands. If you remove the password part it will just simply show you a password prompt when you execute these commands which better than exposing your password to bash history.

3.9 Convert Documents

I'll just leave a link here: docverter.com. You can convert nearly any format to any other one using this service. It has a nice and clear API. The website provides curl command examples.

4 TODO Programming AVR microcontrollers in Linux (Specifically ATMega)

The Windows way of doing that is just using ATMEL Studio but we don’t have it in Linux. As a customization freak, I’ll just write the steps of how to compile and flash your program to an AVR microcontroller and leave the rest for you. So integrating this steps into your favorite IDE, if you are using one, is your job.

4.1 Tools

These are the tools that we need to install, just pull them from your package manager (These package names exists in Arch Linux repos, they might differ in other distros repositories):

  • avr-gcc GNU C compiler for AVR architecture
  • avr-libc AVR libraries
  • avr-binutils Some AVR tools, we need it to create hex files from compiled programs, because avrdude needs a hex file instead of a binary to flash.
  • avrdude A dude that is required to perform flashing

4.2 Steps

  1. Write your program. Let’s say you named it main.c.
  2. Compile it.

    avr-gcc main.c -Os -Wall -mmcu=atmega32 -o main_bin
    
    • Change -mmcu from atmega32 to your devices name. You can find your devices MCU from here.
  3. Convert your program to hex from binary.

    avr-objcopy -j .text -j .data -O ihex main_bin "main.hex"
    
  4. Flash it.

    avrdude -c usbasp -p m32 -U flash:w:"main.hex"
    
    • Here you can see -p option. You need to specify it according to your device. The list is here.
    • Also here you can see -c option. It specifies programmer type. In my case it’s usbasp. So you should change it to whatever you are using. Here is the list of programmer that avrdude accepts. (If your programmer isn’t in the list, which is probably not the case, you can specify your programmer as shown in the same page and save it to a ini file. Then add -C option that points the ini file you just write.)

4.3 The correct way of using avrdude

When you do the last step, you will get an error that says you don’t have permissions. You can just run avrdude with sudo and it will work this time. But of course this is not the preferred way to do it. What you need to do is write an udev rule so we can access programmer without root privileges.

  1. Create this file: /etc/udev/rules.d/55-avr-programmer.rules
  2. Write this into file:

    # USB-ASPcable
    ATTR{idVendor}=="16c0", ATTR{idProduct}=="05dc", GROUP="plugdev", MODE="0666"
    
    • Again, as you can see this configuration is for my programmer, usbasp. You need to change idVendor and idProduct according to your device. To find these values, just run lsusb(If you are using usb extender cord or something like that, it is possible that lsusb might not display your device. Just connect your programmer directly to your PC if that is the case):

      > lsusb
      ...
      Bus 003 Device 010: ID 16c0:05dc Van Ooijen Technische Informatica shared ID for use with libu
      ...
      
    • In sixth column, you can see your devices vendor id and product id in this format VENDOR_ID:PRODUCT_ID. So edit your file according to this information.
  3. You may restart your computer or just use these commands to reload udev rules:

    > sudo udevadm control --reload-rules
    > sudo udevadm trigger
    
    • You may need to unplug your programmer and plug it back. From now on you can use avrdude without needing root privileges.

4.4 TODO Simplifying the process

You can create a bash (or fish or zhs) script to simplify compiling and flashing process. Here is the fish script that I use(Creating a bash script is an exercise for reader, actually I am too lazy to do that right now):

function avrflash
    mkdir -p build
    cd build
    avr-gcc ../$argv -Os -Wall -mmcu=atmega32 -o main_bin
    avr-objcopy -j .text -j .data -O ihex main_bin "main.hex"
    avrdude -c usbasp -p m32 -U flash:w:"main.hex"
    cd ..
end

5 Kotlin Function Application

I often write some code like this:

val result = someData.split(...)
	.map { ... }
	.filter { ... }
	.reduce { ... }
	....

someFunction(result)

As you can see last line of the code is breaking the beautiful flow of chained functions. One can rewrite this as:

someFunction(someData.split(...)
	.map { ... }
	.filter { ... }
	.reduce { ... }
	....)

Which seems better to me but not as good as this:

someData.split(...)
	.map { ... }
	.filter { ... }
	.reduce { ... }
	....
	.apply(::someFunction)

I don’t know if there is a standard way of doing this but here is my solution:

infix fun <T, R> T.apply(func: (T) -> R): R = func(this)

So this extension function applies its object to the function that it took as an argument and returns the result of application. You can use it as an infix operator, if you want to:

someData.split(...)
	.map { ... }
	.filter { ... }
	.reduce { ... }
	.... apply ::someFunction

You can even chain function applications:

someData.split(...)
	.map { ... }
	.filter { ... }
	.reduce { ... }
	....
	.apply(::fun1)
	.apply(::fun2)
	.apply(::fun3)
	.apply { fun4(it) }

Which is same as:

someData.split(...)
	.map { ... }
	.filter { ... }
	.reduce { ... }
	.... apply ::fun1 apply ::fun2 apply ::fun3 apply { fun4(it) }

Also this code is equivalent of this one:

val result = someData.split(...)
	.map { ... }
	.filter { ... }
	.reduce { ... }
	....

fun4(fun3(fun2(fun1(result))))

6 TODO Median cut algorithm in Qt/C++

https://web.archive.org/web/20170430204854/http://blog.isamert.net:80/median-cut-algorithm-in-qt-c/ I needed a simple color quantization algorithm for my project. I didn’t want to use any other program/library for this simple job. So I implemented median cut with Qt. I just used the explanation of the algorithm in Wikipedia, I didn’t make any other research, so the code is not well optimized but it just works. I’ll try to explain step by step:

We have an image with an arbitrary number of pixels and want to generate a palette of X colors. The very first thing we need to is putting all the pixels in a list. By pixels, I mean their Rgb data. Then we need to find the color channel(red, green, blue) that has the most wide range. Let’s implement this:

QString filePath = "someimage.png"; int colorcount = 256; // The color count that we want to reduce our image.

QList<QRgb> pixels; QImage img(filePath);

/ For finding color channel that has the most wide range, / we need to keep their lower and upper bound. int lowerred = qRed(img.pixel(0, 0)), lowergreen = qGreen(img.pixel(0, 0)), lowerblue = qBlue(img.pixel(0, 0)); int upperred = 0, uppergreen = 0, upperblue = 0;

// Just loop trough all the pixels for (int x = 0; x < img.width(); ++x) { for (int y = 0; y < img.height(); ++y) { QRgb rgb = img.pixel(x, y); / Get rgb data of a particular pixel if (!pixels.contains(rgb)) { / If we have the same pixel, we don't need it twice or more lowerred = std::min(lowerred, qRed(rgb)); lowergreen = std::min(lowergreen, qGreen(rgb)); lowerblue = std::min(lowerblue, qBlue(rgb));

upperred = std::max(upperred, qRed(rgb)); uppergreen = std::max(uppergreen, qGreen(rgb)); upperblue = std::max(upperblue, qBlue(rgb)); pixels.append(rgb); } } }

We have upper bounds and lower bounds of the color channels, so just find out the one that has widest range:

int red = upperred - lowerred; int green = uppergreen - lowergreen; int blue = upperblue - lowerblue; int max = std::max(std::max(red, green), blue);

Then we need to short our pixels list according to the channel we just found out. For example, if the blue channel has the greatest range, then a pixel with an RGB value of (32, 8, 16) is less than a pixel with an RGB value of (1, 2, 24), because 16 < 24.

qSort(pixels.begin(), pixels.end(), [max,red,green,blue](const QRgb& rgb1, const QRgb& rgb2){ if (max == red) / if red is our color that has the widest range return qRed(rgb1) < qRed(rgb2); / just compare their red channel else if (max == green) //… return qGreen(rgb1) < qRed(rgb2); else if (max == blue) return qBlue(rgb1) < qBlue(rgb2); }); / We just used qSort here. / As comparison function, we sent a lambda function // that compares two rgb color according to our selected color channel.

After sorting our list, we need to move the upper half of the list to another list, then we have two list. For these two list, we will do the same thing until we get X lists (So if we want to reduce our color palette to 16 colors, we need to repeat this step until we get 16 lists.).

QList<QList<QRgb>> lists; int listsize = pixels.size() / colorcount;

for (int i = 0; i < colorcount; ++i) { QList<QRgb> list; for (int j = listsize * i; j < (listsize * i) + listsize; ++j) { list.append(pixels.at(j)); } lists.append(list); }

We got our lists. After that, we can get the average of each list and we can build our X colored palette or we can just get the median of each list. I didn’t observe so much difference, so I’m going with the easy one.

QVector<QRgb> palette; for (QList<QRgb> list: lists) { palette.append(list.at(list.size() / 2)); }

We build up our X color palette. The next thing I am going to do is convert our original image color palette to our new palette. Actually there is a Qt function for that but it has a bug.(I’ll explain it later) So we need to implement this.

QVector<QRgb> palette; for (QList<QRgb> list: lists) { palette.append(list.at(list.size() / 2)); }

QImage out(img.width(), img.height(), QImage::FormatARGB32); for (int x = 0; x < img.width(); ++x) { for (int y = 0; y < img.height(); ++y) { out.setPixel(x,y, palette[closestMatch(img.pixel(x, y), palette)]); } }

In this piece of code, we just create a QImage that has same size of our original image and format. Then we loop through all the pixels in our original image and find the closest color from our new palette then set that color to corresponding pixel of our new QImage object. And that’s it.

There is one function that needs explanation in this code, closestMatch. I just took it from the Qt source code. Actually, QImage has a function named convertToFormat. You can use this function to change the format of your image and also it lets you to change color palette of your image. The function definition goes like this: QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Qt::ImageConversionFlags flags = Qt::AutoColor) const and it’s definition says:

Returns a copy of the image converted to the given format, using the specified colorTable. Conversion from 32 bit to 8 bit indexed is a slow operation and will use a straightforward nearest color approach, with no dithering.

So we can simply use this function to convert any image using our palette. But there is a one problem, if you don’t want to change your image format(so your source and output image has the same format), it just simply returns the image itself without converting to our palette. So I extracted the part that it finds the closest color to given color from a vector:

static inline int pixeldistance(QRgb p1, QRgb p2) { int r1 = qRed(p1); int g1 = qGreen(p1); int b1 = qBlue(p1); int a1 = qAlpha(p1);

int r2 = qRed(p2); int g2 = qGreen(p2); int b2 = qBlue(p2); int a2 = qAlpha(p2);

return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2) + abs(a1 - a2); }

static inline int closestMatch(QRgb pixel, const QVector<QRgb> &clut) { int idx = 0; int currentdistance = INTMAX; for (int i=0; i<clut.size(); ++i) { int dist = pixeldistance(pixel, clut.at(i)); if (dist < currentdistance) { currentdistance = dist; idx = i; } } return idx; }

Author: Isa Mert Gurbuz

Created: 2018-08-02 Thu 22:08

Validate