diff --git a/README.md b/README.md
index 4d2f4de5f8281545cb2877917fd7d652ba1562e5..a49bf413337929998b4c7071f5c119df95da2402 100644
--- a/README.md
+++ b/README.md
@@ -32,10 +32,9 @@ The manual way of installing and setting up lektor:
 ```sh
 meson build
 ninja -C build
-./build/lktadm --init                   # Modify mkv, if the metadata ar already set do not do this.
-# Create and modify the ini file manually, must be at ~/.config/lektor/config at the moment.
-sqlite3 /home/kara/kara.db < init.sql   # Create the database.
-./build/lktadm --populate-all           # Populate the sqlite database.
+./build/lktadm init database            # Create the database
+./build/lktadm init metadata            # Modify mkv, if the metadata ar already set do not do this
+./build/lktadm init populate            # Papulate the database with karas on the filesystem
 ```
 
 You may need to put the `lib_window_x11.so` in the right directory to have the
diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h
index 5e0a17b6be084c4f42423c76cff622486e4600d9..98817754a011d9eae462de1cd8520880c3c0adc8 100644
--- a/inc/lektor/cmd.h
+++ b/inc/lektor/cmd.h
@@ -17,8 +17,12 @@ typedef void (*lkt_cmd_callback)(struct lkt_cmd_args *);
 struct lkt_cmd_opt {
     const char *name;
     lkt_cmd_callback call;
+    const char *help;
+    struct lkt_cmd_opt *sub;
 };
 
 /* Parse the command line with the list of options. No parameter may be NULL.
    Does not return. */
 noreturn void lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv, void (*help)(void));
+
+void lkt_cmd_help(struct lkt_cmd_opt *opts, const char *name);
diff --git a/inc/lektor/config.h b/inc/lektor/config.h
index 52f5de2cbd08b79a7018b3dc0877abc40e619f88..75aaced78226f816388555dae0994c879fafdb93 100644
--- a/inc/lektor/config.h
+++ b/inc/lektor/config.h
@@ -22,9 +22,9 @@ static const char *const lkt_default_config_file =
     "\n"
     "; Database configuration.\n"
     "[database]\n"
-    "kara_dir = /home/kara               ; Root for the mkv files\n"
-    "db_path = /home/kara/kara.db        ; Sqlite3 database, must be rw\n"
-    "init_script = /opt/lektor/init.sql  ; Init script for the database\n"
+    "kara_dir = /home/kara                          ; Root for the mkv files\n"
+    "db_path = /home/kara/kara.db                   ; Sqlite3 database, must be rw\n"
+    "init_script = LKT_PREFIX/share/lektor/init.sql ; Init script for the database\n"
     "\n"
     "; Player configuration, the window where the karas\n"
     "; can be seen.\n"
@@ -38,20 +38,14 @@ static const char *const lkt_default_config_file =
     "\n"
     "; The WinX11 module configuration. Modules are .so files\n"
     "; loaded by lektor.\n"
-    "[module_winx11]\n"
-    "path = /opt/lektor/modules/lib_module_x11.so\n"
+    "[module_x11]\n"
+    "path = LKT_PREFIX/lib/lektor/lib_module_x11.so\n"
     "load_function = module_set_function\n"
     "xwallpaper = false\n"
     "\n"
