Quand je touche Vim, une action se produit chaque fois que j'entre un caractère, donc j'étais techniquement intéressé par son fonctionnement, alors j'ai essayé de lire le code source.
Je sais que je peux saisir ligne par ligne avec getc () et gets (), mais je ne sais pas comment traiter chaque entrée clé.
J'ai imaginé qu'il était facile de penser de ma propre connaissance que ce serait comme surveiller l'entrée de caractère dans un autre thread et notifier le thread principal s'il y avait une entrée clé.
Je me souviens avoir écrit une bibliothèque de console Ruby appelée wincons.rb il y a longtemps qu'elle se terminerait après avoir entré un seul caractère, et je me demandais comment cela était réalisé.
Vous pouvez obtenir la source à partir de ce qui suit. http://texcell.co.jp/ruby/Lib/winconsole.html
En le regardant, il semble qu'il se réalise en appelant une fonction appelée PeekConsoleInputW de win32api.
http://texcell.co.jp/ruby/PLC/rubyc24.html
↑ En regardant les exemples ici, il semble que la vérification de l'entrée de clé est toujours effectuée dans la boucle, et elle se termine quand q
arrive.
La manière dont wincons.rb est-elle vraiment correcte? J'avais aussi une question, alors j'ai décidé de jeter un œil au code source de Vim.
Le code source peut être obtenu à partir de github. https://github.com/vim/vim
Quand j'ai cherché l'endroit où PeekConsoleInputW mentionné plus tôt était utilisé, j'ai trouvé qu'il était utilisé dans la fonction read_console_input
de src / os_win32.c
.
Ce read_console_input
semble être appelé de pas mal d'endroits, et je ne savais pas lequel était directement connecté à l'entrée du clavier, alors j'ai abandonné.
mch_inchar
=> tgetch
est suspecte. mch_inchr
est appelé depuis ʻui_inchar, et ʻui_inchar
est appelé dans la boucle for de la fonction ʻinchar`. La boucle for continue de tourner jusqu'à ce que vous puissiez obtenir l'entrée clé de ui_inchar, donc je pense que c'est la clé de l'entrée clé, mais dans ce cas, elle bouclera dans la fonction inchar et les autres traitements ne fonctionneront pas. , Je pense que c'est un fil au parent qui appelle «inchar», mais c'est de la spéculation.La ligne de lecture fournie avec ruby appelle le processus complémentaire lorsque vous appuyez sur la touche TAB. Je suppose qu'il doit y avoir un processus tel que l'appel de Proc lorsque la touche TAB est enfoncée.
Tout d'abord, le code lisant la ligne de lecture fournie avec ruby
La source du rubis peut être vue de ce qui suit. https://github.com/ruby/ruby
La source de readline est autour de ʻext / readline`.
Après de nombreuses recherches, j'ai trouvé que la fonction qui appelle Proc est readline_attempted_completion_function
. La fonction est liée à rl_attempted_completion_function
.
La fonction rl_attempted_completion_function
n'est pas dans le code ruby, mais dans le code readline GNU, alors lisez cela.
La source de GNU readline peut être trouvée ci-dessous. https://github.com/JuliaLang/readline
Ce n'est pas exactement la véritable source de GNU readline, mais je ne pense pas que ce soit un problème pour cette compréhension.
La fonction rl_attempted_completion_function
est dans complete.c
, mais je n'ai pas pu arriver à ce point en remontant dans le temps.
En regardant ici, readline
ressemble à une racine, alors j'ai décidé de le vérifier étape par étape depuis la racine.
http://d.hatena.ne.jp/cocoatomo/20071112/1194855728
readline ()
se trouve dans readline.c
. Au fur et à mesure que vous parcourez cette fonction, il semble que kbhit ()
dans rl_gather_tyi ()
de ʻinput.c` soit la clé de l'entrée clé.
Si tu regardes ici http://tricky-code.net/mine/c/mc07kbhit.php
La fonction kbhit renvoie une valeur non nulle lorsqu'une touche est enfoncée, Une fonction qui renvoie 0 si aucune touche n'est enfoncée.
Il semble que cela ne détermine pas en soi quelle touche a été enfoncée.
Il semble que ce qui est réellement pris est d'appeler la fonction read ()
dans rl_getc (stream)
et de lire un caractère de l'IO passé en argument.
En le retournant en boucle, il semble que l'entrée de la touche soit toujours vérifiée et vérifiée caractère par caractère.
Il n'y avait pas de fil.
readline vérifie les frappes dans une boucle sans utiliser de threads.
J'utilise kbhit ()
pour déterminer s'il y a eu une frappe
Les caractères sont acquis un par un en utilisant read ()
.
Recommended Posts