SlickEdit Community

SlickEdit Product Discussion => SlickEdit® => Topic started by: shenguhan on December 25, 2009, 06:20:11 AM

Title: cursor movements caused the loss of the redo history
Post by: shenguhan on December 25, 2009, 06:20:11 AM
 This is really bothersome, Is there some way to make the undo history only track  text editing?   :(
Title: Re: cursor movements caused the loss of the redo history
Post by: chrisant on December 25, 2009, 07:43:38 PM
I find this very frustrating as well.  In my opinion it means SlickEdit essentially does not have a Redo feature.

I have not found any way to exclude cursor movement from the Undo history.
Title: Re: cursor movements caused the loss of the redo history
Post by: ScottW, VP of Dev on December 29, 2009, 05:11:57 PM
Setting def_undo_with_cursor to 1 should "enable the undo of each cursor movement". When set to 0, which is the default, it appears to treat all cursor movements in a sequence as one operation. Setting it to 1 allows you to undo each, individual cursor movement. It sounds like we need another value to completely exclude cursor movement from the undo stack.

If we do that, how should undo/redo work? Would it undo/redo the changes at the location they were made or at the current cursor location? If we undo/redo at the original location, doesn't that imply a cursor movement? It seems like undo should undo the change at the original location, but redo would make the same change at the new location. Does that sound right?

Can you describe a series of edits and how you would like this to work. I'm sorry if I sound thick, but I want to make sure I precisely understand the behaviors you want so I can file the change and get it right. Obviously, we're missing an important behavior and we must not think it's terribly obvious or we would have added it by version 14.  ;)
Title: Re: cursor movements caused the loss of the redo history
Post by: evanratt on December 29, 2009, 05:59:15 PM
I can say that for my use, what I would like to see would be the changes undone/redone at the location they were originally made. My use scenario is this:
1. Make an edit
2. Undo that edit
3. Navigate elsewhere in the file, to look at something
4. Change my mind, decide I want the edit I had originally made.
In the current implementation, once I navigate elsewhere in step 3 to check something else, I can no longer change my mind and redo my original edit.

It doesn't seem natural to me to expect redo to ever redo an operation somewhere other than the original location; if I were looking to use redo to repeat an action in this way, I would be inclined to record and execute a temporary macro.
Title: Re: cursor movements caused the loss of the redo history
Post by: jbhurst on December 29, 2009, 06:31:02 PM
I think that this improved redo idea has merit, and I believe there may be other actions that inappropriately lose undo/redo in SlickEdit (can't recall them right now).

However, I have always been one of the users that appreciates the ability to undo cursor movement. I use this all the time. Please don't break it! :-)

John Hurst
Wellington, New Zealand
Title: Re: cursor movements caused the loss of the redo history
Post by: chrisant on December 30, 2009, 09:42:19 PM
If we do that, how should undo/redo work? Would it undo/redo the changes at the location they were made or at the current cursor location? If we undo/redo at the original location, doesn't that imply a cursor movement? It seems like undo should undo the change at the original location, but redo would make the same change at the new location. Does that sound right?

Can you describe a series of edits and how you would like this to work. I'm sorry if I sound thick, but I want to make sure I precisely understand the behaviors you want so I can file the change and get it right. Obviously, we're missing an important behavior and we must not think it's terribly obvious or we would have added it by version 14.  ;)

Ah, I get your question, that had never occurred to me.
I would expect both Undo and Redo to always undo/redo the change in its original location, and move the cursor to whereever it was as of that change.

Overall I am very happy with the SlickEdit Undo model:  I have def_undo_with_cursor set to 0, and I found that I actually really like that the cursor movement is in the undo stack.

The trouble comes with the symmetry in the Redo model:  if I press Undo and then for example hit End or scroll to see the end of a line (or any other cursor movement) then that cursor movement discards the content redo stack.

I guess that what I'm intuitively expecting is some kind of a partial differentiation between content redo and cursor redo after I've hit Undo, but only until I make a content change.

Here is an example:
1.  Type "hello" press Enter
2.  Type "big" press Enter
3.  Type "world" press Enter
4.  Press Undo ("world" disappears cursor moves to after the Enter from step 2)
5.  Press Up twice (cursor is now on "hello")
6a.  If I press Undo, I want the cursor to go back to where it was after step 4
6b.  Or if I press Redo, I really expect "world" to reappear and the cursor to go to where it was after step 3
6c.  Or if I type something, then I expect the redo stack to get cleared -- but not until I actually make a content change.

Does that make sense?  My reasoning is that content is much more important than cursor movement, and it seems undesirable to discard the more important content redo stack just because I did some kind of cursor movement.

I should soften my original statement -- it's not that SlickEdit has no Redo feature, it's just that my fingers insist on making cursor movements and the Redo stack is almost always empty by the time I decide I need to Redo.
Title: Re: cursor movements caused the loss of the redo history
Post by: shenguhan on December 31, 2009, 06:47:32 AM
I think the best way is to add a Goto Last/Next Edit Location function, separate cursor movement records from Redo/Undo functions. ::)
Title: Re: cursor movements caused the loss of the redo history
Post by: Graeme on December 31, 2009, 11:59:37 AM
I've tried 3 other editors and they all do what chrisant has described - as soon as you change content, the redo history is cleared and not before.  Microsoft Word also does that but it has an additional feature which is that when there's nothing to redo, the redo command/shortcut changes into "repeat last change".

I still use undo cursor quite often to take me back to the place I last made a content change (despite having xretrace (http://community.slickedit.com/index.php?topic=4693.msg19253#msg19253)), so I hope that capability doesn't disappear.

Graeme
Title: Re: cursor movements caused the loss of the redo history
Post by: myk on March 26, 2010, 02:15:43 PM
I posted something about this a couple of years back (http://community.slickedit.com/index.php?topic=2253.0).  Returning to SlickEdit over 2 years later, I'm sorry to see it still hasn't been addressed.

ScottW, if you want to see the sort of behaviour I'd prefer, look at Kate in KDE/Kubuntu, TextPad or Word or Visual Studio in Windows, or just vim.  I'm actually surprised there's this level of confusion over a pretty common behaviour.  And for the record, I'm not saying there shouldn't be an option to include cursor movements in the undo stack.  (On the occasions where I do want to return to my previous edit point without reverting the edit, I just undo then redo immediately.)

The cursor movement thing would mostly just be a nuisance, except that it completely breaks the redo history, as shenguhan said.  There's another problem with SlickEdit's undo behaviour, but I'll put that in a separate post.
Title: Re: cursor movements caused the loss of the redo history
Post by: pdebonte on July 06, 2010, 12:35:13 PM
myk wrote:
> where I do want to return to my previous edit point without reverting the edit, I just undo then redo immediately.

I do the same, and like everything in a consistent GUI (e.g. MS Windows), I do it instinctively [e.g. how many of you actually read most dialogs before hitting OK or Cancel?].  With SlickEdit, however, my instincts fail so often it is frustrating [and in the case of Ctrl-Arrow, I'd even call it aggravating, but I've remapped those now].  If an application is going to do something counter to every other application out there, I think it had better at least provide an option to follow the standard.

-Pete

P.S. - I see I now have negative Hero points: does that mean I have villain points? Oh well.
Title: Re: cursor movements caused the loss of the redo history
Post by: ScottW, VP of Dev on July 06, 2010, 06:26:03 PM
Hmm, "villain points". I like the sound of that. Maybe if you accumulate enough of them you can achieve Evil Genius status. Then you would be allowed to recruit henchfolk (my proposed alternative to the sexist term, "henchmen").

As for the undo history, change requests have been filed, but I doubt this will be changed any time soon. It's one of those cases where amending the current implementation is unsavory. I think Clark would like to redo our undo mechanism.
Title: Re: cursor movements caused the loss of the redo history
Post by: pektusin on June 14, 2011, 04:25:54 PM
Any progress on that? It is a very serious bug, really annoying. You edit your file a lot, then want to look how it was before the changes, one mouse click - and history is gone! I consider SE as an editor w/o undo/redo and it spoils overall editor impression very much.
Title: Re: cursor movements caused the loss of the redo history
Post by: volovyan on June 14, 2011, 04:35:59 PM
SlickEdit 2011 - almost unable to use because of this issue. Redo history is gone; now I have to save a file after each and every change to not have to type it again should an accidental cursor movement occurred after undo.
Title: Re: cursor movements caused the loss of the redo history
Post by: Phil Barila on June 14, 2011, 06:29:24 PM
Take a look at Tools->Options->Editing->Cursor Movement->"Undo affects cursor movement".  Set to True or False?  Mine is set to False, I haven't tried it set to True.  I think it might be the switch that combines all cursor movements without any edits into one "Undo Cursor Movement" operation, which effectively makes it a "Go back to the site of the last edit".

I think it would be a major improvement if SE would behave like many other apps and divorce cursor movement from content changes. 

On the other hand, I've actually used Ctrl+Z to undo a cursor movement.

What I would really like is a separate "Undo/Redo cursor movement", independent of "Undo/Redo edits".
Title: Re: cursor movements caused the loss of the redo history
Post by: volovyan on June 14, 2011, 09:16:11 PM
I tried setting it to True, doesn't help.
Here is the problem: you type something (e.g. hello world) on a line, then undo until only "hello" is here. Then move cursor. No more Redo. You have to type "world" manually once again. Imagine if it is not only just one word "world" and you applied undo several times  - you will lose whatever you had before undos unless you save quite often.
Title: Re: cursor movements caused the loss of the redo history
Post by: Stu on June 16, 2011, 03:58:30 PM
maybe it should be as simple as dont commit cursor movement to the undo stack until a physical change in file is made. once another action is performed, then commit preceeding cursor actions.

Title: Re: cursor movements caused the loss of the redo history
Post by: chrisant on July 18, 2011, 08:05:19 AM
Bump.  Whenever I really need Redo, it doesn't actually work because SE is so aggressive about discarding the content Redo stack whenever any kind of movement occurs.  Even just clicking the mouse discards the content Redo stack.

This has forced me to try to change my workflow.  To be successful at that I have to remember ahead of time that SE discards the content Redo stack aggressively, before I hit Undo in the first place.  So what I do now is basically hit Save every couple of lines.  Which pollutes the SE backup history and reduces its effectiveness (sifting through 120 "revisions" from a single day to try to find something is awkward).

It's not uncommon for me to hold down Undo for a bit, accidentally overshoot where I meant to go, but need to move the cursor to be able to detect that I overshot.  And once I've done that there's nothing I can do about having overshot, the Redo stack is already gone.  If I'm lucky the SE backup history will have the changes I'm looking for, but it's cumbersome to try to find what I'm looking for that way (because the lack of Redo has made me save every couple of lines).  I end up using Save As, then open several backup files and Save As each of them to temp files, then close SE without saving (saving could potentially nuke the only copy of the text and force me to reinvent it).  Then I use other tools to compare the several files and extract the bits I need and use another editor to get the file to have the right content again.  Then I launch SE again and continue.

It's not the highest priority, but it's a bit of an "in your face" fit and finish item.  Hopefully it can be addressed before too long.
Title: Re: cursor movements caused the loss of the redo history
Post by: Graeme on July 20, 2011, 11:11:27 AM

This has forced me to try to change my workflow.  To be successful at that I have to remember ahead of time that SE discards the content Redo stack aggressively, before I hit Undo in the first place.  So what I do now is basically hit Save every couple of lines.  Which pollutes the SE backup history and reduces its effectiveness (sifting through 120 "revisions" from a single day to try to find something is awkward).

Dunno if this is any use but your post reminded me that when this problem came up a year ago I fiddled round with trying to use backup history as a solution too.  At the time I gave up and didn't post the code but I can't remember what the problem was.  I just tried it in V16 and it sort of seems to work.

The idea is to use x_undo and x_redo instead of undo redo.  x_undo switches the backup location, saves the file, restores the backup location before calling undo.    If x_redo finds nothing to redo it fires up backup history but with the alternate backup location selected.  You can left click in the bottom pane of the backup history window to switch backup locations.

I definitely don't recommend using this, it's very clunky.  I'm just posting it in case it gives you an idea.



Code: [Select]
#include "slick.sh"

#pragma option(strictsemicolons,on)
#pragma option(strict,on)
#pragma option(autodecl,off)
#pragma option(strictparens,on)

#import "tagform.e"
 
 


#define UNDO_BACKUP_FOLDER 'C:/gp/dev/temp1/b1'

// non static allows inspection with set-var
_str my_normal_backup_folder;
int x_redo_timer_handle;
int x_undo_timer_handle;
int x_undo_holdoff_counter;
int x_redo_holdoff_counter;

/**
 * Writes current buffer to filename.  This function is a hook function
 * that the user may replace.  Options allowed by <b>_save_file</b>
 * built-in may be specified.
 * @param filename parameter should not contain options.
 *
 * @appliesTo Edit_Window
 *
 * @categories File_Functions
 *
 */
_str save_file(_str filename,_str options)
{
   boolean was_undo = false;
   // the following 3 lines are added to handle x_redo
   _str vb = get_env('VSLICKBACKUP');
   if (vb == UNDO_BACKUP_FOLDER) {
      set_env('VSLICKBACKUP', my_normal_backup_folder );
      was_undo = true;
   }
   say(vb);

   typeless status=_save_file(options " "filename);
   if (!status && file_eq(strip(filename,'B','"'),p_buf_name)) {
      call_list('_cbsave_');
      if (def_autotag_flags2&AUTOTAG_ON_SAVE) {
         TagFileOnSave();
      }
   }
   if (was_undo && _tbIsVisible('_tbdeltasave_form')) {
      set_env('VSLICKBACKUP', UNDO_BACKUP_FOLDER );
   }
   return(status);
}


static int x_redo_holdoff_counter;

void x_redo_timer_callback(boolean force_normal = false)
{
   if (x_redo_holdoff_counter > 0) {
      say(' kk4 ' :+ x_redo_holdoff_counter);
      --x_redo_holdoff_counter;
      return;
   }
   _str vb = get_env('VSLICKBACKUP');
   if (vb != UNDO_BACKUP_FOLDER) {
      _kill_timer(x_redo_timer_handle);
      _cbsave_BackupHistory();  // force refresh
      return;
   }
   if (!_tbIsVisible('_tbdeltasave_form') || force_normal) {
      say(' kk5 ' :+ x_undo_holdoff_counter);
      set_env('VSLICKBACKUP', my_normal_backup_folder );
      _kill_timer(x_redo_timer_handle);
//    int wid = _find_formobj("_tbdeltasave_form", 'n');
//    if (wid) {
//       wid.p_caption = 'Backup History';
//    }
      _cbsave_BackupHistory();  // force refresh
      return;
   }
}



void x_undo_timer_callback()
{
   say(' kk1 ' :+ x_undo_holdoff_counter);
   if (--x_undo_holdoff_counter <= 0) {
      _kill_timer(x_undo_timer_handle);
   }
}


_command void x_undo() name_info(','VSARG2_MARK|VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX/*|VSARG2_NOEXIT_SCROLL*/)
{
   if (x_undo_holdoff_counter > 0) {
      x_undo_holdoff_counter = 10; // seconds
      undo();
      x_redo_timer_callback(true);
      say(' kk2 ' :+ x_undo_holdoff_counter);
      return;
   }
   x_undo_holdoff_counter = 10; // seconds
   say(' kk3 ' :+ x_undo_holdoff_counter);
   set_env('VSLICKBACKUP', UNDO_BACKUP_FOLDER );
   _save_file(p_buf_name :+ ' -O +DD -Z -ZR -E -S -L ');
   set_env('VSLICKBACKUP', my_normal_backup_folder );
   undo();
   undo();
   x_undo_timer_handle = _set_timer(1000,x_undo_timer_callback);
   x_redo_timer_callback(true);
}


_command void x_redo() name_info(','VSARG2_MARK|VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
   _control ctl_BH_comment_note2;
   x_redo_holdoff_counter = 2;
   if (redo() == NOTHING_TO_REDO_RC) {
      set_env('VSLICKBACKUP', UNDO_BACKUP_FOLDER );
      activate_deltasave();
      _cbsave_BackupHistory();  // force refresh
      x_redo_timer_handle = _set_timer(500,x_redo_timer_callback);
      int wid = _find_formobj("_tbdeltasave_form", 'n');
      if (wid) {
         //wid.p_caption = 'Backup History $$$$$  UNDO  $$$$$';
         wid.ctl_BH_comment_note2.p_text =
            '<FONT face="Helvetica" size="2"><b>$$$ UNDO HISTORY $$$</b><br>PATH: ' :+ UNDO_BACKUP_FOLDER ;
      }
   }
}


// 1 2

// 1 2 3
// 1 2
// 1 2 3
// 1x_redo
// 4 5

definit ()
{
   if (arg(1)!="L") {
      // editor invocation
      my_normal_backup_folder = get_env('VSLICKBACKUP');
      if (my_normal_backup_folder == '') {
         set_env('VSLICKBACKUP', 'C:/GP/Dev/temp1/B2');
         my_normal_backup_folder = 'C:/GP/Dev/temp1/B2';
      }
   }
   x_undo_holdoff_counter = 0;
   x_redo_holdoff_counter = 0;
}

defeventtab _tbdeltasave_form;
void ctl_BH_comment_note2.lbutton_down()
{
   _str vb = get_env('VSLICKBACKUP');
   if (vb != UNDO_BACKUP_FOLDER) {
      set_env('VSLICKBACKUP', UNDO_BACKUP_FOLDER );
      _cbsave_BackupHistory();  // force refresh
      int wid = _find_formobj("_tbdeltasave_form", 'n');
      if (wid) {
         //wid.p_caption = 'Backup History $$$$$  UNDO  $$$$$';
         wid.ctl_BH_comment_note2.p_text =
            '<FONT face="Helvetica" size="2"><b>$$$ UNDO HISTORY $$$</b><br>PATH: ' :+
            UNDO_BACKUP_FOLDER :+ '<br>Left click here to swap' ;
      }
   }
   else
   {
      set_env('VSLICKBACKUP', my_normal_backup_folder );
      _cbsave_BackupHistory();  // force refresh
   }
}