Wenn ich Vim berührte, trat jedes Mal eine Aktion auf, wenn ich ein Zeichen eingab. Daher war ich technisch daran interessiert, wie es funktioniert, und versuchte, den Quellcode zu lesen.
Ich weiß, dass ich mit getc () und get () Zeile für Zeile eingeben kann, aber ich weiß nicht, wie ich jede Tasteneingabe verarbeiten soll.
Ich stellte mir vor, dass es nach meinem eigenen Wissen leicht zu denken war, dass es so wäre, als würde man die Zeicheneingabe in einem anderen Thread überwachen und den Hauptthread benachrichtigen, wenn es eine Schlüsseleingabe gäbe.
Ich erinnere mich, dass ich vor langer Zeit eine Ruby-Konsolenbibliothek namens wincons.rb geschrieben habe, die nach Eingabe eines einzelnen Zeichens enden würde, und ich habe mich gefragt, wie dies erreicht wurde.
Sie können die Quelle aus dem Folgenden beziehen. http://texcell.co.jp/ruby/Lib/winconsole.html
Wenn man es betrachtet, scheint es, dass es durch Aufrufen einer Funktion namens PeekConsoleInputW von win32api realisiert wird.
http://texcell.co.jp/ruby/PLC/rubyc24.html
↑ Wenn man sich die Beispiele hier ansieht, scheint es, dass die Schlüsseleingabeprüfung immer in der Schleife durchgeführt wird und endet, wenn q
kommt.
Ist der Weg wincons.rb wirklich richtig? Ich hatte auch eine Frage und beschloss, mir den Vim-Quellcode anzusehen.
Der Quellcode kann von github bezogen werden. https://github.com/vim/vim
Als ich den Ort durchsuchte, an dem PeekConsoleInputW verwendet wurde, stellte ich fest, dass es in der Funktion read_console_input
von src / os_win32.c
verwendet wurde.
Dieser read_console_input
scheint von einigen Stellen aus aufgerufen zu werden, und ich wusste nicht, welcher direkt mit der Tastatureingabe verbunden war, also gab ich auf.
mch_inchar
=> tgetch
verdächtig ist. mch_inchr
wird von ui_inchar
aufgerufen, und ui_inchar
wird in der for-Schleife der Funktion inchar
aufgerufen. Die for-Schleife dreht sich so lange, bis Sie die Schlüsseleingabe von ui_inchar erhalten können. Ich denke, dies ist der Schlüssel für die Schlüsseleingabe, aber in diesem Fall wird die Inchar-Funktion wiederholt und die andere Verarbeitung funktioniert nicht. Ich denke, es ist ein Thread beim Elternteil, der "inchar" nennt, aber es ist Spekulation.Die mit Ruby gelieferte Readline ruft den Abschlussprozess auf, wenn Sie die TAB-Taste drücken. Ich gehe davon aus, dass es einen Prozess wie das Aufrufen von Proc geben muss, wenn die TAB-Taste gedrückt wird.
Zuerst Code, der die mit Ruby gelieferte Readline liest
Die Rubinquelle ist aus dem Folgenden ersichtlich. https://github.com/ruby/ruby
Die Quelle für readline ist "ext / readline".
Nach vielen Recherchen stellte ich fest, dass die Funktion, die Proc aufruft, "readline_attempted_completion_function" ist. Die Funktion ist an rl_attempted_completion_function
gebunden.
Die rl_attempted_completion_function
befindet sich nicht im Ruby-Code, sondern im GNU-Readline-Code. Lesen Sie das also.
Die Quelle der GNU-Readline finden Sie unten. https://github.com/JuliaLang/readline
Es ist nicht gerade die wahre Quelle der GNU-Readline, aber ich denke nicht, dass es ein Problem für dieses Verständnis ist.
Die rl_attempted_completion_function
ist in complete.c
, aber ich konnte diesen Punkt nicht erreichen, indem ich in der Zeit zurückging.
Wenn ich mich hier umsehe, sieht readline
wie eine Wurzel aus, also habe ich beschlossen, es Schritt für Schritt von der Wurzel aus zu überprüfen.
http://d.hatena.ne.jp/cocoatomo/20071112/1194855728
readline ()
befindet sich in readline.c
. Während Sie diese Funktion durchlaufen, scheint es, dass "kbhit ()" in "rl_gather_tyi ()" von "input.c" der Schlüssel zur Schlüsseleingabe ist.
Wenn Sie hier schauen http://tricky-code.net/mine/c/mc07kbhit.php
Die kbhit-Funktion gibt einen Wert ungleich Null zurück, wenn eine Taste gedrückt wird. Eine Funktion, die 0 zurückgibt, wenn keine Taste gedrückt wird.
Es scheint, dass dies selbst nicht bestimmt, welche Taste gedrückt wurde.
Es scheint, dass tatsächlich die Funktion "read ()" in "rl_getc (stream)" aufgerufen und ein Zeichen aus dem als Argument übergebenen E / A gelesen wird.
Wenn Sie es in einer Schleife drehen, scheint es, dass die Tasteneingabe immer zeichenweise überprüft und überprüft wird.
Es gab keinen Thread.
readline prüft Tastenanschläge in einer Schleife ohne Verwendung von Threads.
Ich benutze kbhit ()
, um festzustellen, ob es einen Tastenanschlag gab
Zeichen werden einzeln mit "read ()" erfasst.
Recommended Posts