All posts searchable

In chronological order below. To search, use search function in browse. In most browsers this is CTRL+F.

Latest posts:
  • 2021-03-05 Ranger file manager.
    keywords: python, pip, files, cli. Plaintext:
    Ranger is a CLI filemanager written in Python. Personally I use this program as my only file manager except for conventional Linux CLI. The program starts quickly and can be run over SSH. It's available in Pypi and can be installed with pip3: pip install ranger-fm Github: ranger/ranger. Homepage: After installing the program, start it in the current directory by running ranger. It follows the VIM-style of shortcuts with hjkl. These keys are used for navigation in the file system. Quit the program with q. Keep in mind that ranger distinguishes between capital key presses and non-capital ones. Navigate by find To quickly open a file / directory in ranger press f and type the name of the file until it's opened. When you've typed out enough of the filename / directory to select it, it'll open. While in the find mode, press <tab> to select between matching files / directories. Then you can press <enter> to open the selected entry. Tabs Use ALT-<number>. Will create a new tab in the current directory. When you switch to a new tab, it'll be created. If you have many tabs open, the key q will be used to close the current tab. Copy / paste Similar to vims line-copy and line-paste. Select a file for copy with yy and copy it to the selected directory with pp. For cut / move operations use dd. To to an actual remove operation run dD. Select many files Use <space>to select a file. v inverts current selection (If no files are selected, the inverse selects all files). V executes a kind of visual mode like in Vim. Navigate up and down to select multiple files. Press V again to turn it off. Deselect everything with uv. Copy / Cut / Paste works with multiple files selected. Most operations work on multiple files. Order files Press o for a variety of ways to order the files. Unlike vim, ranger is more useful when it comes to commands which are based on multiple keys. After pressing the first key of a command sequence, ranger will show a pop-up dialog with all available continuing keys. Calculate size of directory Run dc to collect the total size of a directory. Follow this up with a os to order by file / directory sizes. Bulk rename Like vim, run commands by pressing :. The command :bulkrename opens up an external text editor for renaming all selected files. Then after editing the file and closing the editor, ranger performs a rename operation based on what you put into the external editor. Run commands There are a few ways to run shell commands in ranger. The easiest is to press s. It just provides a prompt for running a shell command. When the command is done, ranger pops back up again. To see what is printed on stdout / stderr from the program run the command by pressing # instead. After the command is done the output is display in less. Command macros Commands have access to macros which contain information about the current file selection: The tab-wise scope of the macros can be selected with a number specified. Read the included manual for more about that. Filter Press zf to input a filter. Files that does not have the filter string in the name, will be hidden from view. To remove the filter again, specify a empty string as filter. Go to There are default shortcuts to common file system paths. Press g to get the list of predefined shortcuts. Go to bookmark You can add your own bookmarks, they'll be in their own list. Go to a directory and press m, now press a key. This shortcut can now be accessed by pressing ' and the assigned key. This is similar to how vim does bookmarks. Tags You can select files on a global scope across the file system. To mark a file with a tag press either t to mark it with the default tag (*) or press " followed by a custom key. Unlike the selection previously mentioned, tags are not limited to the active working directory. What's the point of tags? You can ranger with the argument --list-tagged="X", where x is the tag you want to focus on. This command prints the path of all files selected with the specified tag. It's useful for piping into other commands. For example: ranger --list-tagged="*" | xargs tar cfz my_files.tar.gz This command copies all tagged file into a compressed tar ball. FYI: the tags are stored in the file ~/.local/share/ranger/tagged. Image preview This only works if the terminal emulator you are using can display bitmap graphics. Follow the guide in the ranger wiki. Other links: Sixel - Wikipedia, information on the standard alacritty/alacritty: A cross-platform, OpenGL terminal emulator., terminal that support graphics Flat directories mode Normally you enter or select a directory to see the content of it. To get an expanded view of the content of all sub directories in the current working directory. Use the command :flat 1. 1 means one level of sub directories. Put any number of sub directories you want to expand. -1 expand all levels.
  • 2021-01-19 Regex101, a good regex tool.
    keywords: regex, regex101. Plaintext:
    Link to the site: Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript. This site provides excellent debugging for regular expressions. Just don't forget to select the correct standard for your case. Screenshot with example from other regex post:
  • 2021-01-19 Python Regex.
    keywords: python, regex, re, snippet. Plaintext:
    Here are some code chunks for the normal regex cases in Python. When using Regex in python you can either use the regular expression as an argument to the operation. Or compile an existing expression. I'll do the compiled method on this page. Python regex strings is a special type of string. To express a regex string, add the letter r before the string. Like the example below. Compile a regular expression: import re __PDF = re.compile(r'\<.*(?:value)=\"(.*?\.pdf)\"\>(.*?)\<') This regular expression will find HTML links to .pdf files on this page: Reference Guides - The Khronos Group Inc. Single match match = __PDF.match('<option value="gltf20-reference-guide.pdf">glTF 2.0</option>') # '<option value="gltf20-reference-guide.pdf">glTF 2.0<' # 'gltf20-reference-guide.pdf' # 'glTF 2.0' Note group 0 is the entire match. If there is no match, match will be None. Iterate multiple matches for match in __PDF.finditer(content): print('Found a pdf link: {}'.format( Output: Found a pdf link: collada_reference_card_1_4.pdf Found a pdf link: gltf20-reference-guide.pdf Found a pdf link: egl-1-4-quick-reference-card.pdf Found a pdf link: opencl30-reference-guide.pdf Found a pdf link: opencl22-reference-guide.pdf Found a pdf link: opencl21-reference-guide.pdf Found a pdf link: opencl20-quick-reference-card.pdf Found a pdf link: opencl-1-2-quick-reference-card.pdf ...
  • 2021-01-15 Using the Python Markdown library.
    keywords: python, markdown, blog. Plaintext:
    For my blog , I use the Pypi package Markdown to convert Markdown files to HTML. All my text is stored as .md. The library works well once the extensions are all setup. I use the extensions extra, meta, codehilite and markdown_checklist.extension. If you're used to Github markdown. These extensions will give you a similar setup. The extension codehilite gives you syntax highlights compatible with Pygments. To get the actual CSS-tags for the HTML, pygments includes a CLI tool for that: pygmentize -S default -f html -a .codehilite The -a .codehilite is necessary because of a class name used by codehilite. I use meta data in the beginning of my Markdown files. For this I use the meta extension. Snippet for how I use the library: import markdown md = markdown.Markdown(extensions=['extra', 'meta', 'codehilite', 'markdown_checklist.extension']) doc = md.convert(text_md) args = md.Meta() References: The package documentation: Python-Markdown — Python-Markdown 3.3.3 documentation. All available extensions: Extensions — Python-Markdown 3.3.3 documentation. Pygments: Pygments · PyPI Markdown meta data: Meta-Data — Python-Markdown 3.3.3 documentation
  • 2021-01-15 Moved my blog.
    keywords: blog, markdown, static. Plaintext:
    I have now migrated my home page from a Hugo setup to a home made Markdown to HTML system. The only thing missing from the previous site, is RSS. I'll get to that next.
  • 2020-01-21 Pattern exhaustion in Haskell.
    keywords: pattern exhaustion, haskell. Plaintext:
    Haskell is supposedly safe and crashing is not possible in a pure environment. But one of the easiest way to crash is by simply passing a arguments to a function that does not implement the arguments. For example, the following function: func :: Int -> Int func 1 = 2 func 2 = 3 Just crash it with: *Main> func 1 2 *Main> func 2 3 *Main> func 3 *** Exception: e.hs:(2,1)-(3,10): Non-exhaustive patterns in function func To avoid this, just use the flag -fwarn-incomplete-patterns in Haskell. The same can also be done by putting this in your source file: {-# OPTIONS_GHC -fwarn-incomplete-patterns #-} Now Haskell is even more safe!
  • 2019-11-23 xargs in shell - Forget the for loop.
    keywords: xargs, map, loop, cli. Plaintext:
    If you supply the shell command xargs with the right commands, it will function the same way as a for loop. But more like a functional map command. Normally xargs will execute a provided command once and append everything from pipe as arguments: > echo 1 2 3 4 | xargs echo These arguments were provided: These arguments were provided: 1 2 3 4 Adding the parameters -n 1 will execute the command time for each 1 piped arguments. > echo 1 2 3 4 | xargs -n 1 echo Run for each argument: Run for each argument: 1 Run for each argument: 2 Run for each argument: 3 Run for each argument: 4 If your variable argument for the command is the last argument, this will work fine. But if not. xargs has the parameter -I. Unfortunately this parameter make the command work different: > echo 1 2 3 4 | xargs -n 1 -I {} echo Run with {} as argument Run with 1 2 3 4 as argument -n 1 no longer works... There is a work around. A delimiter has to be given. In the example it will be space: -d " ". However, -d messes up the delimiter by not striping aways other white spaces. When using echo, a newline character will be put at the end of the arguments. We can remove any newline from the xargs input by using an additional before our intended xargs: > echo 1 2 3 4 | xargs echo -n | xargs -d " " -I {} echo Run with {} as argument Run with 1 as argument Run with 2 as argument Run with 3 as argument Run with 4 as argument Here, the part xargs echo -n will take all piped incoming arguments and print them space separated and -n will prevent a newline character from being printed at the end.
  • 2019-06-01 The real reason to use snippets.
    keywords: snippets, vim, neovim, ultisnips, development, documentation. Plaintext:
    As a ~~Vim~~ Neovim user, I often indulge in the novelty of browsing plugins. For some reason, I have missed snippets. If you don't know what they are, do a quick internet search. Or have a look at Ultisnips. They have an excellent set of screen cast tutorials. It is available for Vim/Neovim. Most modern editors seams to have snippets plugins available. At first glance, I looks like it is just a way for the user to code faster by using exandable macros. As this might be true, I have come to like it for a different reason. In my daily programming, I often jump between languages and environments. Sometimes it has been a while since I used the language the last time. Which puts me in a situation where I have to refresh my memmory on the basics of the language. Things like for-loops, or what syntax to write the documentation in. Of course, one can just search on the internet and read up on it in a few minutes. But snippets do the same thing. For example, if I have forgotten how to write a class in Javascript. I can just search for a class snippet. The snippet will exand to the correct syntax. And I didn't have to search for something basic like that. Saves a lot of time and doesn't break your focus.
  • 2019-03-18 Scanning 3D scenes with a camera.
    keywords: meshroom, 3d scanning, scan 3d, camera, mesh, photo. Plaintext:
    I had a look at this guide on 3D scanning objects and gave it a try. The guide describes how to take pictures with a normal camera and make a 3D representation of it. For the mesh to be decent, you must take a lot of pictures. In my test, I took 21 photos. Covering as many angles as possible. The lighting must be consistent in all images. So I had to be quick in taking the pictures outside, while the sun was behind clouds. I used my Canon D500 set on manual mode. With ISO 100 and a shutter speed of 1/100. The scene in the photograph is 3D scanning friendly. There's no reflective surfaces. No semi transparent objects, like leaves. In the guide they use the open source program Meshroom. I installed the program on my gaming PC, which has a beefy graphics card. The program utilized GPU acceleration when processing the scene. First I tried running on my laptop. But I had to cancel the processing, because it took too long. After importing the images into Meshroom, I just ran it with the default settings enabled. Ca 5 minutes later, the scene had been constructed from the images: Neat! To use this mesh in a real-time graphics situation, the amount of vertices should be cut down:
  • 2018-10-16 Basic HTTP authentication in NGINX.
    keywords: nginx, HTTP authentication, password, openssl, systemd. Plaintext:
    Exposing protected and private files on a public web server is generally speaking a bad idea... But... Sometimes the extra work to hide the files behind thick security is just not worth the time. Here's a quick guide on adding basic HTTP login prompt to a nginx site. First we will create a user account for prompt to allow. Run this as root/administrator. sudo -i cd /etc/nginx echo -n 'USERNAME:' >> .htpasswd USERNAME should be the user name you want. Generate a hashed password. This command will prompt you for the password. openssl passwd -apr1 >> .htpasswd The .htpasswd file should look something like this: test$apr1$8DpQHldW$Ja1/.dDGt561RIYw2P7CR1 Change the ownership of the file to whatever your web server user is running as. chown www-data:www-data .htpasswd In this case, the user will be www-data Edit your nginx site configuration file. Normally these files are located under /etc/nginx/sites-enabled. Find or create a location section that you want to add the prompt for. Add auth_basic and auth_basic_user_file to it. Like this: location /my_secret/ { auth_basic "Secret log in message"; auth_basic_user_file /etc/nginx/.htpasswd; } The Secter log in message will be visible on the login prompt. At this point, all you need is to restart the nginx server and you should be set. systemctl restart nginx
  • 2018-08-30 Fast proofreading with redpen.
    keywords: writing, redpen, proofreading, docker, alias, markdown, cli. Plaintext:
    Proofreading is something you want to-do quickly and on the fly. If you have docker installed you can download the entire redpen server. docker pull dai0304/techdoc-redpen Of course, you're not interested in running a server. You just want to proof read your document. Bind this alias in your terminal: alias docker-redpen='docker run -v $(pwd):/redpen -w /redpen --rm -it dai0304/techdoc-redpen' Start a new terminal and go to your document directory. Now type docker-redpen. Your work directory is mounted into the container. And you are in the shared volume directory. Proof read your file: redpen Apart from internal redpen information, you should get remarks on your text. Unless everything is perfect. Redpen can read all kinds of formats. Personally I use it on my markdown documentation.
  • 2018-01-16 Ludum Dare 40 entry.
    keywords: bestfund inc., game, ludum dare 40, ld40, tic-80, github, stratergy, cash, investment, shooting, payroll. Plaintext:
    This game is done with TIC-80. The code is available on github. Play the game View the page on the Ludum dare site.
  • 2017-05-30 Combozard, new game released.
    keywords: game, comozard, pico-8,, combo, ai, magic, 2d, sidescroller, bat. Plaintext:
    I’ve just finished a small game Combozard. It’s follows the classical platforming style of the NES/SNES era. Furthermore, the game is short to fit the short attention span of browser based gamers. Thus below is the link to the game: Play in browser Play on The game is created in PICO-8 which I got in a Humblebundle a long time ago. While the environment is excellent for game assets building in retro style, it falls short on the coding part. Incidentally this is evaded by using some tools. Given that you use an external editor for the code, you can create bigger projects. Otherwise the code editor will be a problem. The game duration is short as mentioned. In fact it can be completed in 30 seconds. Nonetheless the game is suppose to be hard for this duration. The difficulty lies in the execution of key combos (called spells in game). Instructions about the spells are available on different places on the map. With this in mind the player must learn each spell to progress. Enemy AI units come as two different types. Namely crawlers and bats. Crawlers will simply walk straight until a reaching a wall, then turn around. And bats attach by flying and land on predefined landing points on the map. Image showing bat AI landing points. The bat AI will select a fly destination that is closer to the player position. ...To conclude, be sure to play the game and check out the code over at Github.
  • 2017-03-20 Export PICO-8 sound effects.
    keywords: pico-8, sfx, sound effect, export, extract. Plaintext:
    The sound effect editor in PICO-8 is a good tool for making retro style sound effects. While it fits well into the work flow of the environment that it lives in. Maybe we can take this functionality outside of the PICO-8 world. Extracting data The crew behind the system has implemented a function export to extract content from the cartridges. This function can be called from both the internal command line interface and the scripted game code. Because memorizing this command is cumbersome we will write this in the code editor. Like this: export("sfx%d.wav") As a result new sound files will be created in the working directory each time we run the cartridge. Trimming the silence Consequently all sound effects that don’t make use of the full length available in the sound editor will contain silence for remaining time of the sound. Either you accept this since the audience of the effect wont hear it. Or you trim of the silence. Since game engines doesn’t have infinite sound buffers to play sounds with, we’ll cut it off. SoX – Sound eXchange is a program that can manipulate sound files. For this post we will use the ability to remove silence. For Debian users; installation of SoX can be done with this command: apt-get install sox To begin with the removal of silence, we can execute this command on a sound file: sox input.wav output.wav silence -l 0 1 0.5 0.1% For the purpose of automation and applying this to many files, we can put a few rules in a Makefile. IDIR=input ODIR=output INPUT=$(wildcard input/*.wav) OUTPUT=$(INPUT:input/%.wav=output/%.wav) all: $(OUTPUT) $(ODIR)/%.wav: $(IDIR)/%.wav sox $< $@ silence -l 0 1 0.5 0.1% Exporting the music So far the export has been done on all sound effects. For the purpose of getting the music out, a different procedure has to be done. As it turns out, depending on what view the user is in the editor, different things will be exported. To export music, the music view has to be active in the editor. Then the following command will export the music. export("music.wav") With that in mind the user has to be in the music view in the editor when the cartridge is executed. And with regards to the sound effects, as long a the enumeration flag %d is in the export command, they will be exported. Finally we can update our export script in the editor: export("music.wav") export("sfx%d.wav") Thus music and trimmed sound effects are at our disposal!
  • 2017-03-10 Git archive without .gitignore.
    keywords: git, gitattributes, gitignore, git archive. Plaintext:
    The built-in archive functionality in Git is handy. Indeed an easy way of making a clean archive of the source. Leaving all Git meta files. However one common type of Git file will be included in the archive; .gitignore. So to tell the archiver to exclude all .gitignore files you can simply add the file .gitattributes to your repository. Then include these lines in it: .gitignore export-ignore .gitattributes export-ignore As a result the export-ignore flag will tell Git to ignore all .gitignore. Additionally we should also exclude the new file .gitattributes by listing it in this file. Finally you can make an archive of your Git repository excluding all version control system files: git archive HEAD --prefix=myproject/ -o myproject.tar.gz
  • 2016-04-29 Using the Dvorak keyboard layout.
    keywords: None. Plaintext:
    I’ve been using Dvorak for about 18 months now and it has been a pleasant experience. I’m actually not sure if I type faster then before, but I do physically move my hands less then I did before which gives a nice feel. I find Qwerty cumbersome in the way I always seemed to have my fingers “trip” over each others. This doesn’t happen with Dvorak. The biggest downside of Dvorak for me is that many programs have their keyboard shortcuts organized for the left hand on a Qwerty layout. For example Undo-Cut-Copy-Paste. These keys are often used and are easy to access with Qwerty. Since I mostly use Vim when I type, this is not a problem for me. But as soon as I use a program that conforms to the standard layout these shortcuts are harder to use. Blender is hard to use with Dvorak. It relies on Qwerty focused shortcuts for basic operations. Another problem is games. It’s annoying having to configure keys for all games and If you’re using a nationalized version of Dvorak like me (Swedish Dvorak, Svorak), some keys simply wont be assignable because the game doesn’t recognize them. Sharing your computer becomes a problem since most other users wont be familiar with your layout. So you end up having to navigate various settings menus or running a command to switch layout each time someone else touches your keyboard. The best solution I’ve come that solves both these problems is to bind a global keyboard shortcut in your window manager to switch between Qwerty and Dvorak. In Windows you can toggle keyboard layout with SHIFT+ALT. In Linux you can bind these a command: setxkbmap us # English setxkbmap se # Swedish setxkbmap dvorak # Dvorak setxkbmap se dvorak # Svorak I’ve bound the shortcut CTRL+Meta+1 to set Dvorak (Svorak) and CTRL+Meta+2 to set Qwerty. This way if you’re using a program that is designed for a specific layout (games, blender etc.) or letting someone else use your computer, you can activate the Qwerty layout. In the window manager i3 you can put this in your configuration file (.i3/config): bindsym $mod+Ctrl+1 exec "setxkbmap us dvorak" bindsym $mod+Ctrl+2 exec "setxkbmap us"
  • 2016-04-11 Making Haskell useful.
    keywords: haskell, c, ffi, ghc, model, io. Plaintext:
    During the last week I’ve been trying to brush up on my Haskell. Me trying to learn Haskell has been a reoccurring event for the past years. This video was a real turn off last time. But this time I finally think I see how Haskell can be useful. The new discovery is the Haskell FFI system. The Foreign Function Interface. It’s a simple system that allows you to integrate your Haskell program right into other native binaries. This means, the things that Haskell is useless with, low level operations, performance code, platform specifics, unsafe code, general IO etc; can be implemented in another language. And you are left with a more pure implementation of the code model in Haskell. I’ve made a small code example showing of basic FFI: {-# LANGUAGE ForeignFunctionInterface #-} import Foreign import Foreign.C.Types foreign import ccall hello :: CInt -> IO () main :: IO () main = do putStrLn "Hello World" mapM_ hello [1..4] And the non Haskell part in C: #include <stdio.h> void hello(int x) { printf("Let's print this number: %d\n", x); } This code can be compiled using different compilers: ghc -c ffi.hs -o ffi.o gcc -c ffi_c.c -o ffi_c.o ghc ffi.o ffi_c.o -o ffi You can get a Haskell environment that limits IO operations to your non Haskell part. There you can put all your dirty impure code, and write it in a language that is actually suitable for dirty operations.
  • 2016-01-29 Private SMS torrent service.
    keywords: torrent, sms, kickass, npm, javascript, transmission, twilio, android. Plaintext:
    Last year I looked into the possibility of communication between phone and computer via SMS. SMS should be a outdated way of communicating, but it seams that a lot of people (including myself) still use it every day. It’s a very reliable way of communication. The thing I wanted to do with SMS, is a torrent downloading service that is connected to my computer at home. So when I’m out and hear about a movie that sounds interesting, I can just send a SMS and the download will start. The plan was to integrate this into the Node.js server I’m running. Thanks to the community at NPM this is can be done with a few libraries. SMS One way of getting SMS to a computer could probably be, by connecting a phone to a computer and have the computer control the phone. But that’s too much physical work for a programmer. There are many SMS and phone services online where you can buy telephone numbers cheaply. I tried one called Twilio. I bought a Swedish SMS enabled number that costs $1 USD per month + ~$0.03 USD per SMS. They have API bindings for Node.js. Torrent searching Kickass is a good site for finding torrents. If you search NPM for Kickass you’ll find a lot of libraries for searching the site. Putting it all together First you search with sök and a query. The response is the match with the highest amount of seeders. A ID for the match is given. Then you send ladda and the ID of the match. The download will now start. When you get home later the download is probably completed. Resources NPM Twilio NPM Kickass API NPM Transmission