codejar icon indicating copy to clipboard operation
codejar copied to clipboard

[Feature Request] Multiline Indentation with Tab Key

Open StevenEWright opened this issue 2 years ago • 6 comments
trafficstars

@antonmedv

It appears https://github.com/antonmedv/codejar/issues/64 was closed as complete, but I don't think this feature exists in codejar.

If you're open to it, I may be willing to contribute the feature, but I wanted to ask your opinion before I bothered.

Is this something codejar would like to have, and would you be open to a PR for it?

Thanks,

Steve

StevenEWright avatar May 11 '23 07:05 StevenEWright

This feature seems very complicated. I think there are a lot of things to do. For example, improve the handling of newline in empty editor.

antonmedv avatar May 11 '23 08:05 antonmedv

Could you elaborate on why you think it may be complicated?

It seems like a relatively straight forward change to the tab handling routine to simply iterate over the selected lines and insert (or remove, if it's shift-ed) a tab character from the beginning of each line. Is there some complexity to it I'm missing?

Please let me know if this is something you'd be willing to work with me on if I send you a PR or if you'd prefer to focus your time on other things like the newline problems.

Thanks for the response!

Steve

StevenEWright avatar May 11 '23 10:05 StevenEWright

Check it in chrome,safari and firefox.

antonmedv avatar May 11 '23 11:05 antonmedv

perhaps a solution could be:

  1. Get raw code of selected HTML
  2. Apply multiline indentation on raw code (for each line prefix with tab).
  3. Apply highlighting on raw code => new HTML code
  4. Replace selected HTML with new HTML code.

Am I missing something?

Edit: Perhaps the problem could be to find the start and end position of selected HTML if the selection starts/ends between the start and/or end line.

julianpoemp avatar May 12 '23 09:05 julianpoemp

This feature seems very complicated. I think there are a lot of things to do.

@antonmedv This can sometimes be a tad extraneous when loc sizes are in the thousands.

Perhaps the problem could be to find the start and end position of selected HTML if the selection starts/ends between the start and/or end line.

@julianpoemp You can just leverage the existing logic. Based on what I quickly browsed over in the source for CodeJar, the below should work for a few hundred loc~line. Supports dedent and indent.

Someone should test.

EDIT 1

Consider moving around tab Indent handler


/* add with the keydown event, in codejar that is here */

on('keydown', (event) => {
  
    // other code .....
   
   // pass directly after the options.history recording,
   handleMultilineIndent(event)
   
})

/*  the multiline tab indent */
function handleMultilineIndent (event: KeyboardEvent) {


    if (event.key === 'Tab') {

      event.preventDefault();

 
      // Obtain selection
      const sel = getSelection().getRangeAt(0).toString();  
       // Newlines
      const nwl = sel.split('\n');  
      // Cached length 
      const itm = nwl.length;

      let len = 0; // Holds the increment/decrement for restore()

      if (event.shiftKey) { // Dedent, ie: shift + tab

         const pos = save();  // Save pos

        for (let i = 0; i < itm; i++) {

          // We want the padding upto the first non whitespace character
         // while regex here is a little extraneous it suffices.
          const space = nwl[i].slice(0, nwl[i].search(/\S/));
          
          // Handle dedents
          if (space.length > options.tab.length) {
            nwl[i] = nwl[i].slice(options.tab.length);
            len = len + options.tab.length;
          } else if (options.tab.length > 0) {
            len = len + 1;
            nwl[i] = nwl[i].slice(1);
          }

        }

        insert(nwl.join('\n'));  // Rejoin

        if (pos.dir === '->') {
          restore({ start: pos.start - len, end: pos.end });
        } else {
          restore({ start: pos.start, end: pos.end - len });
        }

      } else {

       // Tab indent on multiline
       const pos = save();

        for (let i = 0; i < itm; i++) {
          nwl[i] = options.tab + nwl[i];
          len = len + options.tab.length;
        }

        insert(nwl.join('\n'));

        if (pos.dir === '->') {
          restore({ start: pos.start + len, end: pos.end });
        } else {
          restore({ start: pos.start, end: pos.end + len });
        }
      }

    }
  }

panoply avatar Jun 16 '23 02:06 panoply

@panoply Thank you for the jump-start. Please checkout my PR - I'd be interested in hearing your thoughts on the Firefox situation.

StevenEWright avatar Jul 23 '23 18:07 StevenEWright