-    "; Dummy module. A module is a .so file. two option must be\n"
-    "; present: the 'path' option which indicate the .so file to load.\n"
-    "; and the 'load_function' which is the name of the function used\n"
-    "; to load the module correctly.\n"
-    "[module_dummy]\n"
-    "path = /some/path/to/file.so\n"
-    "load_function = foo\n"
-    "specific_opt1 = 1\n"
-    "specific_opt2 = a string\n";
+    "[module_sdl2]\n"
+    "path = LKT_PREFIX/lib/lektor/lib_module_sdl2.so\n"
+    "load_function = module_set_function\n";
 
 /* It is just an alias to the consecutive use of config_detect_file and
    config_new function, with the return an '&&' between the two returns of the
diff --git a/meson.build b/meson.build
index 1184051085b5884573f28add51451d9bcd561f50..cd546e9d1bf2632598879b827ef67417ea074eeb 100644
--- a/meson.build
+++ b/meson.build
@@ -13,16 +13,11 @@ project( 'lektor'
                           ]
        )
 
-add_project_arguments('-march=native', language : 'c')
-
-cc      = meson.get_compiler('c')
-libdl   = cc.find_library('dl')
+libdl   = meson.get_compiler('c').find_library('dl')
 dep_x11 = dependency('x11', required : false)
 dep_mpv = dependency('mpv', required : false)
 dep_sdl = dependency('sdl2', required : false)
 
-# Sources
-
 ## Sources for the server
 core_sources =  [ 'src/mkv/bufferfd.c'
                 , 'src/mkv/write.c'
@@ -70,6 +65,7 @@ srv = executable( meson.project_name() + 'd'
                 , files('src/main/server.c')
                 , include_directories : includes
                 , dependencies : [ bin_deps ]
+                , install : true
                 )
 
 # Admin executable
@@ -77,12 +73,14 @@ metadata = executable( 'lktadm'
                      , files('src/main/lktadm.c', 'src/cmd.c')
                      , include_directories : includes
                      , dependencies : bin_deps
+                     , install : true
                      )
 
 # Client executable
 lkt = executable( 'lkt'
                 , files('src/main/lkt.c', 'src/cmd.c')
                 , include_directories : includes
+                , install : true
                 )
 
 # X11 window module
@@ -92,6 +90,8 @@ if dep_x11.found() and dep_mpv.found()
                                , include_directories : includes
                                , dependencies : [ dep_x11, dep_mpv ]
                                , link_with : lib
+                               , install : true
+                               , install_dir : 'lib/lektor'
                                )
 endif
 
@@ -102,5 +102,12 @@ if dep_sdl.found() and dep_mpv.found()
                                , include_directories : includes
                                , dependencies : [ dep_sdl, dep_mpv ]
                                , link_with : lib
+                               , install : true
+                               , install_dir : 'lib/lektor'
                                )
 endif
+
+# Install
+install_data('scripts/init.sql', install_dir : 'share/lektor')
+install_man('doc/lektord.1')
+meson.add_install_script('scripts/install.sh')
diff --git a/init.sql b/scripts/init.sql
similarity index 98%
rename from init.sql
rename to scripts/init.sql
index c835e98a26731a1f1c4d884528c0cdbc87c820dd..3f36cb0a701e9e062c57390e4acc7a741ac4c835 100644
--- a/init.sql
+++ b/scripts/init.sql
@@ -91,7 +91,7 @@ CREATE TABLE IF NOT EXISTS users
   , PRIMARY KEY (username, password)
   ) WITHOUT ROWID;
 
-INSERT INTO OR REPLACE users (username, password) VALUES ('sakura', 'hashire');
+INSERT OR REPLACE INTO users (username, password) VALUES ('sakura', 'hashire');
 
 
 -- The stickers table
@@ -141,3 +141,5 @@ CREATE VIEW IF NOT EXISTS queue_ AS
     priority,
     queue.position AS old_position
   FROM queue;
+
+.exit
diff --git a/scripts/install.sh b/scripts/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..213e4d297b180ad3dd690cbb977f0053e75a6872
--- /dev/null
+++ b/scripts/install.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# Usefull things
+alias die='exit 1'
+if [[ $OSTYPE == "linux-gnu" ]] ; then alias sed="sed -i" ; fi
+if [[ $OSTYPE == "darwin" ]] || [[ $OSTYPE == "freebsd"* ]] ; then alias sed="sed -i ''" ; fi
+LKT_INI=$MESON_INSTALL_PREFIX/etc/lektor.ini
+
+# Verify lktadm
+LKTADM=$MESON_INSTALL_PREFIX/bin/lktadm
+type $LKTADM &>/dev/null
+[ $? -ne 0 ] && echo "$LKTADM not found" && exit 1
+
+# Install files
+$LKTADM conf > $LKT_INI                             || die
+sed "s+LKT_PREFIX+$MESON_INSTALL_PREFIX+g" $LKT_INI || die
+mkdir /home/kara >&/dev/null                        || echo '/home/kara already exists'
+$LKTADM init database                               || die
diff --git a/src/cmd.c b/src/cmd.c
index 5e70e6d1dec9fefc9e7a381d377c51310f2dee5b..e13fd7674a7bd31792693a0685ccb93a4f99f461 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1,11 +1,13 @@
 #define _POSIX_C_SOURCE 200809L
 
 #include <lektor/cmd.h>
+#include <lektor/macro.h>
 #include <sys/types.h>
 #include <stdlib.h>
 #include <strings.h>
 #include <string.h>
 #include <stdio.h>
+#include <unistd.h>
 
 noreturn void
 lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv, void (*help)(void))
@@ -17,6 +19,7 @@ lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv, void (*help
     if (argc == 0 || *argv == NULL)
         goto no_args;
 
+    /* Find the command */
     while (it && it->name) {
         is_ok = (! strncasecmp(argv[0], it->name, strlen(argv[0])));
         call[is_ok] = it->call;
@@ -54,9 +57,45 @@ not_found:
     exit(EXIT_FAILURE);
 
 no_args:
-    help();
+    lkt_cmd_help(opts, NULL);
+    if (help)
+        help();
+    exit(EXIT_SUCCESS);
 
 not_exclusive:
     fprintf(stderr, "Failed to determine which option to choose, '%s' is not exclusive\n", argv[0]);
     exit(EXIT_FAILURE);
 }
