Getting user input in Odin CLI apps

Search for a command to run...

No comments yet. Be the first to comment.
Remember my post about switching to VSCode? Well, plot twist: the very next day after publishing it, I switched to WebStorm. And guess what? I've been on JetBrains IDEs ever since. I know, I know. Another "why I switched editors" post. But hear me ou...

Why Emacs Keybindings? I've always preferred Emacs-style editing, especially the way it handles cursor movement and text manipulation. Even though I have switched to using VSCode for most of my development work, I often found myself missing the intui...

In my previous post about building C/C++ projects with CMake, I shared a simple CMakeLists.txt setup for compiling a basic project. Today, I’ll dive into a specific need that many developers encounter: linking libraries directly from project folders ...

Some time ago, I wrote a post about using Vim to look cool and why that’s not a good idea. Now, funny enough, here I am—having switched to VSCode after years of hopping between Vim and Emacs. This isn’t one of those "Vim sucks, I'm going back to VSCo...

I had been doing some basic interpreter work in Go and wanted to redo it in another language to solidify my understanding. Naturally, I chose Odin, it’s another great language, with a Go-like, easy-to-approach syntax and no unnecessary complexity.
I had previously used Odin while building the Jack compiler for my Nand2Tetris projects last year, and I really enjoyed the experience.
As I began reimplementing my interpreter in Odin, I realized I’d never actually dealt with reading interactive user input from the command line. Since I needed a REPL, this was a must. Surprisingly, just like Go’s bufio pattern, it’s not super obvious how to do this in Odin either.
After digging around in the Odin Discord, I found how to do it.
And here is a REPL that echoes your input:
package main
import "core:bufio"
import "core:fmt"
import "core:os"
main :: proc() {
scanner: bufio.Scanner
stdin := os.stream_from_handle(os.stdin)
bufio.scanner_init(&scanner, stdin, context.temp_allocator)
for {
fmt.printf("> ")
if !bufio.scanner_scan(&scanner) {
break
}
line := bufio.scanner_text(&scanner)
if line == "q" {break}
fmt.println(line)
}
if err := bufio.scanner_error(&scanner); err != nil {
fmt.eprintln("error scanning input: %v", err)
}
free_all(context.temp_allocator)
}