diff --git a/src/lib.zig b/src/lib.zig
new file mode 100644
index 0000000..7be0d1d
--- /dev/null
+++ b/src/lib.zig
@@ -0,0 +1,42 @@
+const std   = @import("std");
+const mem   = std.mem;
+const stdout = std.io.getStdOut().writer();
+const process = std.process;
+
+const fs = std.fs;
+
+pub const warn  = std.debug.print;
+pub const print = std.debug.print;
+
+const cli_arguments = @import("./cli_arguments.zig");
+
+pub const CLI = struct {
+    const Self = @This();
+
+    arena: std.heap.ArenaAllocator,
+    allocator: std.mem.Allocator,
+    args: []const [:0]u8,
+
+    pub fn init() !Self {
+        var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+        const allocator = arena.allocator();
+        var args = try process.argsAlloc(allocator);
+
+        return Self {
+            .arena = arena,
+            .allocator = allocator,
+            .args = args,
+        };
+    }
+
+    pub fn deinit(self: *Self) void {
+        self.arena.deinit();
+        // process.argsFree(self.allocator, self.args);
+    }
+
+    pub fn nextArg(self: Self, idx: *usize) ?[]const u8 {
+        if (idx.* >= self.args.len) return null;
+        defer idx.* += 1;
+        return self.args[idx.*];
+    }
+};
diff --git a/src/ls.zig b/src/ls.zig
index afcce63..57e3d6a 100644
--- a/src/ls.zig
+++ b/src/ls.zig
@@ -1,41 +1,45 @@
-const std   = @import("std");
-const mem   = std.mem;
-const stdout = std.io.getStdOut().writer();
-const process = std.process;
-
+const std = @import("std");
 const fs = std.fs;
+const lib = @import("./lib.zig");
 
-const warn  = std.debug.warn;
-const print = std.debug.print;
-
-const cli_arguments = @import("./cli_arguments.zig");
-
+// WON'T: human output => use human command instead
 // TODO: error management.
+// TODO: verbose output (-l).
+
+pub const cwd = fs.cwd();
+
+// Either print directory's content or file.
+fn print_element(path: []const u8) !void {
+    var dir: fs.Dir = cwd.openDir(path, .{.iterate = true}) catch |err| switch (err) {
+        error.NotDir => return lib.print("{s}\n", .{path}),
+        else => return err,
+    };
+    var dir_it = dir.iterate();
+
+    while (try dir_it.next()) |entry| {
+        lib.print("{s}\n", .{entry.name});
+    }
+}
 
 pub fn ls() !void {
-
-    // Memory allocator for the cli arguments.
-    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
-    defer arena.deinit();
-
-    const allocator = &arena.allocator;
-    var args = try process.argsAlloc(allocator);
-    defer process.argsFree(allocator, args);
+    var cli = try lib.CLI.init();
+    defer cli.deinit();
 
     // Skipping the executable binary name.
     var arg_idx: usize = 1;
 
-    const directory = cli_arguments.nextArg(args, &arg_idx) orelse {
-        warn("Expected first argument to be path to gui file\n", .{});
-        return error.InvalidArgs;
-    };
+    // case there are parameters
+    while(arg_idx < cli.args.len) {
+        const element = cli.nextArg(&arg_idx) orelse {
+            lib.warn("Null argument\n", .{});
+            return error.InvalidArgs;
+        };
+        try print_element(element);
+    }
 
-    var current_working_directory: fs.Dir = fs.cwd();
-    var cwd: fs.Dir = try current_working_directory.openDir(directory, .{.iterate = true});
-    var dir_it = cwd.iterate();
-
-    while (try dir_it.next()) |entry| {
-        print("{}\n", .{entry.name});
+    // case there were no parameter, print current directory
+    if (cli.args.len == 1) {
+        try print_element(".");
     }
 }