+
+void
+lkt_cmd_help(struct lkt_cmd_opt *opts, const char *name)
+{
+    struct lkt_cmd_opt *it = opts;
+    int offset = 0, max_len = 1;
+
+    /* Get the maximan argument len */
+    while (it && it->name) {
+        int len = strlen(it->name);
+        max_len = MAX(max_len, len);
+        it = opts + (++offset);
+    }
+
+    /* Print the options */
+    it = opts;
+    offset = 0;
+    printf("COMMAND %s:\n", name);
+    while (it && it->name) {
+        printf("\t%*s  %s\n", max_len, it->name, it->help);
+        it = opts + (++offset);
+    }
+
+    /* Prints the sub commands help */
+    it = opts;
+    offset = 0;
+    write(1, "\n", sizeof(char));
+    while (it && it->name) {
+        if (it->sub)
+            lkt_cmd_help(it->sub, it->name);
+        it = opts + (++offset);
+    }
+}
diff --git a/src/config.c b/src/config.c
index 5df978b5ab42d01a0f44ab72695963bc9c7e404d..0568353ecc6664f43f9abc37dd8271851d0a61e7 100644
--- a/src/config.c
+++ b/src/config.c
@@ -124,7 +124,7 @@ config_detect_file(char *conf, size_t conf_len)
     if (getcwd(conf, conf_len - 1) != NULL) {
         strncat(conf, "/lektor.ini", conf_len - 1);
         fprintf(stderr, " . config_detect_file: trying %s\n", conf);
-        if (!access(conf, R_OK))
+        if (!access(conf, R_OK | F_OK))
             goto found;
     }
 
@@ -146,23 +146,23 @@ no_config_directory:
     /* Try the '/opt/lektor' file. */
     memcpy(conf, "/opt/lektor/lektor.ini", sizeof("/opt/lektor/lektor.ini"));
     fprintf(stderr, " . config_detect_file: trying %s\n", conf);
-    if (!access(conf, R_OK))
+    if (!access(conf, R_OK | F_OK))
         goto found;
 
     /* Try the '/usr/local/etc/lektor.ini' file. */
