New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add textutils.prompt() #470

Open
wants to merge 6 commits into
base: master
from

Conversation

Projects
None yet
5 participants
@hugeblank

hugeblank commented Sep 28, 2017

textutils.prompt is the brainchild of numerous people that have attempted to contribute to ComputerCraft. SquidDev has mentioned this in various PR's as "super-duper READ-O-MATIC 4000 with turbo text entry", and to be quite honest, that's what it is. It is the read function on steroids, if you will.

Features:

  • All arguments are put into a table, so that they don't have to be put in any particular order, like how it is in read().
  • Type error protection has been condensed into a more understandable form.
  • Adds a few arguments, including those from read(), and others that would never make it into read():
    • replaceChar (_sReplaceChar)
    • history (_tHistory)
    • complete (_fnComplete)
    • prefix (_sDefault)
    • limit (number): As defined in #387
    • newline (boolean): As defined in #386
    • completeBGColor (number): Changes the Background color of the suggested completion values
    • completeTextColor (number): Changes the Text color of the suggested completion values
    • filter (function): takes the current input string and feeds it to a function. The function can then manipulate the string and return it.
    • customkeys (table): a table consisting of all the "special" keys, any and all of which can now be redirected to any other key. Keys that can be redirected (if not redirected, their default is just the key name, prefixed by "keys."):
      • enter
      • up
      • down
      • left
      • right
      • backspace
      • home
      • delete
      • tab
      • end (["end"])

What's really great about this function being used over read is that it allows for both command lines, and applications with a GUI alike to have greater customizability, over read(). Hopefully in the future this may be used in replacement of read().
Along with this, my hope with prompt is to have people that have wanted a specific feature implemented into read(), be put here. As there is no particular order to the arguments, it's all subject to the user's need of it.

Add textutils.prompt()
textutils.prompt is the brainchild of numerous people that have attempted to contribute to ComputerCraft. It is the read function on steroids, if you will. 
Features:
- All arguments are put into a table, so that they don't have to be put in any particular order, like read().
- Type error protection has been condensed into a more understandable form.
- Adds a few arguments, including those from read(), and others that would never make it into read():
  - replaceChar (_sReplaceChar), history (_tHistory), complete (_fnComplete), prefix (_sDefault); all arguments from read
  - limit (number): As defined in #387
  - newline (boolean): As defined in #386
  - completeBGColor (number): Changes the Background color of the suggested completion values
  - completeTextColor (number): Changes the Text color of the suggested completion values

What's really great about this function being used over read is that it allows for both command lines, and applications with a GUI alike to have greater customizability, over read(). Hopefully in the future this may be used in replacement of read(). 
Along with this, my hope with prompt is to have people that have wanted a specific feature implemented into read(), be put here. As there is no particular order to the arguments, it's all subject to the users need of it.
term.setCursorPos( sx, cy )
local sReplace = (_bClear and " ") or _tOptions.replaceChar
if sReplace then
term.write( string.sub( string.rep( sReplace, math.max( string.len(sLine) + nScroll, 0 ) ), nScroll + 1, nScroll + w ) )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

