{
    "mode": "perldoc",
    "parameter": "POE::Wheel::ReadLine",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AWheel%3A%3AReadLine/json",
    "generated": "2026-07-05T09:23:50Z",
    "synopsis": "#!perl\nuse warnings;\nuse strict;\nuse POE qw(Wheel::ReadLine);\nPOE::Session->create(\ninlinestates=> {\nstart => \\&setupconsole,\ngotuserinput => \\&handleuserinput,\n}\n);\nPOE::Kernel->run();\nexit;\nsub handleuserinput {\nmy ($input, $exception) = @[ARG0, ARG1];\nmy $console = $[HEAP]{console};\nunless (defined $input) {\n$console->put(\"$exception caught.  B'bye!\");\n$[KERNEL]->signal($[KERNEL], \"UIDESTROY\");\n$console->writehistory(\"./testhistory\");\nreturn;\n}\n$console->put(\"  You entered: $input\");\n$console->addhistory($input);\n$console->get(\"Go: \");\n}\nsub setupconsole {\n$[HEAP]{console} = POE::Wheel::ReadLine->new(\nInputEvent => 'gotuserinput'\n);\n$[HEAP]{console}->readhistory(\"./testhistory\");\n$[HEAP]{console}->clear();\n$[HEAP]{console}->put(\n\"Enter some text.\",\n\"Ctrl+C or Ctrl+D exits.\"\n);\n$[HEAP]{console}->get(\"Go: \");\n}",
    "sections": {
        "NAME": {
            "content": "POE::Wheel::ReadLine - non-blocking Term::ReadLine for POE\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "#!perl\n\nuse warnings;\nuse strict;\n\nuse POE qw(Wheel::ReadLine);\n\nPOE::Session->create(\ninlinestates=> {\nstart => \\&setupconsole,\ngotuserinput => \\&handleuserinput,\n}\n);\n\nPOE::Kernel->run();\nexit;\n\nsub handleuserinput {\nmy ($input, $exception) = @[ARG0, ARG1];\nmy $console = $[HEAP]{console};\n\nunless (defined $input) {\n$console->put(\"$exception caught.  B'bye!\");\n$[KERNEL]->signal($[KERNEL], \"UIDESTROY\");\n$console->writehistory(\"./testhistory\");\nreturn;\n}\n\n$console->put(\"  You entered: $input\");\n$console->addhistory($input);\n$console->get(\"Go: \");\n}\n\nsub setupconsole {\n$[HEAP]{console} = POE::Wheel::ReadLine->new(\nInputEvent => 'gotuserinput'\n);\n$[HEAP]{console}->readhistory(\"./testhistory\");\n$[HEAP]{console}->clear();\n$[HEAP]{console}->put(\n\"Enter some text.\",\n\"Ctrl+C or Ctrl+D exits.\"\n);\n$[HEAP]{console}->get(\"Go: \");\n}\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "POE::Wheel::ReadLine is a non-blocking form of Term::ReadLine that's compatible with POE. It\nuses Term::Cap to interact with the terminal display and Term::ReadKey to interact with the\nkeyboard.\n\nPOE::Wheel::ReadLine handles almost all common input editing keys. It provides an input history\nlist. It has both vi and emacs modes. It supports incremental input search. It's fully\ncustomizable, and it's compatible with standard readline(3) implementations such as\nTerm::ReadLine::Gnu.\n\nPOE::Wheel::ReadLine is configured by placing commands in an \"inputrc\" initialization file. The\nfile's name is taken from the \"INPUTRC\" environment variable, or ~/.inputrc by default.\nPOE::Wheel::ReadLine will read the inputrc file and configure itself according to the commands\nand variables therein. See readline(3) for details about inputrc files.\n\nThe default editing mode will be emacs-style, although this can be configured by setting the\n'editing-mode' variable within an inputrc file. If all else fails, POE::Wheel::ReadLine will\ndetermine the user's favorite editor by examining the EDITOR environment variable.\n",
            "subsections": []
        },
        "PUBLIC METHODS": {
            "content": "",
            "subsections": [
                {
                    "name": "Constructor",
                    "content": "Most of POE::Wheel::ReadLine's interaction is through its constructor, new().\n\nnew"
                },
                {
                    "name": "new",
                    "content": "multiple console readers would conflict.\n\nInputEvent\n\"InputEvent\" names the event that will indicate a new line of console input. See \"PUBLIC EVENTS\"\nfor more details.\n\nPutMode\n\"PutMode\" controls how output is displayed when put() is called during user input.\n\nWhen set to \"immediate\", put() pre-empts the user immediately. The input prompt and user's input\nto date are redisplayed after put() is done.\n\nThe \"after\" \"PutMode\" tells put() to wait until after the user enters or cancels her input.\n\nFinally, \"idle\" will allow put() to pre-empt user input if the user stops typing for \"IdleTime\"\nseconds. This mode behaves like \"after\" if the user can't stop typing long enough. This is\nPOE::Wheel::ReadLine's default mode.\n\nIdleTime\n\"IdleTime\" tells POE::Wheel::ReadLine how long the keyboard must be idle before \"put()\" becomes\nimmediate or buffered text is flushed to the display. It is only meaningful when \"PutMode\" is\n\"idle\". \"IdleTime\" defaults to 2 seconds.\n\nAppName\n\"AppName\" registers an application name which is used to retrieve application-specific key\nbindings from the inputrc file. The default \"AppName\" is \"poe-readline\".\n\n# If using POE::Wheel::ReadLine, set\n# the key mapping to emacs mode and\n# trigger debugging output on a certain\n# key sequence.\n$if poe-readline\nset keymap emacs\nControl-xP: poe-wheel-debug\n$endif\n"
                },
                {
                    "name": "History List Management",
                    "content": "POE::Wheel::ReadLine supports an input history, with searching.\n\naddhistory"
                },
                {
                    "name": "add_history",
                    "content": "single line: the last line of input received from the terminal. The \"SYNOPSIS\" shows"
                },
                {
                    "name": "add_history",
                    "content": "gethistory"
                },
                {
                    "name": "get_history",
                    "content": "contain everything entered into the wheel\n\nwritehistory"
                },
                {
                    "name": "write_history",
                    "content": "the name of the file where the input history will be written. writehistory() will write to\n~/.history if no file name is specified.\n\nReturns true on success, or false if not.\n\nThe \"SYNOPSIS\" shows an example of writehistory() and the corresponding readhistory().\n\nreadhistory"
                },
                {
                    "name": "read_history",
                    "content": "from ~/.history if no file name is specified. It may also read a subset of the history file if\nit's given optional START and END parameters. The file will be read from the beginning if START\nis omitted or zero. It will be read to the end if END is omitted or earlier than START.\n\nReturns true on success, or false if not.\n\nThe \"SYNOPSIS\" shows an example of readhistory() and the corresponding writehistory().\n\nRead the first ten history lines:\n\n$[HEAP]{console}->readhistory(\"filename\", 0, 9);\n\nhistorytruncatefile"
                },
                {
                    "name": "history_truncate_file",
                    "content": "parameters: the name of the file to truncate, and the maximum number of history lines to leave\nin the file. The history file will be cleared entirely if the line count is zero or omitted.\n\nThe file to be truncated defaults to ~/.history. So calling historytruncatefile() with no\nparameters clears ~/.history.\n\nReturns true on success, or false if not.\n\nNote that historytrucatefile() removes the earliest lines from the file. The later lines\nremain intact since they were the ones most recently entered.\n\nKeep ~/.history down to a manageable 100 lines:\n\n$[HEAP]{console}->historytruncatefile(undef, 100);\n"
                },
                {
                    "name": "Key Binding Methods",
                    "content": "bindkey"
                },
                {
                    "name": "bind_key",
                    "content": "sequence can be in any of the forms defined within readline(3). The function should either be a\npre-defined name, such as \"self-insert\" or a function reference. The binding is made in the\ncurrent keymap. Use the rlsetkeymap() method to change keymaps, if desired.\n\nadddefun NAME FN"
                },
                {
                    "name": "add_defun",
                    "content": "may then be bound to keystrokes by that NAME.\n\nConsole I/O Methods\nclear\nClears the terminal.\n\nterminalsize\nReturns what POE::Wheel::ReadLine thinks are the current dimensions of the terminal. Returns a\nlist of two values: the number of columns and number of rows, respectively.\n\nsub someeventhandler {\nmy ($columns, $rows) = $[HEAP]{console}->terminalsize;\n$[HEAP]{console}->put(\n\"Terminal columns: $columns\",\n\"Terminal rows: $rows\",\n);\n}\n\nget"
                },
                {
                    "name": "get",
                    "content": "noticed unless get() has enabled the wheel's internal I/O watcher.\n\nAfter get() is called, the next line of input or exception on the console will trigger an\n\"InputEvent\" with the appropriate parameters. POE::Wheel::ReadLine will then enter an inactive\nstate until get() is called again.\n\nCalls to get() without an argument will preserve the current prompt. Calling get() with an\nargument before a whole line of input is received will change the prompt on the fly.\n\nSee the \"SYNOPSIS\" for sample usage.\n\nput"
                },
                {
                    "name": "put",
                    "content": "POE::Wheel::Curses for more funky display options.\n\nPlease do not use print() with POE::Wheel::ReadLine. print() invariably gets the newline wrong,\nleaving an application's output to stairstep down the terminal. Also, put() understands when a\nuser is entering text, and \"PutMode\" may be used to avoid interrupting the user.\n"
                },
                {
                    "name": "ReadLine Option Methods",
                    "content": "attribs"
                },
                {
                    "name": "attribs",
                    "content": "query or modify POE::Wheel::ReadLine's behavior.\n\noption"
                },
                {
                    "name": "option",
                    "content": "way to query POE::Wheel::ReadLine options.\n"
                }
            ]
        },
        "PUBLIC EVENTS": {
            "content": "POE::Wheel::ReadLine emits only a single event.\n",
            "subsections": [
                {
                    "name": "InputEvent",
                    "content": "\"InputEvent\" names the event that will be emitted upon any kind of complete terminal input.\nEvery \"InputEvent\" handler receives three parameters:\n\n$[ARG0] contains a line of input. It may be an empty string if the user entered an empty line.\nAn undefined $[ARG0] indicates some exception such as end-of-input or the fact that the user\ncanceled their input or pressed C-c (^C).\n\n$[ARG1] describes an exception, if one occurred. It may contain one of the following strings:\n\ncancel\nThe \"cancel\" exception indicates when a user has canceled a line of input. It's sent when the\nuser triggers the \"abort\" function, which is bound to C-g (^G) by default.\n\neot\n\"eot\" is the ASCII code for \"end of tape\". It's emitted when the user requests that the\nterminal be closed. By default, it's triggered when the user presses C-d (^D) on an empty\nline.\n\ninterrupt\n\"interrupt\" is sent as a result of the user pressing C-c (^C) or otherwise triggering the\n\"interrupt\" function.\n\nFinally, $[ARG2] contains the ID for the POE::Wheel::ReadLine object that sent the\n\"InputEvent\".\n"
                }
            ]
        },
        "CUSTOM BINDINGS": {
            "content": "POE::Wheel::ReadLine allows custom functions to be bound to keystrokes. The function must be\nmade visible to the wheel before it can be bound. To register a function, use\nPOE::Wheel::ReadLine's adddefun() method:\n\nPOE::Wheel::ReadLine->adddefun('reverse-line', \\&reverseline);\n\nWhen adding a new defun, an optional third parameter may be provided which is a key sequence to\nbind to. This should be in the same format as that understood by the inputrc parsing.\n\nBound functions receive three parameters: A reference to the wheel object itself, the key\nsequence that triggered the function (in printable form), and the raw key sequence. The bound\nfunction is expected to dig into the POE::Wheel::ReadLine data members to do its work and\ndisplay the new line contents itself.\n\nThis is less than ideal, and it may change in the future.\n",
            "subsections": []
        },
        "CUSTOM COMPLETION": {
            "content": "An application may modify POE::Wheel::ReadLine's \"completionfunction\" in order to customize how\ninput should be completed. The new completion function must accept three scalar parameters: the\nword being completed, the entire input text, and the position within the input text of the word\nbeing completed.\n\nThe completion function should return a list of possible matches. For example:\n\nmy $attribs = $wheel->attribs();\n$attribs->{completionfunction} = sub {\nmy ($text, $line, $start) = @;\nreturn qw(a list of candidates to complete);\n}\n\nThis is the only form of completion currently supported.\n",
            "subsections": []
        },
        "IMPLEMENTATION DIFFERENCES": {
            "content": "Although POE::Wheel::ReadLine is modeled after the readline(3) library, there are some areas\nwhich have not been implemented. The only option settings which have effect in this\nimplementation are: bell-style, editing-mode, isearch-terminators, comment-begin,\nprint-completions-horizontally, show-all-if-ambiguous and completionfunction.\n\nThe function 'tab-insert' is not implemented, nor are tabs displayed properly.\n",
            "subsections": []
        },
        "SEE ALSO": {
            "content": "POE::Wheel describes the basic operations of all wheels in more depth. You need to know this.\n",
            "subsections": [
                {
                    "name": "readline",
                    "content": "The SEE ALSO section in POE contains a table of contents covering the entire POE distribution.\n\nTerm::Visual is an alternative to POE::Wheel::ReadLine. It provides scrollback and a status bar\nin addition to editable user input. Term::Visual supports POE despite the lack of \"POE\" in its\nname.\n"
                }
            ]
        },
        "BUGS": {
            "content": "POE::Wheel::ReadLine has some known issues:\n",
            "subsections": [
                {
                    "name": "Perl 5.8.0 is Broken",
                    "content": "Non-blocking input with Term::ReadKey does not work with Perl 5.8.0, especially on Linux systems\nfor some reason. Upgrading Perl will fix things. If you can't upgrade Perl, consider alternative\ninput methods, such as Term::Visual.\n\n<http://rt.cpan.org/Ticket/Display.html?id=4524> and related tickets explain the issue in\ndetail. If you suspect your system is one where Term::ReadKey fails, you can run this test\nprogram to be sure.\n\n#!/usr/bin/perl\nuse Term::ReadKey;\nprint \"Press 'q' to quit this test.\\n\";\nReadMode 5; # Turns off controls keys\nwhile (1) {\nwhile (not defined ($key = ReadKey(-1))) {\nprint \"Didn't get a key.  Sleeping 1 second.\\015\\012\";\nsleep (1);\n}\nprint \"Got key: $key\\015\\012\";\n($key eq 'q') and last;\n}\nReadMode 0; # Reset tty mode before exiting\nexit;\n"
                },
                {
                    "name": "Non-Optimal Code",
                    "content": "Dissociating the input and display cursors introduced a lot of code. Much of this code was\nthrown in hastily, and things can probably be done with less work.\n"
                },
                {
                    "name": "Unimplemented Features",
                    "content": "Input editing is not kept on one line. If it wraps, and a terminal cannot wrap back through a\nline division, the cursor will become lost.\n\nUnicode support. I feel real bad about throwing away native representation of all the\n8th-bit-set characters. I also have no idea how to do this, and I don't have a system to test\nthis. Patches are very much welcome.\n"
                }
            ]
        },
        "GOTCHAS / FAQ": {
            "content": "",
            "subsections": [
                {
                    "name": "Lost Prompts",
                    "content": "Q: Why do I lose my prompt every time I send output to the screen?\n\nA: You probably are using print or printf to write screen output. ReadLine doesn't track STDOUT\nitself, so it doesn't know when to refresh the prompt after you do this. Use ReadLine's put()\nmethod to write lines to the console.\n\nEdit Keystrokes Display as ^C\nQ: None of the editing keystrokes work. Ctrl-C displays \"^c\" rather than generating an\ninterrupt. The arrow keys don't scroll through my input history. It's generally a bad\nexperience.\n\nA: You're probably a vi/vim user. In the absence of a ~/.inputrc file, POE::Wheel::ReadLine\nchecks your EDITOR environment variable for clues about your editing preference. If it sees /vi/\nin there, it starts in vi mode. You can override this by creating a ~/.inputrc file containing\nthe line \"set editing-mode emacs\", or adding that line to your existing ~/.inputrc. While you're\nin there, you should totally get acquainted with all the other cool stuff you can do with\n.inputrc files.\n"
                },
                {
                    "name": "Lack of Windows Support",
                    "content": "Q: Why doesn't POE::Wheel::ReadLine work on Windows? Term::ReadLine does.\n\nA: POE::Wheel::ReadLine requires select(), because that's what POE uses by default to detect\nkeystrokes without blocking. About half the flavors of Perl on Windows implement select() in\nterms of the same function in the WinSock library, which limits select() to working only with\nsockets. Your console isn't a socket, so select() doesn't work with your version of Perl on\nWindows.\n\nReally good workarounds are possible but don't exist as of this writing. They involve writing a\nspecial POE::Loop for Windows that either uses a Win32-specific module for better multiplexing,\nthat polls for input, or that uses blocking I/O watchers in separate threads.\n"
                },
                {
                    "name": "Cygwin Support",
                    "content": "Q: Why does POE::Wheel::ReadLine complain about my \"dumb\" terminal?\n\nA: Do you have Strawberry Perl installed? Due to the way it works, on installation it sets a\nglobal environment variable in MSWin32 for TERM=dumb. ( it may be fixed in a future version, but\nit's here to stay for now, ha! ) In this case, logging into the Cygwin shell via the cygwin.bat\nlauncher results in a nonfunctional readline.\n\nNormally, Cygwin will set TERM=cygwin in the launcher. However, if the TERM was already set it\nwill not alter the value. Hence, the \"bug\" appears! What you can do is to hack the cygwin.bat\nfile to add this line:\n\nSET TERM=cygwin\n\nOther users reported that you can have better results by editing the ~/.bashprofile file to set\nTERM=cygwin because on a Cygwin upgrade it overwrites the cygwin.bat file.\n\nAlternatively, you could install different terminals like \"xterm\" or \"rxvt\" as shown here:\n<http://c2.com/cgi/wiki?BetterCygwinTerminal>. Please let us know if you encounter problems\nusing any terminal other than \"dumb\".\n\nIf you feel brave, you can peruse the RT ticket at\n<http://rt.cpan.org/Ticket/Display.html?id=55365> for more information on this problem.\n\nAUTHORS & COPYRIGHTS\nPOE::Wheel::ReadLine was originally written by Rocco Caputo.\n\nNick Williams virtually rewrote it to support a larger subset of GNU readline.\n\nPlease see POE for more information about other authors and contributors.\n"
                }
            ]
        }
    },
    "summary": "POE::Wheel::ReadLine - non-blocking Term::ReadLine for POE",
    "flags": [],
    "examples": [],
    "see_also": []
}