-    memcpy(conf, "/usr/local/etc/lektor.ini", sizeof("/opt/lektor/lektor.ini"));
+    memcpy(conf, "/usr/local/etc/lektor.ini", sizeof("/usr/local/etc/lektor.ini"));
     fprintf(stderr, " . config_detect_file: trying %s\n", conf);
-    if (!access(conf, R_OK))
+    if (!access(conf, R_OK | F_OK))
         goto found;
 
     /* Try the '/etc/lektor.ini' file. */
     memcpy(conf, "/etc/lektor.ini", sizeof("/etc/lektor.ini"));
     fprintf(stderr, " . config_detect_file: trying %s\n", conf);
-    if (!access(conf, R_OK))
+    if (!access(conf, R_OK | F_OK))
         goto found;
 
     /* Error */
-    fprintf(stderr, "config_detect_file: an error occured with file %s: %s",
+    fprintf(stderr, " ! config_detect_file: an error occured with file %s: %s\n",
             conf, strerror(errno));
     if (is_malloc)
         free(conf);
diff --git a/src/main/lkt.c b/src/main/lkt.c
index 8781e704f0aa1193d3fcf0147b1a4f0983a31600..b03a223006539ab4bbd93e7af20d269f739b7dbe 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -35,72 +35,26 @@ noreturn void
 help(void)
 {
     static const char *help_str =
-        "USAGE: lkt [OPTIONS] <COMMAND> [ARGS [...]]\n"
+        "OPTIONS:\n"
+        "  host         named of the lektor's host, can be resolved\n"
+        "  port         port on which lektor is listening\n"
         "\n"
-        "  OPTIONS:\n"
-        "    host         named of the lektor's host, can be resolved.\n"
-        "    port         port on which lektor is listening.\n"
+        "  options most be passed as one word (no spaced), such as the following:\n"
+        "  % lkt host=sakura port=6601 play\n"
         "\n"
-        "    options most be passed as one word (no spaced), such as the following:\n"
-        "    % lkt host=sakura port=6601 play\n"
+        "QUERY:\n"
+        "  A query is passed in argument of a COMMAND and is composed of:\n"
+        "   - The first word must be the type\n"
+        "   - the rest is used for the sqlite regex\n"
+        "  Supported types are: title, [a]ny, source, [auth]or, [lang]uage, type, title\n"
         "\n"
-        "  COMMANDS:\n"
-        "    help           display this help message.\n"
-        "    play [?idx]    toggle play/pause state of lektor, may start at a certain index.\n"
-        "    stop           stop the playback but not the window if it exists.\n"
-        "    status         get the status of lektor.\n"
-        "    current        get the currently playing song.\n"
-        "    prev           play previous kara in the queue.\n"
-        "    next           play the next kara in the queue.\n"
-        "    shuffle        shuffle lektor's playlist and play it from the begening.\n"
-        "    queue          tge queue sub command.\n"
-        "    plt            the playlist sub command.\n"
-        "    search         the search sub command.\n"
-        "\n"
-        "  QUEUE COMMANDS:\n"
-        "    pos <arg>      the qrgument can be a position or a range.\n"
-        "    <count>        prints the next songs in the queue.\n"
-        "    pop [pos]      pop a song in the queue.\n"
-        "    add <query>    add a kara to the queue with a query.\n"
-        "    seek <query>   seek the next song that matchs the query.\n"
-        "    delete <id>    delete the song by its id in the queue.\n"
-        "    clear          clear the queue.\n"
-        "    crop           crop the queue.\n"
-        "\n"
-        "  PLAYLIST COMMANDS:\n"
-        "    create <plt>               creates a playlist after the argument.\n"
-        "    destroy <plt>              delete a playlist after the argument.\n"
-        "    add <plt> <type> <query>   add something to a playlist from the database.\n"
-        "    delete <plt> <id>          delete domething from a playlist.\n"
-        "\n"
-        "  SEARCH COMMANDS:\n"
-        "    get <query>            prints the results of the query.\n"
-        "    add <query>            add to the queue and prints the results of the query.\n"
-        "    insert <query>         insert on top of the aueue and prints the results of the query.\n"
-        "    plt <plt> <query>      search inside a playlist and prints the results.\n"
-        "    count <query>          count the number of songs that matches the query.\n"
-        "    queue <query>          prints kara that matches from the queue.\n"
-        "\n"
-        "  QUERY:\n"
-        "    A query is passed in argument of a COMMAND and is composed of:\n"
-        "     - The first word must be the type\n"
-        "     - the rest is used for the sqlite regex\n"
-        "    Supported types are: title, [a]ny, source, [auth]or, [lang]uage, type, title\n"
-        "\n"
-        "  RANGE:\n"
-        "    A range is specified like BEGIN:END which implies from BEGIN to END included\n"
+        "RANGE:\n"
+        "  A range is specified like BEGIN:END which implies from BEGIN to END included\n"
         "\n";
     write(1, help_str, strlen(help_str));
     exit(EXIT_SUCCESS);
 }
 
-noreturn void
-help__(struct lkt_cmd_args *args)
-{
-    (void) args;
-    help();
-}
-
 static noreturn inline void
 fail(const char *message)
 {
@@ -428,7 +382,7 @@ noreturn void
 queue_pop__(struct lkt_cmd_args *args)
 {
     if (args->argc != 0)
-        fail("Invalid argument, the status command takes no arguments");
+        fail("Invalid argument, the pop command takes no arguments");
 
     int ret = EXIT_FAILURE, songid = 0;
     char buff[LKT_MESSAGE_MAX];
@@ -556,7 +510,7 @@ noreturn void
 queue_delete__(struct lkt_cmd_args *args)
 {
     if (args->argc != 1)
-        fail("Invalid argument, need onlt one argument");
+        fail("Invalid argument, need onlt one argument: queue delete <id>");
 
     static const char *cmd_id__ = "deleteid %d\nclose\n";
     int dumy = 0;
@@ -586,7 +540,7 @@ queue_add__(struct lkt_cmd_args *args)
     int i;
 
     if (args->argc < 1)
-        fail("Invalid argument, the add command should takes at least two arguments");
+        fail("Invalid argument, the add command should takes at least two arguments: queue add <query>");
 
     if (!lkt_valid_type(args->argv[0]))
         fail("Invalid argument, the type given to the add command is invalid");
@@ -622,7 +576,7 @@ noreturn void
 queue_seek__(struct lkt_cmd_args *args)
 {
     if (args->argc != 1)
-        fail("The seek command needs one argument");
+        fail("The seek command needs one argument: queue seek <id>");
 
     char *endptr, buf[3];
     long id = strtol(args->argv[0], &endptr, 0);
@@ -647,14 +601,14 @@ queue_pos__(struct lkt_cmd_args *args)
     char buff[LKT_MESSAGE_MAX], *endptr;
 
     if (args->argc != 1)
-        fail("Invalid argument for the pos command");
+        fail("Invalid argument for the pos command: queue pos <arg> where arg is a position or a range");
 
     long continuation = 0, up = 0;
 
     continuation = strtol(args->argv[0], &endptr, 0);
     if ((errno == ERANGE && (continuation == LONG_MAX || continuation == LONG_MIN)) || (errno != 0
             && continuation == 0) || (endptr == args->argv[0]))
-        fail("Invalid argument, not an integer");
+        fail("Invalid argument, not an integer: queue pos <arg> where arg is a position or a range");
 
     if (*endptr != '\0') {
         /* A range */
@@ -705,7 +659,7 @@ queue_list__(struct lkt_cmd_args *args)
     if (args->argc == 0)
         args->argv = LKT_QUEUE_DEFAULT;
     else if (args->argc != 1)
-        fail("Invalid argument");
+        fail("Invalid argument: queue <count?>");
 
     continuation = strtol(args->argv[0], &endptr, 0);
     if ((errno == ERANGE && (continuation == LONG_MAX || continuation == LONG_MIN)) || (errno != 0
@@ -760,7 +714,7 @@ plt_add__(struct lkt_cmd_args *args)
     FILE *sock = lkt_connect();
 
     if (args->argc < 3)
-        fail("Invalid argument, need at least three arguments");
+        fail("Invalid argument, need at least three arguments: plt add <plt> <query>");
 
     if (!lkt_valid_type(args->argv[1]))
         fail("Invalid argument, type for the query is invalid");
@@ -795,7 +749,7 @@ plt_delete__(struct lkt_cmd_args *args)
     int i;
 
     if (args->argc < 1)
-        fail("Invalid argument, need at least two arguments");
+        fail("Invalid argument, need at least two arguments: plt delete <plt> <id>");
 
     write_socket(sock, "playlistdelete ", strlen("playlistdelete "));
     write_socket(sock, args->argv[0], strlen(args->argv[0]));
@@ -821,7 +775,7 @@ noreturn void
 plt_destroy__(struct lkt_cmd_args *args)
 {
     if (args->argc != 1)
-        fail("Invalid argument, you may only specify the name of the playlist to delete");
+        fail("Invalid argument, you may only specify the name of the playlist to delete: plt destroy <plt>");
 
     FILE *sock = lkt_connect();
     char buff[2];
@@ -842,7 +796,7 @@ noreturn void
 plt_create__(struct lkt_cmd_args *args)
 {
     if (args->argc != 1)
-        fail("Invalid argument, you may only specify the name of the playlist to create");
+        fail("Invalid argument, you may only specify the name of the playlist to create: plt create <plt>");
 
     FILE *sock = lkt_connect();
     char buff[2];
@@ -865,7 +819,7 @@ noreturn void
 search_with_cmd__(struct lkt_cmd_args *args, const char *cmd)
 {
     if (args->argc < 2)
-        fail("Invalid number of arguments, need at least a valid query");
+        fail("Invalid number of arguments, need at least a valid query: search <action> <plt when action == plt> <query>");
 
     if (!lkt_valid_type(args->argv[0]))
         fail("Invalid type for the query");
@@ -940,33 +894,31 @@ search_queue__(struct lkt_cmd_args *args)
 /* Parsing stuff. */
 
 static struct lkt_cmd_opt options_queue[] = {
-    { .name = "pos",        .call = queue_pos__     },
-    { .name = "pop",        .call = queue_pop__     },
-    { .name = "add",        .call = queue_add__     },
-    { .name = "seek",       .call = queue_seek__    },
-    { .name = "delete",     .call = queue_delete__  },
-    { .name = "clear",      .call = queue_clear__   },
-    { .name = "crop",       .call = queue_crop__    },
+    { .name = "pos",        .call = queue_pos__,    .help = "Display the content of the queue by a range or a position" },
+    { .name = "pop",        .call = queue_pop__,    .help = "Pop the current kara in the queue"                         },
+    { .name = "add",        .call = queue_add__,    .help = "Add karas to the queue by a query"                         },
+    { .name = "seek",       .call = queue_seek__,   .help = "Seek a kara in the queu by a query"                        },
+    { .name = "delete",     .call = queue_delete__, .help = "Delete a kara by its id in the queue"                      },
+    { .name = "clear",      .call = queue_clear__,  .help = "Clear the queue"                                           },
+    { .name = "crop",       .call = queue_crop__,   .help = "Crop the queue"                                            },
     LKT_OPT_DEFAULT(queue_list__),
 };
 
 static struct lkt_cmd_opt options_plt[] = {
-    { .name = "help",       .call = help__          },
-    { .name = "add",        .call = plt_add__       },
-    { .name = "delete",     .call = plt_delete__    },
-    { .name = "destroy",    .call = plt_destroy__   },
-    { .name = "create",     .call = plt_create__    },
+    { .name = "add",        .call = plt_add__,      .help = "Add something to a playlist"               },
+    { .name = "delete",     .call = plt_delete__,   .help = "Delete karas from a playlist with a query" },
+    { .name = "destroy",    .call = plt_destroy__,  .help = "Delete a playlist"                         },
+    { .name = "create",     .call = plt_create__,   .help = "Create a playlist"                         },
     LKT_OPT_NULL,
 };
 
 static struct lkt_cmd_opt options_search[] = {
-    { .name = "help",       .call = help__          },
-    { .name = "get",        .call = search_get__    },
-    { .name = "add",        .call = search_add__    },
-    { .name = "insert",     .call = search_insert__ },
-    { .name = "plt",        .call = search_plt__    },
-    { .name = "count",      .call = search_count__  },
-    { .name = "queue",      .call = search_queue__  },
+    { .name = "get",        .call = search_get__,       .help = "Prints the results of the query"                                       },
+    { .name = "add",        .call = search_add__,       .help = "Prints and add the results to the queue"                               },
+    { .name = "insert",     .call = search_insert__,    .help = "Prints and inserts at the top of the queue the results of the query"   },
+    { .name = "plt",        .call = search_plt__,       .help = "Search inside a playlist and prints the results"                       },
+    { .name = "count",      .call = search_count__,     .help = "Count the number of karas matching the query and prints it"            },
+    { .name = "queue",      .call = search_queue__,     .help = "Search in the queue and prints the results of the query"               },
     LKT_OPT_NULL,
 };
 
@@ -998,17 +950,16 @@ plt__(struct lkt_cmd_args *args)
 }
 
 static struct lkt_cmd_opt options_[] = {
-    { .name = "help",       .call = help__    },
-    { .name = "current",    .call = current__ },
-    { .name = "play",       .call = play__    },
-    { .name = "next",       .call = next__    },
-    { .name = "previous",   .call = prev__    },
-    { .name = "queue",      .call = queue__   },
-    { .name = "shuffle",    .call = shuffle__ },
-    { .name = "status",     .call = status__  },
-    { .name = "stop",       .call = stop__    },
-    { .name = "plt",        .call = plt__     },
-    { .name = "search",     .call = search__  },
+    { .name = "current",  .call = current__, .help = "Get the current playing song"                         },
+    { .name = "play",     .call = play__,    .help = "Toggle play/pause, may starts at a specified index"   },
+    { .name = "next",     .call = next__,    .help = "Play the next kara in the queue"                      },
+    { .name = "previous", .call = prev__,    .help = "Play the previous kara in the queue"                  },
+    { .name = "queue",    .call = queue__,   .help = "The queue sub-command",          .sub = options_queue },
+    { .name = "shuffle",  .call = shuffle__, .help = "Shuffle the queue"                                    },
+    { .name = "status",   .call = status__,  .help = "Get the status of lektord"                            },
+    { .name = "stop",     .call = stop__,    .help = "Stop playing the queue, won't close lektord's window" },
+    { .name = "plt",      .call = plt__,     .help = "The playlist sub-command",         .sub = options_plt },
+    { .name = "search",   .call = search__,  .help = "The search sub-command",        .sub = options_search },
     LKT_OPT_NULL,
 };
 
diff --git a/src/main/lktadm.c b/src/main/lktadm.c
index f43d40c28a220f563898e39caa91ef846e29a500..41da3dd82a4fb8381d514a7f5ff375b4e91f64e2 100644
--- a/src/main/lktadm.c
+++ b/src/main/lktadm.c
@@ -219,7 +219,8 @@ init_database__(struct lkt_cmd_args *args)
     (void) args;
     pid_t pid;
     int wstatus, status, fd;
-    char *sqlite_args[] = { sqlite3_bin, db_path };
+    open_db();
+    char *sqlite_args[] = { sqlite3_bin, db_path, NULL };
 
     if ((pid = fork()) == 0) {
         if ((fd = open(init_script, O_RDONLY)) < 0)
@@ -228,8 +229,8 @@ init_database__(struct lkt_cmd_args *args)
         if (dup2(fd, 0) < 0)
             fail("Failed to duplicate %s to stdin", init_script);
 
-        execv(sqlite3_bin, sqlite_args);
-        fail("Failed to execute %s", sqlite3_bin);
+        execvp(sqlite_args[0], sqlite_args);
+        fail("Failed to execute %s: %s", sqlite3_bin, strerror(errno));
     }
 
     else if (pid < 0)
@@ -242,7 +243,7 @@ init_database__(struct lkt_cmd_args *args)
         while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
 
         if ((status = WEXITSTATUS(wstatus)))
-            fail("Children failed with status %d", status);
+            fail("Children failed with status %d\n", status);
     }
 
     exit(EXIT_SUCCESS);
@@ -277,10 +278,10 @@ download__(struct lkt_cmd_args *args)
 }
 
 static struct lkt_cmd_opt options_init[] = {
-    { .name = "database",   .call = init_database__ },
-    { .name = "populate",   .call = init_populate__ },
-    { .name = "metadata",   .call = init_metadata__ },
-    { .name = "file",       .call = init_file__     },
+    { .name = "database",   .call = init_database__,    .help = "Create an empty database"          },
+    { .name = "populate",   .call = init_populate__,    .help = "Populate database from kara on fs" },
+    { .name = "metadata",   .call = init_metadata__,    .help = "Set mdt for all kara in fs"        },
+    { .name = "file",       .call = init_file__,        .help = "Set mdt for a kara by its path"    },
     LKT_OPT_NULL,
 };
 
@@ -291,16 +292,16 @@ init__(struct lkt_cmd_args *args)
 }
 
 static struct lkt_cmd_opt options[] = {
-    { .name = "init",       .call = init__      },
-    { .name = "get",        .call = get__,      },
-    { .name = "download",   .call = download__  },
-    { .name = "cat",        .call = cat__,      },
-    { .name = "conf",       .call = conf__,     },
+    { .name = "init",       .call = init__,     .help = "The init sub-command",             .sub = options_init },
+    { .name = "get",        .call = get__,      .help = "Get the mdt of a kara by its id"                       },
+    { .name = "download",   .call = download__, .help = "Download a kara by its id"                             },
+    { .name = "cat",        .call = cat__,      .help = "Prints the mdt of a kara on the fs"                    },
+    { .name = "conf",       .call = conf__,     .help = "Prints out the default config"                         },
     LKT_OPT_NULL,
 };
 
 int
 main(int argc, const char **argv)
 {
-    lkt_cmd_parse(options, argc - 1, argv + 1, help);
+    lkt_cmd_parse(options, argc - 1, argv + 1, NULL);
 }
diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c
index ab619b24ac90e66e988c28761c5af80f29a0a8d8..94c2e957e5120a4e9bc81129ee2d42ed961a9f07 100644
--- a/src/module/module_sdl2.c
+++ b/src/module/module_sdl2.c
@@ -156,17 +156,14 @@ loop:
         break;
 
     case SDL_WINDOWEVENT:
-        if (event.window.event == SDL_WINDOWEVENT_EXPOSED) {
-            fprintf(stderr, " . sdl_thread__: Window exposed\n");
+        if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
             redraw = 1;
-        }
         break;
 
     case SDL_KEYDOWN:
         if (event.key.keysym.sym == SDLK_SPACE) {
             const char *cmd_pause[] = { "cycle", "pause", NULL };
             mpv_command_async((mpv_handle *) sdl2->mpv, 0, cmd_pause);
-            fprintf(stderr, " . sdl_thread__: Toggle pause\n");
         }
         break;
 
@@ -178,7 +175,6 @@ loop:
                 SDL_SetWindowFullscreen((SDL_Window *) sdl2->window, SDL_WINDOW_FULLSCREEN);
             /* May use SDL_WINDOW_FULLSCREEN_DESKTOP, need to check. */
             sdl2->is_fullscreen = 1 - sdl2->is_fullscreen;
-            fprintf(stderr, " . sdl_thread__: Toggle fullscreen\n");
         }
         break;