SlickEdit Community

SlickEdit Product Discussion => SlickEdit® => Topic started by: bogedo on March 08, 2021, 08:47:08 pm

Title: Centre text on open
Post by: bogedo on March 08, 2021, 08:47:08 pm
i'd like to know if it is possible to configure a filetype to centre all its text when a file matching the filetype is opened. let's take a txt filetype for example, is there any way to configure SlickEdit to centre all the text in a .txt file on opening ? such a feature would work like the "shift left" or "shift right" commands. in this case, the entire block of text will be moved, without modification, to the centre of the editor when a file is opened.
Title: Re: Centre text on open
Post by: Graeme on March 08, 2021, 09:59:59 pm
I don't understand what you mean by center text - can you give a diagram or something.

It's possible to run a macro when a new buffer is opened  - any function whose name starts with "_buffer_add_" gets automatically called when a new file is opened.  Add the following code to vusrmac.e in your configuration folder, load it with the "load module" command in the macro menu to try it.  The "say" command outputs text to a debug window.


Code: [Select]
void _buffer_add_center_text(_str old_buffer_name, _str options="")
{
  if ( get_extension(p_buf_name) == "txt" ) {
     say("i'm a text file" :+ p_buf_name);
  }

  if ( p_LangId == "fundamental" ) {
     say("i'm fundamental" :+ p_buf_name);
  }
}

Title: Re: Centre text on open
Post by: bogedo on March 09, 2021, 08:39:04 pm
nice one, again SlickEdit surprises me with its flexibility.

what i mean by centering the text can best be seen when you select all the text in an opened file and use the "Shift Selection Right" command. the entire block of text is shifted right. some screenshots:

Normal:

