Sublime Forum

SOLVED - If View Scratch == True in own group and closed manually, it'll close scratch AND next view which takes focus - reset scratch = fix -When sublime text automatically closes an empty group, the next file which takes focus is closed with it.... Why?

#1

I’m working on making my plugin stand-alone - I thought this one issue stemmed from a different plugin but the same happens under different circumstances which leads me to believe it may be SublimeText related…

Note: With the CodeMap addon - it happens about every single time you open the code-map panel and close it using the show_code_map command from a menu or the key command… alt + m + m + release-alt… The group opens with a blank file… When the group closes it closes the next file which takes focus on top of the blank file and the empty group… This is an issue…

With CodeMap this issue occurs whether I use the middle mouse to close the panel, or if I use the command…


With my plugin it only happens if I use middle-mouse to close the file ( and the empty group is closed automatically by Sublime Text ) - but if I use the code to open and close the layout, then it works as expected unless I save a file which is auto-refreshed which erases some vars ( because it is still in development I don’t have logic to detect if the panel is already open in these cases but I will - the problem for me is that I don’t trust user input, and being able to close the file in the group with middle-mouse and having sublime text close the group needs to be allowed but the issue of it taking other files with it is highly problematic…


Code Map and I use different code - I saw this bug in his addon earlier and I added some checks to fix it - and it does in some cases except when using the middle-mouse… but I’m using the default addon right now and phasing it out while I code my addon…


The user should be able to close the group any way they see fit whether using the context menu, main plugin settings / options menu, using reset layout from Sublime Text, middle-mouse or X button on the tab, etc… without any of their files being closed in the process…

I am leaning towards this being an issue with SublimeText, but I haven’t tried everything in terms of debugging, but I’m almost out of ideas… The code is very simple…

Adjust the window layout by multiplying 0.25 for all open cells ( this shrinks the size of them relatively so the 0.25 or 25% width will be available for the new panel / cell / column being added – use division to undo it )… Below is a list of the differences…

Layout Before: {‘cols’: [0.0, 1.0], ‘cells’: [[0, 0, 1, 1]], ‘rows’: [0.0, 1.0]}
Layout After: {‘cols’: [0.0, 0.75, 1.0], ‘cells’: [[0, 0, 1, 1], [1, 0, 2, 1]], ‘rows’: [0.0, 1.0]}

In short - columns, as said above, are multiplied by 0.25 to modify the size, divide to undo it, so 1 becomes 0.75… then 1.0 is added to the end… divide to undo and pop the last… A new cell is added using x1, y1, x2, y2 format for column / row positioning. rows aren’t changed…

Here are the changes from the undo operation:

Layout Before: {‘cols’: [0.0, 0.75, 1.0], ‘cells’: [[0, 0, 1, 1], [1, 0, 2, 1]], ‘rows’: [0.0, 1.0]}
Layout After: {‘cols’: [0.0, 1.0], ‘cells’: [[0, 0, 1, 1]], ‘rows’: [0.0, 1.0]}

– and again, when using code to remove it, it all works great - the problem is when closing the tab / view open in the new group… All cases of closing the group / panel needs to work without any issues…

I have yet to create the ‘as small as possible’ code sample.

Expected behavior

I expect to be able to open a column and a file in that column using code, and then close it any way I want - using middle mouse or via code, or via menu to reset layout… without it closing any other files…

Actual behavior

If I create it with code, and use middle mouse to close - then 2 files are actually removed - the blank file within the right panel opened up and the next file which takes focus on the left after the right panel closes…

I have noticed odd issues with one of the minimaps closing when adjusting panels with code - I’m attempting to pin down exactly how to do this because this would be gold for my addon…


Does anyone know why this is happening? Does anyone have experience with it, and why?

It could be with how the group is created so the pseudocode is:

Window get layout as _layout
grab column and cell info as _cols and _cells

for each column modify the width by multiplying 0.25 ( or dividing on removal )

If showing then add another column value by pushing 1.0 onto the list. and add the cell
if hiding then pop the last value from columns and pop the last cell

Run command set layout with new information

if show then open the blank file and then call a callback to set up options for that view - ie font face, size, etc…
if hide then call close on the blank file after ensuring focus is set to that particular and making sure the view and all still exists…


That works flawlessly - but closing with middle mouse just causes 2 files to be closed and I have no code which executes when something is closed…

0 Likes

#2

I kept having the issue even after disabling plugins I have which aren’t languages, etc… - the one that came to mind is CodeMap since the bug is seen it it too but it is the only other plugin I have which opens a group and closes it - but after disabling it the bug persisted… I even tried disabling the others so it’s likely related to Sublime Text internally - I’ll make sure I go over everything and create a simple short code example to submit as a bug report…

For now, I decided to cave, for now, and write a hack… I’m giving a sacrifice to the Sublime Text Bug Deity who causes this bug ( it has to be Sublime Text related because nothing in my code closes a panel other than ACMS - Panel file - and if it doesn’t exist, it doesn’t execute…

This is what I did…


##
## This Event Listener is specifically designed to maintain the plugin itself - it is used to reload / re-process the mapping panel output when files it is mapping have changed, etc...
##
class AcecoolCodeMappingSystemEventListener( sublime_plugin.EventListener ):
	##
	## Callback - Called when a file / view is closed...
	##
	def on_close( self, _view ):

		##
		## Bug Fix - Called when ACMS - Panel File is closed using middle mouse or using tab X - this prevents the next file to receive focus from being closed too by giving a Sacrifice to the Sublime Text Bug Deity who causes this bug...
		##
		if ( IsSublimeView( _view ) and _view.file_name( ) !=  None ):
			## Grab the window
			_window = AcecoolSublime.GetWindow( )

			##
			if ( AcecoolString.GetFileName( _view.file_name( ) ) == ACMS( ).__panel_name__ ):
				_window.new_file( )
				_window.run_command( 'close' )

I added on_close to the Plugin Event Listener and, as said above, I’m giving Sublime Text a sacrificial file to cannibalize…

I’d honestly like to find out why this is happening, so once I get my plugin released as standalone on the Package Control I’ll set up the simple code example and try it on a clean version of Sublime Text… For now, the sacrifice to Sublime Text works…

Edit: AcecoolString.GetFileName( ) simply splits \ and returns -1 to get the last of all paths…

0 Likes

#3

It would definitly be easier to diagnose and see where the problem lies if you could come up with a minimal set of code that exhibits this. It may also be useful to temporarily use a portable Sublime version for testing, since it would be guaranteed to be 100% clear of anything external and see if you can still make the same thing happen.

1 Like

#4

I am planning on setting up a minimum code example as soon as possible… The hack works, but as I say: Just because it works, doesn’t make it right…

So the strange thing is, I can open the group using code, and close the group using code along with closing the file after opening, both with code and all works flawlessly… but if I use the tab X or middle mouse to close the tab then it takes something else with it…

The hack detects when it is closed ( which happens when it is closed using code or the user closes it manually ) and creates a new file, then closes that file…

With that set of instruction, there is no issue…

Heck, if I don’t close the new file and I close it manually in the group the group closes without any issues…

So it could be with how I’m creating it, or with how I’m creating the group… but why work flawlessly with code and not with user input? Or, it could simply be the file - it is set as read only and scratch is set… I’ll play around with those too to see if they have something to do with it because the new file created doesn’t have those markers set and the issue only happens when the user manually closes it… - I need to really isolate WHY it is happening and that may or may not be easier on the portable version… I’ll play around with these first…

I’ll get started on setting up a portable Sublime Text for testing these things… but as the hack resolves the issue for now I want to get the addon ready for release and come back to that afterwards…

0 Likes

#5

And that’s it…

	##
	## Callback - Called when a file / view is closed...
	##
	def on_close( self, _view ):
		## Bug Fix - Called when ACMS - If Scratch is set to True, and it is in a group by itself, and the file is closed manually by the user - then it'll close the Scratch file, and the next file which takes focus... Ensuring Scratch is false corrects the issue...
		if ( IsSublimeView( _view ) and _view.file_name( ) !=  None ):
			if ( AcecoolString.GetFileName( _view.file_name( ) ) == ACMS( ).__panel_name__ ):
				AcecoolSublime.SetViewScratch( _view, False )

If Scratch is set to True, and it is in a group - and the group closes then it’ll consume another file…

I set it to false on Close and now the hack is resolved… excellent…

note:

## IsSublimeView
def IsSublimeView( _data ):		return _data != None and str( type( _data ) ) == '<class \'sublime.View\'>'


##
##
##
class AcecoolString
	## Returns the filename with file extension from path/to/file.ext
	def GetFileName( _file = '' ):
		return _file.split( '\\' )[ - 1 ]

EDIT: Now that I know the cause - I’ll test this by setting a blank file as Scratch and close it in a group created by Sublime Text main menu… If it causes the closing of 2 files in this case then it is a back-end issue and it doesn’t get any more light-weight than press menu > Select 2 columns, make sure 2 files are open in left column and open a single file in the right, - for the file on the right set Scratch to True, middle mouse click it…

0 Likes

#6

For what it’s worth, you can test if an item is a View with something like the following rather that testing what it’s description string contains:

>>> isinstance(view, sublime.View)
True
>>> isinstance(window, sublime.View)
False
>>> isinstance(view, sublime.Window)
False
>>> isinstance(window, sublime.Window)
True
>>> isinstance(None, sublime.View)
False
2 Likes

#7

Also, that hook is always called with a view, but may be None, so the only thing you need to do is testing whether the value is None. Also note that in Python you should use is and is not when checking for. None.

0 Likes

#8

Cheers - I was using is x for the other comparisons but it didn’t seem to work for sublime.View.


##
## Data-Type Helpers...
##

##
def IsFunction( _data = None ): return str( type( _data ) ) == "<class 'function'>" or str( type( _data ) ) == "<class 'method'>"

## A Boolean is a 1 bit data-type representing True / False or as 1 / 0 in most languages.
def IsBoolean( _data = None ): return type( _data ) is bool

## A List is a list created using [ ]s - It can contain a series of values - the index must be whole-numerical
def IsList( _data = None ): return type( _data ) is list

## A Tuple is a list created using ( )s - It is similar to a List but a Tuple is fixed in size once ccreated.
def IsTuple( _data = None ): return type( _data ) is tuple

## A Dict is a list created using { }s - It is a powerful data-type which allows string / etc.. key data-types, paired with a value which can be any Data-Type.
def IsDict( _data = None ): return type( _data ) is dict

## A String is a text object typically contained and / or created within quotes..
def IsString( _data = None ): return type( _data ) is str			# ( _typeof == "<class 'string'>" )

## A Complex is a traditional Int as a whole number from 0-255
def IsComplex( _data = None ): return type( _data ) is complex

## An Integer, traditionally is a whole number not exceeding 255 - otherwise it typically has a range of 2.7 or so million... +/-
def IsInteger( _data = None ): return type( _data ) is int

## A long is a number as 123L which can represent octal and hexadecimal values
## def IsLong( _data = None ): return type( _data ) is long

## A Float is half-size Double number with decimal support
def IsFloat( _data = None ): return type( _data ) is float

## A Number is an integer, float, double, etc..
def IsNumber( _data = None ): return IsComplex( _data ) or IsInteger( _data ) or IsFloat( _data ) # or IsLong( _data )

The one instance where it didn’t work was for functions

So I tried using sublime portable… x64… On one occasion the group closed, but it didn’t close any files… then when using non untitled files, the group wouldn’t close when empty…

It may be another addon ( not CodeMap because I tried disabling it ) which is causing the issue, or it has to do with the generated cell, column…

First things first - working on my addon… then as I continue, I will be debugging - seeing if disabling certain addons will correct the issue ( after trying the generated code, etc… as is )… IF it has the issue with just the code, then we can work on a solution - if an addon is causing the issue then It’d be interesting to see the code which causes it… Although I’ve disabled almost every single mod - I have sync sidebar bg for the color, sublime linter is disabled, some of the default packages are disabled such as Lua because I use GMod Lua…

It’s good to have found the singular cause of the issue in my set-up, however I still need to reproduce it elsewhere or find out why it’s behaving this way…

I’ll try copying my settings over to the portable version later on, but I didn’t see anything relating to closing an empty group, etc… and I have no idea why the group closed once, but never again ( when I created the group from the menu - I tried using simple view / layout columns, and using groups - it was with the group option that it closed, but I wasn’t able to reproduce despite having repeated identical steps… even restarting st3.p… - I may have to delete and start fresh to get that action again although before I chase that I’ll work on the other things )…

0 Likes