Jump to content

Recommended Posts

Posted

Greetings all.

 

I'm trying to send a prompt to the command line (easy enough) which the user can then type stuff at and send commands to the rest of the program. Normally, to accomplish this one would use a (getwhatever) function. I don't believe that can be used in this case.

 

Here's my code:

 

(defun c:menumsg( / )
 (prompt (setq meuStr "Enter option (Abort/Retry/Cheerios): "))

 (setq data nil)
 (while (/= (cadr data) 97)
   (vl-catch-all-apply '(lambda ( ) (setq data (grread nil 13 1))))

   (cond
     ((and (= (car data) 2) (= (cadr data) )
      (setq meuStr (substr meuStr 1 (1- (strlen meuStr))))
      )
     ((= (car data) 2)
      (setq meuStr (strcat meuStr (chr (cadr data))))
      )
     )

   (displayMenu meuStr)
   (command "regen")
   )
 (princ)
 )

(defun displayMenu(string / strDel)
 (setq strDel "")
 (repeat (1+ (strlen string)) (setq strDel (strcat strDel "\010")))
 (prompt (strcat strDel string))
 (princ)
 )

As you can see, a while loop which terminates when the user types "a" (that's lowercase, for the moment.. it'll change later) and will update repeatedly despite user input or lack thereof. When the user types any letter other than "a", the string will have it appended, and if the user hits "backspace" the string will have one character knocked off of it. Using this conception, I could obtain any sort of user input whilst the program is running, without having to pause. This is my goal.

 

I'm nearly there, but if you run the code you'll find out (remember, type "a" to cancel it, or just mash ESC) where I'm stuck. I can add to the string of text as well as delete the information, but the prompt refuses to change, and I can't figure out why.

 

I know there is probably some other solution to my overall problem, but I'd like to figure this one out, if only to satisfy my curiosity.

 

Thank you very much for your time. ^.^

 

EDIT: Oh, and if you replace the (displayMenu meuStr) line with (princ (strcat "\n" meuStr)) you'll see exactly what I'm getting at, although it will paste it to a new line. I can edit the string properly; my code does this. It's displaying it that seems to be giving me an issue.

Posted

I believe your problem occurs as printing a backspace "\010" does not erase the text, but rather just move the cursor position to the left:

 

I have modified it slightly, but not by much:

 

(defun c:menumsg (/ data)
 (prompt (setq meuStr "Enter option (Abort/Retry/Cheerios): "))

 (while (not (and (eq 2 (car (setq data (grread nil 13 1))))
                  (member (cadr data) '(97 65))))
   (cond
     ((and (= (car data) 2) (= (cadr data) )
      (setq meuStr (substr meuStr 1 (1- (strlen meuStr)))))
     ((= (car data) 2)
      (setq meuStr (strcat meuStr (chr (cadr data))))))
   (displayMenu meuStr))
 (princ))

(defun displayMenu (string / strDel)
 (setq strDel "")
 (repeat (1+ (strlen string)) (setq strDel (strcat strDel "\010")))
 (prompt (strcat strDel string))
 (princ))

Posted

How about this:

 

(defun c:menumsg  (/ data Str)
 (princ "Enter option (Abort/Retry/Cheerios): \n")
 (setq Str "")

 (while (not (and (eq 2 (car (setq data (grread nil 13 1))))
                  (member (cadr data) '(97 65))))
   (cond
     ((and (= (car data) 2) (= (cadr data) 13))
      (princ "\n")
      (setq Str (strcat Str "\n")))
     ((= (car data) 2)
      (princ (chr (cadr data)))
      (setq Str (strcat Str (chr (cadr data)))))))
 (princ))

Posted

Still doesn't seem to be working, Lee. Yours does the same thing mine does: the string itself is indeed modified, but displaying it seems to prove a problem; backspacing deletes the last character on the string as it should, but the display on the command line doesn't change. At least, it doesn't for me.

Posted

In my latest one, the overall concatenated string is stored as a variable which can be used later, but the individual characters are printed to the command line.

 

As for the backspacing - As I said in an earlier post, the backspace does not delete a character once it has been printed to the command line, but merely shifts the cursor position to the left.

Posted

Ah, I see now.. I tested it with:

 

(princ (strcat "hello" "\010" "\010" "hi"))(princ)

(princ (strcat "hello" "\010" "\010" "h"))(princ)

which returns

 

helhi

helho

respectively. Seems that it just over-writes what's already there.

 

Is there any way, then, to delete what is displayed on the command line?

Posted

Give this a shot:

 

(defun c:menumsg  (/ data Str)
 (princ "Enter option (Abort/Retry/Cheerios): \n")
 (setq Str "")

 (while (not (and (eq 2 (car (setq data (grread nil 13 1))))
                  (member (cadr data) '(97 65))))
   (cond
     ((and (= (car data) 2) (= (cadr data) )
      (princ "\010\177\010"))       
     ((and (= (car data) 2) (= (cadr data) 13))
      (princ "\n")
      (setq Str (strcat Str "\n")))
     ((= (car data) 2)
      (princ (chr (cadr data)))
      (setq Str (strcat Str (chr (cadr data)))))))
 (princ))

Posted

I don't see what uses this has over "getstring" however... :unsure:

Posted

Almost there, Lee.. you reminded me of something very basic and I feel like an idiot for forgetting. Once again, you're an inspiration. Give me a minute! :3

Posted
...Once again, you're an inspiration...

 

I feel honoured :P

Posted

What about getkword would not work? -David

Posted

I suppose using the grread is instantaneous, whereas getkword requires an enter.

 

For instance, CAB's example:

 

[i][color=#990099];;  GetKeyPress.lsp[/color][/i]
[i][color=#990099];;  CAB  version 1.0  03/26/09[/color][/i]
[i][color=#990099];;  Get one key press from user similar to GetKword[/color][/i]
[i][color=#990099];;  keys = list of key char & return value  '(("Y" "Yes")("N" "No"))[/color][/i]
[i][color=#990099];;  def = result if ENTER is pressed  nil or "Yes" or "No" etc[/color][/i]
[i][color=#990099];;        if nil then Enter is dissallowed[/color][/i]
[i][color=#990099];;  msg = the prompt nil = "Press a key"[/color][/i]
[i][color=#990099];;  emsg = the error message nil = "Incorrect keypress."[/color][/i]
[b][color=RED]([/color][/b][b][color=BLUE]defun[/color][/b] GetKeyPress [b][color=RED]([/color][/b]keys def msg emsg [b][color=BLUE]/[/color][/b] input result[b][color=RED])[/color][/b]
 [b][color=RED]([/color][/b][b][color=BLUE]or[/color][/b] msg [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] msg [b][color=#ff00ff]"Press a key"[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
 [b][color=RED]([/color][/b][b][color=BLUE]or[/color][/b] emsg [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] emsg [b][color=#ff00ff]"Incorrect keypress."[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
 [b][color=RED]([/color][/b][b][color=BLUE]princ[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]strcat[/color][/b] [b][color=#ff00ff]"\n"[/color][/b] msg[b][color=RED])[/color][/b][b][color=RED])[/color][/b]
 [b][color=RED]([/color][/b][b][color=BLUE]while[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]null[/color][/b] result[b][color=RED])[/color][/b]
   [b][color=RED]([/color][/b][b][color=BLUE]and[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]=[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]car[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] input [b][color=RED]([/color][/b][b][color=BLUE]grread[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=#009900]2[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; keyboard entry[/color][/i]
        [b][color=RED]([/color][/b][b][color=BLUE]<[/color][/b] [b][color=#009900]31[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] input [b][color=RED]([/color][/b][b][color=BLUE]cadr[/color][/b] input[b][color=RED])[/color][/b][b][color=RED])[/color][/b] [b][color=#009900]255[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; a key was pressed[/color][/i]
   [b][color=RED])[/color][/b]
   [b][color=RED]([/color][/b][b][color=BLUE]cond[/color][/b]
     [b][color=RED]([/color][/b][b][color=RED]([/color][/b][b][color=BLUE]listp[/color][/b] input[b][color=RED])[/color][/b][b][color=RED])[/color][/b] [i][color=#990099]; not a keypress[/color][/i]
     [b][color=RED]([/color][/b][b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] result [b][color=RED]([/color][/b][b][color=BLUE]assoc[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]strcase[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]chr[/color][/b] input[b][color=RED])[/color][/b][b][color=RED])[/color][/b] keys[b][color=RED])[/color][/b][b][color=RED])[/color][/b]
      [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] result [b][color=RED]([/color][/b][b][color=BLUE]cadr[/color][/b] result[b][color=RED])[/color][/b][b][color=RED])[/color][/b]
     [b][color=RED])[/color][/b]
     [b][color=RED]([/color][/b][b][color=RED]([/color][/b][b][color=BLUE]and[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]=[/color][/b] input [b][color=#009900]13[/color][/b][b][color=RED])[/color][/b] def[b][color=RED])[/color][/b]
      [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] result def[b][color=RED])[/color][/b]
     [b][color=RED])[/color][/b]
     [b][color=RED]([/color][/b][b][color=RED]([/color][/b][b][color=BLUE]princ[/color][/b] [b][color=RED]([/color][/b][b][color=BLUE]strcat[/color][/b] [b][color=#ff00ff]"\n"[/color][/b] emsg [b][color=#ff00ff]"\n"[/color][/b] msg[b][color=RED])[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]
   [b][color=RED])[/color][/b]
 [b][color=RED])[/color][/b]
 result
[b][color=RED])[/color][/b]

[b][color=RED]([/color][/b][b][color=BLUE]defun[/color][/b] c:test[b][color=RED]([/color][/b][b][color=BLUE]/[/color][/b] ans[b][color=RED])[/color][/b]
 [b][color=RED]([/color][/b][b][color=BLUE]setq[/color][/b] ans [b][color=RED]([/color][/b]GetKeyPress
             [b][color=DARKRED]'[/color][/b][b][color=RED]([/color][/b][b][color=RED]([/color][/b][b][color=#ff00ff]"Y"[/color][/b] [b][color=#ff00ff]"Yes"[/color][/b][b][color=RED])[/color][/b][b][color=RED]([/color][/b][b][color=#ff00ff]"N"[/color][/b] [b][color=#ff00ff]"No"[/color][/b][b][color=RED])[/color][/b][b][color=RED])[/color][/b]  [i][color=#990099]; keys allowed, not case sensitive, & return value[/color][/i]
             [b][color=#ff00ff]"Yes"[/color][/b] [i][color=#990099]; default when ENTER is pressed[/color][/i]
             [b][color=#ff00ff]"Do you need an extra leader? (Y/N) [Yes]:"[/color][/b] [i][color=#990099]; message prompt[/color][/i]
             [b][color=BLUE]nil[/color][/b] [i][color=#990099]; use default error message[/color][/i]
             [b][color=RED])[/color][/b][b][color=RED])[/color][/b]
 [b][color=RED]([/color][/b][b][color=BLUE]princ[/color][/b] ans[b][color=RED])[/color][/b]
 [b][color=RED]([/color][/b][b][color=BLUE]princ[/color][/b][b][color=RED])[/color][/b]
[b][color=RED])[/color][/b]

Posted

Alright.. I had tried using the DEL escape code myself, but while it did delete, I kept getting a bunch of those little boxes you get when you try to use an ASCII code that the font you're using has no character for.

 

Looking at your example, the:

 

(princ "\010\177\010")

 

reminded me of the oldest trick in the book: if you can't delete, move your cursor back and over-write with a space!

 

(princ (strcat "\010" " " "\010"))

 

That takes care of the display, and it was already easy to capture the input as a variable. Way awesome. Here's my code:

 

(defun menumsg( / )
 (princ "Enter option (Abort/Retry/Cheerios): ")
 (setq optStr "")

 (setq data nil)
 (while (/= (cadr data) 97)
   (vl-catch-all-apply '(lambda ( ) (setq data (grread nil 13 1))))

   (cond
     ((and (= (car data) 2) (= (cadr data) )
      (if (/= optStr "") (setq optStr (substr optStr 1 (1- (strlen optStr)))))
      (princ (strcat "\010" "\010"))
      )
     ((= (car data) 2)
      (setq optStr (strcat optStr (chr (cadr data))))
      (princ (chr (cadr data)))
      )
     )
   (command "regen")
   )
 
 (princ)
 )

 

As for your last comment...

 

(getstring) pauses the function and waits for user input. Like most programs, this is a linear progression from start to finish, and when there's a command to stop and get input, the linear progression is ground to a halt. GRREAD, used properly (notice the (command "regen") in my first post), will allow the program to keep running as the user creates an input. Regenning is the only way I know how to do this.. it clears some sort of buffer which, otherwise, would force GRREAD to pause.

 

If you're feeling up to it, try taking my code and creating a simple text object which displays (getvar "DATE"), and have it update every time through the loop. Make sure you leave that (command "regen") in there! And I don't know why this is an issue, but move your cursor into the display window. If I'm not mistaken, your text object will update every second, but you'll still be allowed to type whatever you wish at your leisure.

 

That's why this is important. My ultimate goal with this is to create a client/server system in which a single Server LISP will actively read from several files, one for each active client, and consolidate that data into a single file. Each Client LISP will actively read that single file and display that data to the user, whilst at the same time allowing the client user to actively toss data into their own client file.

 

Since I don't know how to make it work over the internet, I'll start by getting it to work on our network here at work. Chat program or text-based MMORPG, hell even Chess or Pong. Useless? You bet it is. Will it kick all sorts of booty if I get it to work? Yeah. :3

Posted

haha, those are some high-hopes right there... :P

 

I can see what you are saying though, but maybe I just have never found that I needed it.

Posted

I only graduated from college two years ago, I'm pretty low on the pecking order. As such, the necessity is there for me to further my interests and my knowledge by other means... in this case, programming useless toys. Just like the first LISP I wrote to insert a block and edit it by clicking two points, the one that drew a square representing a house complete with driveway, the one that inserted symbols based on a bit of text.. and then BlitzPong, BlitzBreakout, BlitzPrint.. each one is more ambitious than the last, and whilst some may be of some use, many are, to quote those brave (or crazy) folks who topped Everest, simply because they're there.

 

I believe I can do this, but I'm not sure. I need proof. So, I make the attempt.

Posted
I only graduated from college two years ago, I'm pretty low on the pecking order. As such, the necessity is there for me to further my interests and my knowledge by other means... in this case, programming useless toys. Just like the first LISP I wrote to insert a block and edit it by clicking two points, the one that drew a square representing a house complete with driveway, the one that inserted symbols based on a bit of text.. and then BlitzPong, BlitzBreakout, BlitzPrint.. each one is more ambitious than the last, and whilst some may be of some use, many are, to quote those brave (or crazy) folks who topped Everest, simply because they're there.

 

I believe I can do this, but I'm not sure. I need proof. So, I make the attempt.

 

Thats a good attitude to have - I only make the LISPs to see if I can do it, I have no use for them personally :P

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...