(https://i.imgur.com/9uHF7sQ.png)

Centred:

(https://i.imgur.com/4jOzn2S.png)

so what i'd like to see accomplished is a specific filetype being centred on open as seen in the second screenshot.
Title: Re: Centre text on open
Post by: Graeme on March 10, 2021, 08:55:13 am
I had some spare time so I wrote a macro you can play with.  You might not need anything this complex though.  It tries to find the number of visible columns on the screen using the end_window() function  - this seems to get too big a number sometimes and a spurious horizontal scroll occurs  - so if this happens you get prompted to enter the number of columns you want to shift right (or left). 

After the shift is done, the macro enters a loop (an "event loop") which allows you to adjust the centered column using left-arrow or right-arrow   - or ctrl-left-arrow, ctrl-right-arrow to go 5 columns at a time.  You can also use end, home, up, down, page-up, page-down to move around.  Press ESC to exit the event loop.

If a selection already exists it operates on that selection only, otherwise it does select-all.  If you have the cursor on a blank line and run the command it will do a shift right equal to the number of visible columns you have  - which is probably not what you want.  If the first non blank character on the current line is in column 15 and you have 100 visible columns it will do a shift right of 35 columns to get the first non blank on the current line to be at column 50.

You can call this macro from the earlier code I posted.  If you didn't know about the arg_shift_selection command - it might be all you need.  It prompts you for the number of columns you want to shift the selection by.


Code: [Select]
bool xhz_center_text_is_enabled = false;

_command void xhz_center_text_enable_toggle() name_info(',')
{
   xhz_center_text_is_enabled = !xhz_center_text_is_enabled;
   _message_box(xhz_center_text_is_enabled ? "enabled" : "disabled");
}


_command void xhz_center_text() name_info(','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_MARK)
{
   typeless save_sel;
   bool was_sel = false;
   if ( !xhz_center_text_is_enabled ) {
      return;
   }
   if ( select_active() != 0 ) {
      if (save_selection(save_sel) == 0)
      {
         was_sel = true;
         begin_select();  // goto to start of selection
      }
   }

   entry_start_col := _mdi.p_child.p_col;
   entry_start_line := _mdi.p_child.p_line;
   typeless p1;
   save_pos(p1);
   begin_line();   // make col 1 visible
   end_window();   // bottom right of visible window
   
   x1 := _mdi.p_child.p_col / 2;  // we want first non blank to be here
   if ( _mdi.p_child.p_left_edge != 0 ) {
      // the window has scrolled horizontally - means end_window() went wrong
      x1 = 0;
   }

   restore_pos(p1);
   center_line();            // vertical
   first_non_blank();
   first_nbcol := _mdi.p_child.p_col;

   if ( was_sel )
      restore_selection(save_sel);
   else
   {
      select_all();
      restore_pos(p1);
   }
   // say(x1 :+ " " :+ first_nbcol);

   if ( x1 == 0 )
      arg_shift_selection("R");    // end_window() went wrong
   else if ( x1 > first_nbcol)
      shift_selection_right(x1 - first_nbcol);
   else if ( first_nbcol > x1 )
      shift_selection_left(first_nbcol - x1);
   else
      arg_shift_selection("R");   // the text was already centered

   _message_box("Press ESC to exit, -> shift right, <- shift left, +ctrl=faster");

   while ( 1 ) {
      // make numpad keys work properly
      // int orig_auto_map_pad_keys=_default_option(VSOPTION_AUTO_MAP_PAD_KEYS);
      // _default_option(VSOPTION_AUTO_MAP_PAD_KEYS,0);
      _str key = get_event('N');   // refresh screen and get a key
      _str keyt = event2name(key);
      // _default_option(VSOPTION_AUTO_MAP_PAD_KEYS,orig_auto_map_pad_keys);
      switch (keyt) {
         case ' ' :
            xhz_center_text_is_enabled = false;
         case 'ESC' :
         case 'ENTER' :
            if ( !was_sel ) {
               deselect();
            }
            _mdi.p_child.p_col = entry_start_col;
            _mdi.p_child.p_line = entry_start_line;
            center_line();            // vertical
            return;
         
         case 'RIGHT' :
            shift_selection_right(1);
            continue;
         case 'LEFT' :
            shift_selection_left(1);
            continue;
         case 'HOME' :
            begin_select();
            continue;
         case 'END' :
            end_select();
            continue;
         case 'C-LEFT' :
            shift_selection_left(5);
            continue;
         case 'C-RIGHT' :
            shift_selection_right(5);
            continue;
         case 'PGUP' :
            page_up();
            continue;
         case 'PGDN' :
            page_down();
            continue;
         case 'DOWN' :
            cursor_down();
            continue;
         case 'UP' :
            cursor_up();
            continue;

      }
   }
}


Title: Re: Centre text on open
Post by: Graeme on March 10, 2021, 09:18:45 am
I've just updated the code to allow you to enable/disable the command from doing anything  - since you probably don't want text files to get centered at editor startup or when you switch workspaces.  In the event loop you can hit the SPACE key to disable the command and exit.

xhz_center_text_enable_toggle toggles enable / disable.

Title: Re: Centre text on open
Post by: bogedo on March 10, 2021, 11:34:40 am
Thank you for taking your time out to write code to add this feature it is impressive work. i sincerely appreciate it.

the macro works well when bound to a hotkey but i'd like to have it run when a specific filetype is opened without having to use the hotkey(correct me if i'm wrong, but would adding the "_buffer_add_" command to "xhz_center_text" to make "_buffer_add_xhz_center_text" make the macro run at file open ?). would it be possible to add an option to set a filetype(s) for the macro to work on ? so if a user wants it to only work on .ini files they can set it in the macro or if they wanted it to work on only .ini and .log files it would be possible to set it to only run when these files are opened ?

is it possible to specifiy the number of columns to shift left or right for the "arg_shift_selection" command ? if so you are right in that it may be easier to configure the macro to shift the text block a specific number of columns and call it a day since it seems that centring it could turn out to be tricky.
Title: Re: Centre text on open
Post by: Graeme on March 10, 2021, 01:02:48 pm
You can type
shift-selection-right  25
on the slick command line or you can call
shift_selection_right(25);
in macro code.  (or left)

You can call arg_shift_selection("R", 25) in macro code but the main point of this function is to prompt the user for the number and it won't prompt if you specify the number of columns.

If you add the _buffer_add prefix to the xhz function then that function will get called whenever any file is opened in the editor  - including at startup or workspace switch - I suspect that's not what you want.
You could add this code to the xhz function to restrict the file types.

if ( !(get_extension(p_buf_name) == "txt")
     && !(get_extension(p_buf_name) == "ini")  )
     return;

To stop the function from running on workspace open you need the enable / disable code I added.

You could write your own gui-open function
_command gui_open_and_center_text()
{
   xhz_center_text_is_enabled = true;
   gui_open();
   xhz_center_text_is_enabled = false;
}
or just
_command gui_open_and_center_text()
{
   gui_open();
   xhz_center_text();
}


 
Title: Re: Centre text on open
Post by: bogedo on March 10, 2021, 10:08:07 pm
You can type
shift-selection-right  25
on the slick command line or you can call
shift_selection_right(25);
in macro code.  (or left)

You can call arg_shift_selection("R", 25) in macro code but the main point of this function is to prompt the user for the number and it won't prompt if you specify the number of columns.


this is valuable information, i've combined the code you've written in this thread and come up with this(please overlook and correct any mistakes made as i'm not a programmer)

Code: [Select]
_command void xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "txt")
     && !(get_extension(p_buf_name) == "ini")  )
     return;
   select_all()
   arg_shift_selection("R", 60)
   deselect()
}

