Skip to content
forked from orhun/daktilo

Turn your keyboard into a typewriter! ⌨️📇

License

Notifications You must be signed in to change notification settings

arda-guler/daktilo

 
 

Repository files navigation

Turn your keyboard into a typewriter! 📇

GitHub Release Crate Release Coverage
Continuous Integration Continuous Deployment Documentation

daktilo-demo.mp4

daktilo ("typewriter" in Turkish, pronounced "duck-til-oh") is a small command-line program that plays typewriter sounds every time you press a key. It also offers the flexibility to customize keypress sounds to your liking. You can use the built-in sound presets to create an enjoyable typing experience, whether you're crafting emails or up to some prank on your boss.

✨ Inspiration: "Taking notes in class with my typewriter"

Now you can recreate this moment without the actual need for a physical typewriter!

Table of Contents

Getting Started

Simply run daktilo for the classic typewriter effect.

There are also different presets available:

Preset Name Description
default the classic typewriter effect
basic an alternative and more basic typewriter effect
musicbox plays random notes like a music box
ducktilo quack quack 🦆

To list the presets:

daktilo --list

To use a preset:

daktilo --preset musicbox

Installation

Packaging status

Packaging status

Cargo

daktilo can be installed from crates.io:

cargo install daktilo

The minimum supported Rust version is 1.70.0.

Arch Linux

daktilo can be installed from the official repositories using pacman:

pacman -S daktilo

Binary releases

See the available binaries for different targets from the releases page.

Build from source

  1. Clone the repository.
git clone https://github.com/orhun/daktilo && cd daktilo/
  1. Build.
CARGO_TARGET_DIR=target cargo build --release

Binary will be located at target/release/daktilo.

Usage

daktilo [OPTIONS]

Options:

-v, --verbose          Enables verbose logging [env: VERBOSE=]
-p, --preset <PRESET>  Sets the name of the sound preset to use [env: PRESET=]
-l, --list             Lists the available presets
-c, --config <PATH>    Sets the configuration file [env: DAKTILO_CONFIG=]
-i, --init             Writes the default configuration file
-h, --help             Print help
-V, --version          Print version

Configuration

daktilo can be configured with a configuration file using the TOML format.

The path of the configuration file can be specified via --config argument or DAKTILO_CONFIG environment variable.

It can also be placed in one of the following global locations:

  • <config_dir> / daktilo.toml
  • <config_dir> / daktilo/daktilo.toml
  • <config_dir> / daktilo/config

<config_dir> depends on the platform as shown in the following table:

Platform Value Example
Linux $XDG_CONFIG_HOME or $HOME/.config /home/orhun/.config
macOS $HOME/Library/Application Support /Users/Orhun/Library/Application Support
Windows {FOLDERID_RoamingAppData} C:\Users\Orhun\AppData\Roaming

See daktilo.toml for the default configuration options.

You can also create the default configuration file in the current directory with --init flag:

daktilo --init

Adding custom presets

The configuration file consists of an array of sound_preset entries.

To define an array in TOML, you can create different sections as follows:

[[sound_preset]]
name = "custom"
key_config = []

[[sound_preset]]
name = "another_custom"
key_config = []
disabled_keys = []

As shown above, sound_preset consists of 2 entries:

  • name: The name of the preset. It will be used in conjunction with --preset flag. e.g. --preset custom
  • key_config: An array of key press/release events for assigning audio files to the specified keys. It can also be used to control the volume etc.
  • disabled_keys: An array of keys that will not be used for playback.
Click for the list of available keys.

Alt, AltGr, Backspace, CapsLock, ControlLeft, ControlRight, Delete, DownArrow, End, Escape, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, Home, LeftArrow, MetaLeft, MetaRight, PageDown, PageUp, Return, RightArrow, ShiftLeft, ShiftRight, Space, Tab, UpArrow, PrintScreen, ScrollLock, Pause, NumLock, BackQuote, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9, Num0, Minus, Equal, KeyQ, KeyW, KeyE, KeyR, KeyT, KeyY, KeyU, KeyI, KeyO, KeyP, LeftBracket, RightBracket, KeyA, KeyS, KeyD, KeyF, KeyG, KeyH, KeyJ, KeyK, KeyL, SemiColon, Quote, BackSlash, IntlBackslash, KeyZ, KeyX, KeyC, KeyV, KeyB, KeyN, KeyM, Comma, Dot, Slash, Insert, KpReturn, KpMinus, KpPlus, KpMultiply, KpDivide, Kp0, Kp1, Kp2, Kp3, Kp4, Kp5, Kp6, Kp7, Kp8, Kp9, KpDelete, Function, Unknown

As an example, here is how you can configure key_config:

key_config = [
  { event = "press", keys = "return", files = [{ path = "ding.mp3", volume = 1.0 }] },
]
  • event: "press" or "release"
  • keys: A regular expression (regex) for matching the keys.
  • files: An array of files.
    • path: The absolute path of the file. If the file is embedded in the binary (i.e. if it is inside sounds/ directory) then it is the name of the file without full path.
    • volume: The volume of the sound. The value 1.0 is the "normal" volume (unfiltered input). Any value other than 1.0 will multiply each sample by this value.

If you have defined multiple files for a key event, you can also specify a strategy for how to play them:

key_config = [
  { event = "press", keys = ".*", files = [{ path = "1.mp3" }, { path = "2.mp3" }], strategy = "random" },
]

Currently supported strategies are:

  • strategy = "random": pick a random file from the list and play it.
  • strategy = "sequential": play the files sequentially.

Here is how you can combine everything together:

[[sound_preset]]
# Custom sound preset named "custom"
name = "custom"

# Key configurations for various events
key_config = [
  # When a key starting with "Key" is pressed, play 1.mp3, 2.mp3, and 3.mp3 sequentially
  { event = "press", keys = "Key*", files = [
    { path = "1.mp3" },
    { path = "2.mp3" },
    { path = "3.mp3" },
  ], strategy = "sequential" },

  # When a key starting with "Key" is released, play 4.mp3
  { event = "release", keys = "Key*", files = [
    { path = "4.mp3" },
  ] },

  # When a key starting with "Num" is pressed, play num.mp3 at a very high volume (10.0)
  { event = "press", keys = "Num*", files = [
    { path = "num.mp3", volume = 10.0 },
  ] },

  # When any key is pressed, play a random sound from cat.mp3, dog.mp3, or bird.mp3
  { event = "press", keys = ".*", files = [
    { path = "cat.mp3" },
    { path = "dog.mp3" },
    { path = "bird.mp3" },
  ], strategy = "random" },
]

# Disabled keys that won't trigger any sound events
disabled_keys = ["CapsLock", "NumLock"]

Acknowledgements

Huge thanks to H. Arda Güler for giving me the idea for this project, sharing the inspiration behind it and implementing the first iteration in Python.

Kudos! 👾

Donations

Support me on GitHub Sponsors Support me on Patreon Support me on Patreon

If you find daktilo and/or other projects on my GitHub useful, consider supporting me on GitHub Sponsors or becoming a patron!

License

License: MIT License: Apache 2.0

Licensed under either of Apache License Version 2.0 or The MIT License at your option.

🦀 ノ( º _ º ノ) - respect crables!

Copyright

Copyright © 2023, Orhun Parmaksız

About

Turn your keyboard into a typewriter! ⌨️📇

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%