[RUBY] I understood the very basics of character input


When I touch Vim, some action occurs every time I enter a character, so I was technically interested in how it works, so I tried reading the source code.

Knowledge level

I know that I can input line by line with getc () and gets (), but I don't know how to process each key input.

Expected behavior

I imagined that the simple idea from my own knowledge was to monitor the character input in another thread and notify the main thread when there was a key input.

Look at wincons.rb

I remember writing a Ruby console library called wincons.rb a long time ago that it would end after entering a single character, and I was wondering how this was achieved.

You can get the source from the following. http://texcell.co.jp/ruby/Lib/winconsole.html

Looking at it, it seems that it is realized by calling a function called PeekConsoleInputW of win32api.

http://texcell.co.jp/ruby/PLC/rubyc24.html ↑ Looking at the example here, it seems that the key input check is always performed in the loop and it ends when q comes.

Look at the Vim source code

Is the way wincons.rb really correct? I also had a question, so I decided to take a look at the Vim source code as well.

You can get the source code from github. https://github.com/vim/vim

When I searched for the part where PeekConsoleInputW mentioned earlier was used, I found that it was used in the function read_console_input of src / os_win32.c.

This read_console_input seems to be called from quite a few places, and I didn't know which one was directly connected to keyboard input, so I gave up.

View the readline source code

The readline that comes with ruby calls the completion Proc when you press the TAB key. I guess it must have a process such as calling Proc when the TAB key is pressed.

First, code read the readline that comes with ruby

You can see the source of ruby from the following. https://github.com/ruby/ruby

The source for readline is around ʻext / readline`.

After a lot of research, I found that the function that calls Proc looks like readline_attempted_completion_function. That function is bound to rl_attempted_completion_function.

The rl_attempted_completion_function is not in the ruby code, but in the GNU readline code, so read that.

You can see the source of GNU readline from the following. https://github.com/JuliaLang/readline

It's not exactly the real source of GNU readline, but I don't think it's a problem for this understanding.

The rl_attempted_completion_function is in complete.c, but I couldn't get to that point by going back in the function.

Find out how to use readline

Looking around here, readline looks like a root, so I decided to check it step by step from the root. http://d.hatena.ne.jp/cocoatomo/20071112/1194855728

readline () is located in readline.c. If you follow the function more and more, it seems that kbhit () in rl_gather_tyi () of ʻinput.c` is the key to key input.

What is kbhit ()?

If you look here http://tricky-code.net/mine/c/mc07kbhit.php

The kbhit function returns a non-zero value when any key is pressed, A function that returns 0 if no key is pressed.

It seems that this itself does not determine which key was pressed.

It seems that what is actually taken is to call the read () function in rl_getc (stream) and read one character from the IO passed as an argument.

By turning it around in a loop, it seems that the key input is always checked and checked character by character.

There was no thread.


readline checks for keystrokes in a loop without using threads.

I use kbhit () to determine if there was a keystroke

To get the characters, use read () to get the characters one by one.

Recommended Posts

I understood the very basics of character input
[day: 5] I summarized the basics of Java
I summarized the types and basics of Java exceptions
Docker monitoring-explaining the basics of basics-
Basics of character operation (java)
Understand the basics of docker
The basics of Swift's TableView
I tried to summarize the basics of kotlin and java
About the basics of Android development
I read the source of ArrayList I read
The basics of SpringBoot + MyBatis + MySQL
I read the source of Integer
I read the source of Long
I read the source of Short
I read the source of Byte
I read the source of String
I tried the input / output type of Java Lambda ~ Map edition ~
I want to limit the input by narrowing the range of numbers
[Challenge CircleCI from 0] Learn the basics of CircleCI
Now, I've summarized the basics of RecyclerView
Recorded because I was addicted to the standard input of the Scanner class
I investigated the internal processing of Retrofit
Looking back on the basics of Java
Character string comparison: I was caught in the skill check problem of Paiza
What is JSP? ~ Let's know the basics of JSP !! ~
[Ruby] Summary of class definitions. Master the basics.
I want to output the day of the week
I checked the place of concern of java.net.URL # getPath
[Delete the first letter of the character string] Ruby
I compared the characteristics of Java and .NET
The basics of the App Store "automatic renewal subscription"
I want to var_dump the contents of the intent
How to display the result of form input
I touched on the new features of Java 15
I tried using the profiler of IntelliJ IDEA
I checked the number of taxis with Ruby
Try the free version of Progate [Java I]
Basics of Ruby
I examined the life cycle of the extension of JUnit Jupiter
I tried using the Server Push function of Servlet 4.0
Is drainTo of LinkedBlockingQueue safe? I followed the source
[For beginners] DI ~ The basics of DI and DI in Spring ~
I tried to summarize the state transition of docker
I saw the list view of Android development collectively
05. I tried to stub the source of Spring Boot
I tried to reduce the capacity of Spring Boot
I tried the new feature profiler of IntelliJ IDEA 2019.2.
I want to know the answer of the rock-paper-scissors app
I want to display the name of the poster of the comment
I summarized the display format of the JSON response of Rails
Rails6: Input the initial data of ActionText using seed
I wrote a sequence diagram of the j.u.c.Flow sample
[WIP] I tried the configuration of Docker + Streama + NFS
I am keenly aware of the convenience of graphql-code-generator, part 2
[Ruby] Class nesting, inheritance, and the basics of self
I can't get out of the Rails dbconsole screen
I learned about the existence of a gemspec file
I want to be aware of the contents of variables!
I want to return the scroll position of UITableView!
I have a question about keyboard input of numbers