what i'm trying to accomplish with this(Thank you very much for the code you posted as this is derived from it) is:

- double click a .txt or .ini file in a file manager,
- since the two are already associated with SlickEdit, they'll be opened in the editor,
- have the macro run without user input and centre the text in the .txt or .ini file opened,
- the macro will only run when .ini and/or .txt files are opened.

with those objectives laid out, the above code only works when called by a hotkey, it is not automatic. how can the code be modified to run when an .ini and/or .txt file is opened ?

Title: Re: Centre text on open
Post by: Graeme on March 11, 2021, 10:59:26 am
As I've mentioned before, if you add the _buffer_add prefix to your function name it will run when any buffer is opened  - including at startup and when you switch workspaces.

If the only time you want the macro to run is when you double click a file in explorer, then you can associate the txt and ini file extensions with a batch file  - if you're using Windows.  The batch file can run slickedit like this

vs.exe %1  -#xhz_center_text

You could also add the batch file to the Windows "send to" list and use right click send-to.

Another way as I already mentioned  - the following command will allow you to choose a file to open, then run the xhz command.

_command void gui_open_and_center_text()
{
   gui_open();
   xhz_center_text();
}

You're missing some semicolons in your code

_command void xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "txt")
     && !(get_extension(p_buf_name) == "ini")  )
     return;
   select_all();
   arg_shift_selection("R", 60);           // could be just shift_selection_right(60);
   deselect();
}

Title: Re: Centre text on open
Post by: bogedo on March 14, 2021, 05:57:48 pm
Thank you for the tips and indeed, as you mentioned, adding _buffer_add_ now ensures that the macro is run when a specified file is opened in SlickEdit. i had to remove the _command from _command void xhz_center_text() to make it work, it now works very well. i'm impressed by SlickEdit's macro feature it is very very feature rich.

now to some questions if you do not mind:

- i have not found references to _buffer_add_ in the manual is this an undocumented command or have i not looked hard enough. same goes for the arg_shift_selection("R", 60) way of writing the command.

- is it possible to use a macro to hide the toolbars and tool-windows only when a particular filetype is opened ? let say you want to edit a .html file in a minimal editing environment, is there a macro that can be configured to run when a html file is opened that will hide all toolbars and tool-windows or hide toolbars and tool-windows that a user specifies ?

Thank you.
Title: Re: Centre text on open
Post by: Graeme on March 14, 2021, 11:12:41 pm
Regarding _buffer_add prefix, if you search slick source code for call_list whole word only, you'll see all of the prefixes that are available.  It's an undocumented feature.  You'll see there's a prefix _switchbuf_ that is for when you switch to a different buffer, also _cbsave_ for when you save a buffer.  This should really be in the help  - or maybe in SlickCMacroBestPractices.pdf

For arg-shift-selection, it is in the help.  One way to find things like this is go to help in the main menu, then "macro functions by category" then "selection functions".  The function names give you a pretty good idea what the function will do.

For tool windows  -  Slick V23 introduced save_named_layout and load_named_layout commands.  These allow you to save and restore all your tool-windows and toolbars with a particular layout  - you get prompted for a name for each layout.  So if you call save_named_layout from the command line and save a layout as "t1" you can create a command to load that layout like this  - and bind a key to it.

Code: [Select]
_command void  t1() name_info(',')
{
   load_named_layout("t1");
}

https://community.slickedit.com/index.php/topic,17426.msg71156.html#msg71156 (https://community.slickedit.com/index.php/topic,17426.msg71156.html#msg71156)

Title: Re: Centre text on open
Post by: Graeme on March 14, 2021, 11:16:39 pm
Also in case you didn't know, each workspace remembers its own toolbar / toolwindow layout.
Title: Re: Centre text on open
Post by: bogedo on March 15, 2021, 11:12:41 am
Regarding _buffer_add prefix, if you search slick source code for call_list whole word only, you'll see all of the prefixes that are available.  It's an undocumented feature.  You'll see there's a prefix _switchbuf_ that is for when you switch to a different buffer, also _cbsave_ for when you save a buffer.  This should really be in the help  - or maybe in SlickCMacroBestPractices.pdf