Can be shortened to:
term.write( sReplace:rep(math.max( #sLine + nScroll, 0 ):sub( nScroll + 1, nScroll + w ) )

if sReplace then
term.write( string.sub( string.rep( sReplace, math.max( string.len(sLine) + nScroll, 0 ) ), nScroll + 1, nScroll + w ) )
else
term.write( string.sub( sLine, nScroll + 1, nScroll + w ) )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

Can be shortened to
term.write( sLine:sub( nScroll + 1, nScroll + w) )

-- Find the common prefix of all the other suggestions which start with the same letter as the current one
local sCompletion = tCompletions[ nCompletion ]
sLine = sLine .. sCompletion
nPos = string.len( sLine )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

Can be shortened to
nPos = #sLine

elseif param == keys.right then
-- Right
if nPos < string.len(sLine) then

This comment has been minimized.

@lurr

lurr Sep 28, 2017

if nPos < #sLine then

-- Delete
if nPos < string.len(sLine) then
clear()
sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

sLine = sLine:sub(1, nPos) .. sLine:sub( nPos, 2 )

end
if nhistoryPos then
sLine = _tOptions.history[nhistoryPos]
nPos = string.len( sLine )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

nPos = #sLine

elseif sEvent == "paste" then
-- Pasted text
clear()
sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

sLine = sLine:sub( 1, nPos ) .. param .. sLine:sub( nPos + 1 )

if sEvent == "char" then
-- Typed key
clear()
sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

sLine = sLine:sub( 1, nPos ) .. param .. sLine:sub( nPos + 1 )

end
end
if sReplace then
term.write( string.rep( sReplace, string.len( sCompletion ) ) )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

term.write( sReplace:rep( #sCompletion ) )

-- Pasted text
clear()
sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
nPos = nPos + string.len( param )

This comment has been minimized.

@lurr

lurr Sep 28, 2017

nPos = nPos + #param

@hugeblank

This comment has been minimized.

hugeblank commented Sep 28, 2017

@lurr Most everything you nitpicked was stuff that is in the original read function. I tried to keep everything as close as possible to the style that read() was written. While your proposed changes may be nice, the goal of this PR is not to redefine the style of ComputerCraft scripts.

@dmarcuse

This comment has been minimized.

Contributor

dmarcuse commented Sep 28, 2017

@hugeblank I'd argue that keeping the exact code style in line with CC's original style isn't a good reason to avoid this kind of thing. Using colon notation and the # operator make it much shorter and easier to read IMO.

@dmarcuse

This comment has been minimized.

Contributor

dmarcuse commented Sep 28, 2017

Also, I have a few suggestions:

  • Help file. It's hard to find documentation for a lot of new features, adding a help file would make it much easier for others to use this.
  • A filter function. Called whenever the user types input, changing it before it's added to the prompt. Something like function(currentText, input) return ... end, for example. Special care might need to be taken with the paste event.
  • Configurable keys, pretty self explanatory.
@BombBloke

This comment has been minimized.

Contributor

BombBloke commented Sep 28, 2017

And I'd argue that "keeping things in line with CC's style" would be more of a reason to ditch the "arguments via a table" thing, if you really want to play that card.

@hugeblank

This comment has been minimized.

hugeblank commented Sep 28, 2017

>.< conflicting opinions, If the general consensus is to go through with lurs changes then I will... unless by divine intervention (Dan), things go the other way.

@apemanzilla I'm going to need more explanation on what you mean by points 2 and 3... even though point 3 is supposedly self explanatory,
Although I think I get what you're saying for the filter function, for example when pasting, the 'v' gets input, even though it shouldn't be? Maybe?

@BombBloke

This comment has been minimized.

Contributor

BombBloke commented Sep 28, 2017

Re the filter function, the idea is that the user presses a key, the char / paste gets sent to the function, and its return value is then treated as the actual input. For example, for pincode entry, you might write a filter function that returns "" for anything non-numeric.

@dmarcuse

This comment has been minimized.

Contributor

dmarcuse commented Sep 28, 2017

@hugeblank BB pretty much got it right with regards to the filter function. A function that's called for all input, and can change or negate it accordingly. For example, if I wanted to ignore the letter v for some reason, I could use function(text, input) return input:gsub("v", "") end.

By configurable keys, I meant adding options to change which keys (or key combos) did what - e.g. change the history forward/backward keys from up/down to page up/page down.

@hugeblank

This comment has been minimized.

hugeblank commented Sep 29, 2017

Okay, I understand the idea of the filter function, and I think I could make it happen.
And, I can easily do the configurable keys, that won't be too difficult, just a tad bit tedious :P

hugeblank added some commits Sep 29, 2017

Requested features added to textutils.prompt
This commit adds the 2 primary requested features to textutils.prompt()
1) filter (function): add a function that filters out characters/strings from the user input, EX. `textutils.prompt({filter = function( sText ) return string.gsub(sText, "%D", "") end})`; filters out everything that isn't a digit.
2) customkeys (table): a table consisting of all the "special" keys in the function, things like "keys.up" or "keys.down" can now be redirected to any other key. Ex. `textutils.prompt({customkeys = {enter = keys.space}})`; sets the typical "enter" key to the spacebar.
@hugeblank

This comment has been minimized.

hugeblank commented Sep 29, 2017

@apemanzilla @BombBloke Added both the filter function and the custom characters, killing and reviving slowWrite in the process.

...and I forgot the freaking help file, let me implement that

@dmarcuse

This comment has been minimized.

Contributor

dmarcuse commented Sep 29, 2017

I never liked slowWrite anyways.

@hugeblank

This comment has been minimized.

hugeblank commented Sep 29, 2017

Edit: ^ Is that what you meant by adding it to help

Unfortunately, it must live on...

@dmarcuse

This comment has been minimized.

Contributor

dmarcuse commented Sep 29, 2017

Well, it's better than nothing, but given how complex the function is it would be a good idea to expand on it some - maybe change it to textutils.prompt(table) - run "help prompt" for more info and then add a separate help file that goes into specifics about options?

@hugeblank

This comment has been minimized.

hugeblank commented Sep 29, 2017

My concern is that it isn't a big enough implementation to include an entire help article about it. I'll let this sit for a while and see what Bomb and others think.

@dmarcuse

This comment has been minimized.

Contributor

dmarcuse commented Sep 29, 2017

I mean, there's a lot of options already - enough to easily fill a screen. I don't think it would be a good idea to try and fit it all into the textutils page.

@hugeblank

This comment has been minimized.

hugeblank commented Sep 29, 2017

I'm saying to include everything it implements at all, not adding it to the textutils help page.

I think it would be better suited for when it gets put into release form, that way it can have it's own wiki page.

@hugeblank

This comment has been minimized.

hugeblank commented Sep 29, 2017

this is what I would want the prompt.txt file to look something like if this it may be generally accepted.

hugeblank added some commits Sep 29, 2017

Paste bugfix for textutils.prompt()
Mutilated bug that, when pasting something that a filter function saw as invalid, nPos went below 0. 
nPos is too hot to go sub zero.
Final fixes and changes to textutils.prompt()
1) Debugged customkeys so that everything now works as intended
2) The filter function now directly manipulates the output string, meaning you can now have single character and multi-character manipulation. (meaning profanity can now be watched ;D).
@thatcraniumguy

This comment has been minimized.

thatcraniumguy commented May 23, 2018

Can one of the admins verify this patch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment