jquery.terminal icon indicating copy to clipboard operation
jquery.terminal copied to clipboard

Suppress Enter don't work when using echo_newline extension

Open hoodmane opened this issue 4 years ago • 14 comments

I've tried

keypress : function(event) {
   if(event.key === "Enter"){
      event.preventDefault();
      event.stopPropagation();
      return false;
   }
},
keydown : function(event) {
   if(event.key === "Enter"){
      event.preventDefault();
      event.stopPropagation();
      return false;
   }
},
keymap : {
   ENTER : function(event){
      event.preventDefault();
      event.stopPropagation();
   }
}

but pressing ENTER still makes a new line in the terminal.

TODO:

  • [x] fix echo_newline keymap option with ENTER
  • [x] fix echo_newline keymap method with ENTER
  • [ ] document workings of keymap and events.

hoodmane avatar Feb 24 '21 23:02 hoodmane

Update: this only happens when echo_newline is included. Complete MWE:

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Test Disable Enter</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet"/>
    <!--If you comment this out it works as expected--> 
       <script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/echo_newline.js"></script> 
    <!---->
</head>
  <body>
    <script type="module">
      let term = $("body").terminal(
        (command) => {}, 
        {
          keypress : function(event) {
            if(event.key === "Enter"){
                event.preventDefault();
                event.stopPropagation();
                return false;
            }
          },
          keydown : function(event) {
            if(event.key === "Enter"){
                event.preventDefault();
                event.stopPropagation();
                return false;
            }
          },
          keymap : {
            ENTER : function(event){
                event.preventDefault();
                event.stopPropagation();
            }
          }
        }
      );
    </script>
  </body>
</html>

hoodmane avatar Feb 24 '21 23:02 hoodmane

Okay, it works if after creating the terminal I say:

term.keymap("ENTER", function(event){
    event.preventDefault();
    event.stopPropagation();
});

hoodmane avatar Feb 24 '21 23:02 hoodmane

The way keymap and keypress, keydown works is that it use return value. To prevent the key you need to return false.

jcubic avatar Feb 25 '21 13:02 jcubic

To prevent the key you need to return false.

I did that though. I think this is actually a bug in echo_newline, if you remove echo_newline script the enter key gets suppressed correctly.

hoodmane avatar Feb 25 '21 15:02 hoodmane

I'm not sure how to solve it, the ENTER is required by echo_newline, what is it exactly that you want to do?

jcubic avatar Feb 25 '21 16:02 jcubic

I see issue #645 I will need to investigate and see how I can make suppress ENTER and echo_newline, I think that I just need to execute the user ENTER before processing the my code. If the enter is suppressed I don't need to do anything so I will just check the return value of user function.

jcubic avatar Feb 25 '21 16:02 jcubic

I think for my purposes this is okay, I can just say:

term.keymap("ENTER", function(event){
    event.preventDefault();
    event.stopPropagation();
});

(I think if I use term.push / term.pop I have to set the "ENTER" handler again.)

I guess I'm just confused about the composition order for event handlers: is it normally that if I add several keymap handlers for the same key, the most recent added handler is on the outermost level? So the most recently added handler can prevent the earlier handlers from running but the earlier handlers can't block the later ones.

Then echo_newline does something weird to ensure that it always runs first / outermost even if later other handlers are added and so with echo_newline I can't stop ENTER handling? But why does it behave differently when I set the enter handler using the keymap option of the terminal command vs when I create the terminal and then use term.keymap("ENTER", handler)? And why does returning false from keypress / keydown not stop the echo_newline "ENTER" handler?

hoodmane avatar Feb 25 '21 17:02 hoodmane

Keymap use only one shortcut so you use use same shortcut two times the previous one is removed.That's why echo_newline check if user set the ENTER keymap and run it, but it do that after it do it's action that's why it's executed first. Example:

     term.keymap('ENTER', function(e, original) {
         console.log('1');
         original();
     });
     term.keymap('ENTER', function(e, original) {
         console.log('2');
         original();
     });

only second keymap will be executed and it call original which is function from terminal or cmd plugin. There are only 3 levels of nestting.

  • Lastest user funciton
  • Terminal keymap
  • cmd keymap

Some default shortcuts are in terminal like CTRL+L and some are in CMD like ArrowUP if you set your own keymap that original function will be in second argument so you can call it. Also there are functions in terminal that overwrite cmd keymap and call original so the code in CMD is also called.

NOTE: CMD is small plugin that is just the command line prompt and input.

jcubic avatar Feb 25 '21 17:02 jcubic

Okay that makes all sense. Thanks for the clear and detailed explanation!

What really got me confused was that I was trying to return false from keydown to block the handler and it wasn't working:

keydown : function(event) {
   if(event.key === "Enter"){ // wrong capitalization
      return false;
   }
}

The problem is that I said event.key === "Enter" rather than event.key === "ENTER"... >_<

hoodmane avatar Feb 25 '21 18:02 hoodmane

I'm still confused about one thing.

Why do these two code examples behave differently with echo_newline:

  1. Enter still does something unexpectedly
      let term = $("body").terminal(
        (command) => {}, 
        { keymap : { ENTER : () => {} } }
      );

and 2. enter ignored as expected

      let term = $("body").terminal(
        (command) => {}
      );
     term.keymap("ENTER", ()=>{});

Full code 1

Enter still does something.

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Test Disable Enter</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet"/>
    <!--If you comment this out it works as expected--> 
       <script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/echo_newline.js"></script> 
    <!---->
</head>
  <body>
    <script type="module">
      let term = $("body").terminal(
        (command) => {}, 
        { keymap : { ENTER : () => {} } } // <-- difference
      );
    </script>
  </body>
</html>

Full code 2

Enter disabled

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Test Disable Enter</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet"/>
    <!--If you comment this out it works as expected--> 
       <script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/echo_newline.js"></script> 
    <!---->
</head>
  <body>
    <script type="module">
      let term = $("body").terminal(
        (command) => {}
      );
     term.keymap("ENTER", ()=>{}); // <-- difference
    </script>
  </body>
</html>

hoodmane avatar Feb 25 '21 18:02 hoodmane

The reason for this is that keymap function is not overwritten by echo_newline I need to fix that. and Make first code also work. Both cases don't work as it should:

  1. it call ENTER after executing the code in echo_newline.
  2. this case just remove completely the code from echo_newline becasue there is only one user keymap.

I need to fix both cases, because even that your second example work for you it should differently behind the scene, the effect should be the same for both (like in second example) but the inner working should be different.

jcubic avatar Feb 25 '21 18:02 jcubic

Also this confusion make it good idea to document it properly. I have lot of documentation to write for the project.

jcubic avatar Feb 25 '21 18:02 jcubic

I think my PR will handle bullets 1 and 2 in the TODO here.

hoodmane avatar Feb 27 '21 20:02 hoodmane

The PR was merged to only documentation the working on events is needed here.

jcubic avatar Apr 19 '21 09:04 jcubic