agreed, SlickEdit is extremely powerful and it is a pity that a user someimes has to go out of their way to seek out all its features. the help could also benefit from a few examples to get people going with Slick-C this way new users can get up to speed quicker with the language and macros in SlickEdit.


For arg-shift-selection, it is in the help.  One way to find things like this is go to help in the main menu, then "macro functions by category" then "selection functions".  The function names give you a pretty good idea what the function will do.


noted, Thank you for the suggestion.


For tool windows  -  Slick V23 introduced save_named_layout and load_named_layout commands.  These allow you to save and restore all your tool-windows and toolbars with a particular layout  - you get prompted for a name for each layout.  So if you call save_named_layout from the command line and save a layout as "t1" you can create a command to load that layout like this  - and bind a key to it.

Code: [Select]
_command void  t1() name_info(',')
{
   load_named_layout("t1");
}

https://community.slickedit.com/index.php/topic,17426.msg71156.html#msg71156 (https://community.slickedit.com/index.php/topic,17426.msg71156.html#msg71156)

this looks promising. i've tested it with the extension restricting code you posted and it works when a specified fileype is tied to a saved layout

Code: [Select]
if ( !(get_extension(p_buf_name) == "html"))
     return;
   load_named_layout("minimal");

but i've run into an issue.

- i would like to open html files in a minimal environment that has no toolbars and tool-windows. i've created such a layout and named it "Minimal".

- i've also created a layout called "Default" for all other files other than html's that i would like to view/edit with the toolbars and tool-windows i've configured visible.

when i open a html file the layout "minimal" is loaded. but unless "default" is re-loaded, all other files other than html's will be loaded in the "minimal" layout. this is where i need help. i've determined that the best option would be to have .html files open a new window with the "minimal" layout. but i foresee some issues:

- how would other html files opened from the system be assigned to the new window using the "minimal" layout ?
- how would files that i would not want to be opened in the window running the "minimal" layout be assigned to the default window running the "default" layout ?

to illustrate the two questions with a use case:

- open a .ini file and it opens in a window running the "default" layout.
- open a .txt file and it will open in the same window.
- open a .html file and a new window will open running the "minimal" layout.
- open an xml file and it will be opened in the window with the "default" layout
- open another .html file and it will open in the window with the "minimal" layout

in total there should be two windows(is it even possible to accomplish this in one window ?) with multiple edit tabs. the default layout window with three tabs(.ini, .txt, .xml) and the minimal layout window with two tabs(.html and .html)

i appreciate your continued patience with me in sharing your knowledge as it is inspiring me to do more with Slick-C.
Title: Re: Centre text on open
Post by: Dan on March 15, 2021, 12:55:57 pm
Thank you for the tips and indeed, as you mentioned, adding _buffer_add_ now ensures that the macro is run when a specified file is opened in SlickEdit. i had to remove the _command from _command void xhz_center_text() to make it work, it now works very well. i'm impressed by SlickEdit's macro feature it is very very feature rich.

now to some questions if you do not mind:

- i have not found references to _buffer_add_ in the manual is this an undocumented command or have i not looked hard enough. same goes for the arg_shift_selection("R", 60) way of writing the command.

- is it possible to use a macro to hide the toolbars and tool-windows only when a particular filetype is opened ? let say you want to edit a .html file in a minimal editing environment, is there a macro that can be configured to run when a html file is opened that will hide all toolbars and tool-windows or hide toolbars and tool-windows that a user specifies ?

Thank you.

++heroPoints;
Title: Re: Centre text on open
Post by: Graeme on March 15, 2021, 10:55:04 pm

Quote
in total there should be two windows(is it even possible to accomplish this in one window ?) with multiple edit tabs. the default layout window with three tabs(.ini, .txt, .xml) and the minimal layout window with two tabs(.html and .html)

I can't tell what you mean by "window" or what you mean by "open a file".

When you open a file in slick that isn't already open, functions with the _buffer_add prefix get called because a new buffer is created (added) for the file.  If you switch to a file that is already open in slick, functions with the _switchbuf_ prefix get called  - because you are switching buffers.  Hence you might be able to get what you want just by changing your _buffer_add prefix to _switchbuf_.  If you need to center text, then use _buffer_add_ to do the centering and _switchbuf_ to select the layout.

When you say "window" do you mean a floating edit window?

What setting do you have for the "one file per window" option
tools -> options -> editing -> editor window -> files per window.
I don't really know what this option does any more but it might make a difference to you.

Floating edit windows can choose a tool-window layout by right click on the doc tab and select "layouts".  This layout setting is completely separate from the "save-named-layout" "load-named-layout" thing.  The non floating MDI window does not have a "layout" option in the doc tab context menu.  Also a floating edit window seems to be always on top of the MDI window so if you're going to use floating windows then you probably need one for html and one for default.  This would be hard to get working properly I think - it's not easy to get html files to open in the html window and others to the other window.

For _switchbuf_ you probably want to avoid switching layouts every time you switch buffers if the correct layout is already open, so you need a local static variable.

Code: [Select]
void _switchbuf_xselect_twlayout(_str oldbuffname, _str flag)
{
    static bool layout_is_default;
    if ( (get_extension(p_buf_name) == "html"))
    {
        if (layout_is_default || oldbuffname :== "")
              load_named_layout("minimal");
         layout_is_default = false;
         return;
    }

    if (!layout_is_default || oldbuffname :== "")
          load_named_layout("minimal");
     layout_is_default = true;

}

There's a potential problem with the above code - when the editor first starts and the first buffer is opened, the static variable might not match the layout.  The check for oldbuffname being empty may or may not fix it so you should call switchbuf from buffer_add like this

void _buffer_add_xhz_center_text()
{
     _switchbuf_xselect_twlayout("", ""); 
}

 
Title: Re: Centre text on open
Post by: bogedo on March 16, 2021, 12:11:10 am

Quote
in total there should be two windows(is it even possible to accomplish this in one window ?) with multiple edit tabs. the default layout window with three tabs(.ini, .txt, .xml) and the minimal layout window with two tabs(.html and .html)

I can't tell what you mean by "window" or what you mean by "open a file".


apologies if i was not clear enough, by window i mean the SlickEdit program window so when i was talking about two windows i meant two SlickEdit instances and by "open a file" i meant opening a file in SlickEdit by double clicking it in Windows Explorer.


What setting do you have for the "one file per window" option
tools -> options -> editing -> editor window -> files per window.
I don't really know what this option does any more but it might make a difference to you.


it is the default "One file per window" though the description is not clear in what the selection is for.

Hopefully the clarification makes clear what i'd like to accomplish. Thank you for the sample code and the advice will try it out and see if it works out.
Title: Re: Centre text on open
Post by: Graeme on March 16, 2021, 01:50:47 am
ok, let me know if switchbuf will work for you.  If not, multiple instances might be possible using DDE.
Title: Re: Centre text on open
Post by: bogedo on March 18, 2021, 10:52:41 pm
got it to work when opening files from file explorer with this code:

Code: [Select]
void _buffer_add_xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "html")
     load_named_layout("default");
   else{
      load_named_layout("minimal");
      select_all();
      arg_shift_selection("R", 65);
      }
}

when html files are opened the "minimal" layout is loaded(this is a stripped down layout with only the menu bar visible). when other filetypes are opened the "default" layout(this is a layout i created with all the toolbars and tool-windows i'd like to use and have named default) is used. now the challenge would be:

- switching layouts when switching document tabs. lets say i open a html file, the "minimal" layout is loaded; then i open a txt file, the "default" layout is loaded. when i switch from the txt file to the html file it will be displayed in the "default" layout because the txt file was the last file to be opened and i would like it to be displayed in the "minimal" layout and the reverse; when a html file is opened and is using the "minimal" layout, i would like all other open files that are not html to load the "default" layout when you switch to them. you may have had a point about using switchbuf to accomplish this but i need help to be able to use it to switch layouts when a user switches tabs.

Thank you for your continued support.

Title: Re: Centre text on open
Post by: Graeme on March 18, 2021, 11:15:03 pm
just use the code I posted here
https://community.slickedit.com/index.php/topic,18107.msg71322.html#msg71322

For _switchbuf_ you probably want to avoid switching layouts every time you switch buffers if the correct layout is already open, so you need a local static variable.

Code: [Select]
void _switchbuf_xselect_twlayout(_str oldbuffname, _str flag)
{
    static bool layout_is_default;
    if ( (get_extension(p_buf_name) == "html"))
    {
        if (layout_is_default || oldbuffname :== "")
              load_named_layout("minimal");
         layout_is_default = false;
         return;
    }

    if (!layout_is_default || oldbuffname :== "")
          load_named_layout("minimal");
     layout_is_default = true;

}

There's a potential problem with the above code - when the editor first starts and the first buffer is opened, the static variable might not match the layout.  The check for oldbuffname being empty may or may not fix it so you should call switchbuf from buffer_add like this

void _buffer_add_xhz_center_text()
{
     _switchbuf_xselect_twlayout("", "");
}

 
Title: Re: Centre text on open
Post by: bogedo on March 19, 2021, 12:37:25 am
hmm, tried it but it did not work, perhaps i'm doing it wrong. is this how i should combine it with my existing code ?

Code: [Select]
void _buffer_add_xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "html")
     load_named_layout("default");
   else{
      load_named_layout("minimal");
      select_all();
      arg_shift_selection("R", 65);
      }
}

