{"id":19836291,"url":"https://github.com/fooeybar/fstdin","last_synced_at":"2026-04-10T22:37:53.575Z","repository":{"id":51282146,"uuid":"367501069","full_name":"Fooeybar/fstdin","owner":"Fooeybar","description":"Simple stdin line control + prompts","archived":false,"fork":false,"pushed_at":"2023-07-21T18:43:22.000Z","size":29,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-11T18:50:37.750Z","etag":null,"topics":["cli","keypress","nodejs","readline","stdin","terminal"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Fooeybar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-14T23:30:04.000Z","updated_at":"2021-12-08T18:04:31.000Z","dependencies_parsed_at":"2022-09-14T07:42:59.604Z","dependency_job_id":null,"html_url":"https://github.com/Fooeybar/fstdin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fooeybar%2Ffstdin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fooeybar%2Ffstdin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fooeybar%2Ffstdin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Fooeybar%2Ffstdin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Fooeybar","download_url":"https://codeload.github.com/Fooeybar/fstdin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241202159,"owners_count":19926564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","keypress","nodejs","readline","stdin","terminal"],"created_at":"2024-11-12T12:10:50.950Z","updated_at":"2026-04-10T22:37:53.491Z","avatar_url":"https://github.com/Fooeybar.png","language":"JavaScript","readme":"# **fstdin**\n\n![npm](https://img.shields.io/npm/v/fstdin?style=flat-square)\n![node](https://img.shields.io/node/v/cu?style=flat-square)\n![license](https://img.shields.io/badge/License-MIT-blue.svg)\nMade with ![linux](https://img.shields.io/badge/Linux-FCC624?logo=linux\u0026logoColor=black)\n\n\u003c/br\u003e\n\nSimple terminal interface + prompts\n\n\u003c/br\u003e\n\n- [Initialization](#initialization)\n- [Prompts](#prompts)\n- [Root Prompt](#root-prompt)\n- [Masking](#masking)\n- [Colouring](#coloring)\n- [Keys](#keys)\n- [Shortcut Keys](#shortcut-keys)\n\n\u003c/br\u003e\n\n---\n\n## Initialization\n\n\u003c/br\u003e\n\n`fstdin=require('fstdin')({config});`\u003c/br\u003e\n\n\u003c/br\u003e\n\nAny config properties `undefined` or `typeof!==` will default to the values listed below:\u003c/br\u003e\n\n```\nconfig={\n    text_color : 15\n   ,cursor_color : 15\n   ,input_history : 50\n   ,escape : '\\x1b'\n   ,mask_char : '*'\n   ,on_exit : function(code=0){}\n   ,on_line : function(line=''){}\n   ,on_key : function(key={sequence:'',name:'',ctrl:false,meta:false,shift:false}){}\n}\n```\n\n\u003c/br\u003e\n\nReturns an object with the properties:\u003c/br\u003e\n\n```\nfstdin()={\n    line : ''                           //Read-only current stdin\n    ,key : function(string||object,...) //Trigger keys\n    ,prompt : function(object,...)      //Prompt user\n}\n```\n\n\u003c/br\u003e\n\nChange the config by calling the fstdin function with new config settings.\n\n\u003c/br\u003e\n\n---\n\n## Prompts\n\n\u003c/br\u003e\n\nPrompts are entered as an object:\u003c/br\u003e\n\n```\nprompt({\n    line : 'What is your name?'\n    ,any_key : true\n})\n```\n\nThe prompt function will take multiple prompts as arguments:\u003c/br\u003e\n\n```\nprompt(\n    {line : 'Hiya!', any_key : true}\n    ,{line : 'Hello!', any_key : true}\n    ,{line : 'Hi!', any_key : true}\n    ,{line : 'Howdy!', any_key : true}\n)\n```\n\n\u003c/br\u003e\n\nPrompt lines longer than the terminal columns will be split with `'\\n'`.\u003c/br\u003e\n\nPrompt response input longer than the terminal columns will scroll to the right.\u003c/br\u003e\n\nPress `escape` to skip a prompt. The `prompt.func(res,esc)` will still be called, with `res=''` and `esc=true`.\n\n\u003c/br\u003e\n\nAny prompt properties `undefined` or `typeof!==` will default to the values listed below:\u003c/br\u003e\n\n```\nprompt={\n    line : ''\n    ,any_key : false\n    ,color : 15\n    ,root : false\n    ,mask : false\n    ,func : (response='',escape=false)=\u003e{}\n}\n```\n\n\u003c/br\u003e\n\n### Root Prompt\n\nInclude the property `root:true` to set a prompt as the root prompt. The root prompt will repeatedly occur when no other prompts are active.\u003c/br\u003e\n\nAn example as a working directory prompt:\u003c/br\u003e\n\n```\n.prompt(proot={\n     line:process.cwd()+'~ '\n    ,root:true\n    ,func:(res)=\u003e{\n        console.log(process.cwd()+'~ '+res);\n        proot.line=process.cwd()+'~ ';\n    }\n});\n```\n\n\u003c/br\u003e\n\n### Masking\n\nInclude the property `mask:true` to mask the input for that prompt.\u003c/br\u003e\n\nDuring a masked prompt, only the `config.mask_char` will be:\u003c/br\u003e\n\n- displayed in the terminal\n- sent in `on_line(res)`\n- recorded in input history\n- recorded in the read-only line `{ line } = fstdin()`\n\nAdditionally, the following shortcuts are disabled and function not called:\n\n- Undo `ctrl+z`\n- Redo `ctrl+y`\n- scroll input history `up`\n- scroll input history `down`\n- `config.on_key(key)`\n\nUnmasked input can only be read in the `prompt.func(res,esc)` call:\u003c/br\u003e\n\n```\n.prompt({\n    line: 'Are you a Led Zeppelin fan?'\n    ,mask: true\n    ,func: (res,esc)=\u003e{\n        if(esc)console.log('Why no answer?'); //res.length==0\n        else console.log(`So your answer is: ${res}`);\n    }\n});\n```\n\n\u003c/br\u003e\n\n### Coloring\n\nAdd color to your prompt line using the `.color` property:\u003c/br\u003e\n- `prompt({line:'This line is yellow!',color:11})`\u003c/br\u003e\n\n\u003c/br\u003e\n\n---\n\n## Keys\n\n\u003c/br\u003e\n\nKeys are either an object `{name:'c',ctrl:true} //ctrl+c (end process)`\u003c/br\u003e\nOr may also be entered as strings when using `.key(key,...)`\u003c/br\u003e\n\nTriggering keys with `.key(key,..)` is the equivalent of pressing the key(s) at runtime, however, this will not trigger the `.on_key(key)` function.\u003c/br\u003e\n\nThe `on_key(key)` will send an object when a key is physically pressed:\u003c/br\u003e\n\n```\nkey={\n    name: ''\n    ,sequence : ''\n    ,ctrl : false\n    ,meta : false\n    ,shift : false\n}\n```\n\n\u003c/br\u003e\n\n### Shortcut Keys\n\n\u003c/br\u003e\n\n- Exit the process using `ctrl+c {name:'c',ctrl:true}`\n- Scroll the previous stdin history using `'up'` or `'down'` arrow keys\n- Undo `ctrl+z {name:'z',ctrl:true}`\n- Redo `ctrl+y {name:'y',ctrl:true}`\n- Escape `'escape'` skip a prompt or return to current history\n\n\u003c/br\u003e\n\n---\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffooeybar%2Ffstdin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffooeybar%2Ffstdin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffooeybar%2Ffstdin/lists"}