void _switchbuf_xselect_twlayout(_str oldbuffname, _str flag)
{
    static bool layout_is_default;
    if ( (get_extension(p_buf_name) == "html"))
    {
        if (layout_is_default || oldbuffname :== "")
              load_named_layout("minimal");
         layout_is_default = false;
         return;
    }

    if (!layout_is_default || oldbuffname :== "")
          load_named_layout("minimal");
     layout_is_default = true;

}
Title: Re: Centre text on open
Post by: Graeme on March 19, 2021, 11:28:31 am
You actually have a syntax error here

void _buffer_add_xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "html")     <<<<<<<<<<<<<< missing a closing parenthesis


so when you load your macro it's not actually loading.  The error gets reported on the command line - it's easy to miss.  I actually sometimes miss these - it would be better if it was a modal dialog.

However, the code is crashing slickedit  - so I'm going to do this another way using a timer.  I'll post the code tomorrow.  In the meantime, don't try this code any more - you might get a crash.


Title: Re: Centre text on open
Post by: bogedo on March 19, 2021, 12:40:01 pm
apologies, it seems i did not paste it correctly and i missed the closing parentheses, that part of the code is working well.
i'm seeing an issue when switchbuf is called. i get a crash when loading the macro, when trying to do this:

Code: [Select]
void _buffer_add_xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "html"))
     load_named_layout("default");
   else{
      load_named_layout("minimal");
      select_all();
      arg_shift_selection("R", 65);
      }
}
void _switchbuf_loadlayout()
{
   if ( !(get_extension(p_buf_name) == "html"))
   load_named_layout("default");
}

but when i test it with this:

Code: [Select]
void _buffer_add_xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "html"))
     load_named_layout("default");
   else{
      load_named_layout("minimal");
      select_all();
      arg_shift_selection("R", 65);
      }
}
void _switchbuf_loadlayout()
{
   if ( !(get_extension(p_buf_name) == "html"))
   select_all();
}

it works as expected.
Title: Re: Centre text on open
Post by: bogedo on March 24, 2021, 08:16:27 pm
switchbuf was unstable for me. got it working using "_on_document_tab_left_click()" this works the way i want it to. here is the code including he center text bit. in summary, when a configured file is opened(in this case html files) it is centered in the middle of the editor and loaded in a "minimal" environment with no toolbars or tool-windows. the "_on_document_tab_left_click()" handles switching layouts between document tabs that contain different filetypes.

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

void _buffer_add_xhz_center_text()
{
   if ( !(get_extension(p_buf_name) == "html"))
     load_named_layout("default");
   else{
      load_named_layout("minimal");
      select_all();
      arg_shift_selection("R", 65);
      }
}

void _on_document_tab_left_click()
{
   if ( (get_extension(p_buf_name) == "html"))
      load_named_layout("minimal");
   else
   {
      load_named_layout("default");
   }
}

now to the challenges:

- i'd like to be able to also switch layouts when using the key sequence(Ctrl+Tab) which is the default sequence for switching between document tabs.

- when opening SlickEdit i get this error:

(https://i.imgur.com/TFuJKVJ.png)

this also happens when SlickEdit is opened from a file explorer by double clicking an associated file.
Title: Re: Centre text on open
Post by: Graeme on March 24, 2021, 10:41:10 pm
I didn't get back to this yet, sorry.  I'll have a go at doing it with a timer in the next couple of days.

Graeme
Title: Re: Centre text on open
Post by: Graeme on March 25, 2021, 04:44:57 am
I'm unable to get load_named_layout working reliably from a timer callback either, sorry.  From the look of the error you're getting in restore.ex, you won't be able to call load_named_layout from the _buffer_add function reliably either.  You can easily write a command macro to switch to a particular layout and bind it to a key though.

Ctrl+TAB runs the command next_window so you just need to write you own macro and bind ctrl+tab to it.

_command void my_ctrl_tab()
{
   next_window();
   // do whatever you want here
   if ( (get_extension(p_buf_name) == "html"))
      load_named_layout("minimal");
}

For ctrl+shift+tab the function is prev_window.


I guess you copied _on_document_tab_left_click from slick source window.e  ??
 
Code: [Select]
void _on_document_tab_left_click()
{
   if ( !p_mdi_child || !_isEditorCtl(false) ) {
      return;
   }
   // Here we simulate the old file tabs tool window auto-reload which occurs
   // when you click on a tab (because edit command was called on the filename).
   // Don't need/have the old_buffer_name. Just pass null. That way, get a Slick-C
   // stack if the old_buffer_name is used.
   _switchbuf_files(null,'E');
   //say('_on_document_tab_middle_click : wid='p_buf_name);
}

Did you realise that your code will override the code in window.e for _on_document_tab_left_click  -  whichever is last loaded wins.  Maybe you should combine the two

Code: [Select]
void _on_document_tab_left_click()
{
   if ( !p_mdi_child || !_isEditorCtl(false) ) {
      return;
   }
   // Here we simulate the old file tabs tool window auto-reload which occurs
   // when you click on a tab (because edit command was called on the filename).
   // Don't need/have the old_buffer_name. Just pass null. That way, get a Slick-C
   // stack if the old_buffer_name is used.
   _switchbuf_files(null,'E');
   //say('_on_document_tab_middle_click : wid='p_buf_name);

   if ( (get_extension(p_buf_name) == "html"))
      load_named_layout("minimal");
   else
   {
      load_named_layout("default");
   }

}

If a hotfix for window.e comes along one day, it will override your code when you install the hotfix.


Title: Re: Centre text on open
Post by: bogedo on April 01, 2021, 08:23:19 pm
I didn't get back to this yet, sorry.  I'll have a go at doing it with a timer in the next couple of days.

Graeme

no worries, you've gone above and beyond with this issue and i sincerely thank you for your efforts.

I'm unable to get load_named_layout working reliably from a timer callback either, sorry.  From the look of the error you're getting in restore.ex, you won't be able to call load_named_layout from the _buffer_add function reliably either.  You can easily write a command macro to switch to a particular layout and bind it to a key though.


well it seems that the issue with load_named_layout is in the hands of the developers now. it is a shame it works unreliably since it would be wonderful to have the layout change automatically without using hotkeys. that being said it is really impressive the amount of customization a user can do with Slick-C and Thank you for helping me get into it.

Ctrl+TAB runs the command next_window so you just need to write you own macro and bind ctrl+tab to it.

_command void my_ctrl_tab()
{
   next_window();
   // do whatever you want here
   if ( (get_extension(p_buf_name) == "html"))
      load_named_layout("minimal");
}

For ctrl+shift+tab the function is prev_window.


works beautifully, Thank you.

I guess you copied _on_document_tab_left_click from slick source window.e  ??
 
Code: [Select]
void _on_document_tab_left_click()
{
   if ( !p_mdi_child || !_isEditorCtl(false) ) {
      return;
   }
   // Here we simulate the old file tabs tool window auto-reload which occurs
   // when you click on a tab (because edit command was called on the filename).
   // Don't need/have the old_buffer_name. Just pass null. That way, get a Slick-C
   // stack if the old_buffer_name is used.
   _switchbuf_files(null,'E');
   //say('_on_document_tab_middle_click : wid='p_buf_name);
}

Did you realise that your code will override the code in window.e for _on_document_tab_left_click  -  whichever is last loaded wins.  Maybe you should combine the two

Code: [Select]
void _on_document_tab_left_click()
{
   if ( !p_mdi_child || !_isEditorCtl(false) ) {
      return;
   }
   // Here we simulate the old file tabs tool window auto-reload which occurs
   // when you click on a tab (because edit command was called on the filename).
   // Don't need/have the old_buffer_name. Just pass null. That way, get a Slick-C
   // stack if the old_buffer_name is used.
   _switchbuf_files(null,'E');
   //say('_on_document_tab_middle_click : wid='p_buf_name);

   if ( (get_extension(p_buf_name) == "html"))
      load_named_layout("minimal");
   else
   {
      load_named_layout("default");
   }

}

If a hotfix for window.e comes along one day, it will override your code when you install the hotfix.




i'm grateful for the tip and the heads-up will modify my code accordingly.
Title: Re: Centre text on open
Post by: bogedo on April 01, 2021, 08:39:48 pm
final issue, i've found that when tabs are closed the next tab is loaded with the layout the previous tab had.

lets say you have a tab with a txt file opened and a tab with a html file opened.
when the html file is opened, the "minimal" layout is applied and when a txt file is opened, the "default" layout is applied.
when the txt file is the active file and it is closed SlickEdit moves on to the next open file which is the html file and it is opened with the "default" layout.
since i would like the html file to always be loaded in a "minimal" layout, how would i be able to accomplish this given the use case laid out above ? i have a feeling that switchbuf may be the command for this but it appears to be unreliable when paired with load_named_layout. is there another command that can be used to run a macro when a tab is closed so that:

- close a tab by clicking the 'x' on the tab
- SlickEdit checks the extension of the next file that will load and applies a layout
Title: Re: Centre text on open
Post by: Graeme on April 02, 2021, 06:37:33 am

There's another way to show / hide tool-windows.  For most / all tool-windows there is an activate-command to show the window and a toggle command to show/ hide.  So you can make a "hide" command by combining them.

Code: [Select]
_command void hide_clipboards() name_info(',')
{
   activate_clipboards();
   toggle_clipboards();
}

This doesn't let you set the location or size of the window though.  Use the keybindings dialog and find commands that start with activate to find them all  - activate_defs etc.


I've sent the code below to slickedit support  - they should be able to reproduce a crash I think - in a clean config using V25.0.1.

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

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



#if 1
static bool layout_is_default;
static int my_layout_timer_handle;
static int my_layout_startup_counter;
static _str my_layout_current_buf_name;



static void my_layout_timer_callback1()
{
   if (!_use_timers || my_layout_timer_handle < 0)
      return;

   if (++my_layout_startup_counter < 6)
      return;

   my_layout_startup_counter = 6;

   if (_no_child_windows()) {
      return;
   }

   if (my_layout_current_buf_name != _mdi.p_child.p_buf_name){
      my_layout_current_buf_name = _mdi.p_child.p_buf_name;
   }
   else {
      if ( get_extension(_mdi.p_child.p_buf_name) == "html" )
      {
         //say("html " :+ layout_is_default :+ " x " :+ oldbuffname );
         if (layout_is_default)
            load_named_layout("minimal");
         layout_is_default = false;
      }
      else
      {
         //say("nothtml " :+ layout_is_default :+ " x " :+ oldbuffname );
         if (!layout_is_default)
            load_named_layout("default");
         layout_is_default = true;
      }
   }

   _kill_timer(my_layout_timer_handle);
   my_layout_timer_handle = _set_timer(1000, my_layout_timer_callback1);
}


void _switchbuf_my_layout_timer()
{
   if (my_layout_startup_counter < 6)
      return;

   _kill_timer(my_layout_timer_handle);
   my_layout_timer_handle = _set_timer(50, my_layout_timer_callback1);
}


definit()
{
   if (arg(1) == "L") {
      _kill_timer(my_layout_timer_handle);
   }
   my_layout_timer_handle = _set_timer(1000, my_layout_timer_callback1);
   my_layout_startup_counter = 0;
   my_layout_current_buf_name = "";
}

#endif
Title: Re: Centre text on open
Post by: bogedo on April 02, 2021, 01:00:58 pm

There's another way to show / hide tool-windows.  For most / all tool-windows there is an activate-command to show the window and a toggle command to show/ hide.  So you can make a "hide" command by combining them.

Code: [Select]
_command void hide_clipboards() name_info(',')
{
   activate_clipboards();
   toggle_clipboards();
}

This doesn't let you set the location or size of the window though.  Use the keybindings dialog and find commands that start with activate to find them all  - activate_defs etc.

[/code]
interesting, good to know this bit of information. though i can see the code being a bit long if i choose to hide all tool-windows. is there also a command to hide toolbars ? if it can be combined with the hide tool-windows code, a minimal layout can be achieved in the same way loading the "minimal" layout does.

I've sent the code below to slickedit support  - they should be able to reproduce a crash I think - in a clean config using V25.0.1.

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

#pragma option(strictsemicolons,on)
#pragma option(strict,on)
#pragma option(autodecl,off)
#pragma option(strictparens,on)
...
Thank you for reporting this to them, hopefully they can get to the bottom of the load_named_layout issues..