Sublime Forum

Automatic Build System selector based on string in folder name

#1

Hi Guys,

I have written my own build system for Sikuli, which is python based and it is working perfectly.
I just want to get AUTO build selection to work.

Now the only way for Sublime to understand that I don’t want to build in python but in Sikuli is for the selector to check the folder name as
“selector”: “$file_path:*.sikuli”
or something similar because inside each projectname.sikuli folder there is the python file.
And just a python file would of course want to build in python, which is good, but I need the selector to check for *.sikuli in the project folder name.

How do we do this??

I’m on V3 B3143 (latest ST3 as of today).

0 Likes

#2

BUMP.

Dev guys, have you seen this?!

0 Likes

#3

Can you share a full path of a sikuli file that you are editing and that you want to build, and the exact command you intend to run (as you would in a terminal)?

0 Likes

#4

Basically the way it works in Sikuli, is that the project file is a .py python file inside a folder that is called “someprojectname”.sikuli .

I’ve got the build process sorted that is fine, my build system is working perfectly.

But I want to get the auto build system selection working, which is tricky because that actual file I’m editing is a python file so the system wants to build it with my python build system, which is great for when I’m only working on python files.
BUT when that pythin file is inside a filder called *.sikuli, the auto build selector should know that it is should select my Sikuli build system instead of my Python build system.

This is why I though putting something like this in my Sikuli build system file would solve it: “selector”: “$file_path:*.sikuli”
So that the selector checks the file’s parent folder name for a .sikuli string, but it’s not working.

0 Likes

#5

using a scope selector to try to filter a file path won’t work, instead you should look at the keyfiles property:
http://www.sublimetext.com/docs/3/build_systems.html#options

I’m not sure if that accepts wildcards or folder names, but at the least you can create an empty .sikuli file in your project folder and set the build system to check for that.

0 Likes

#7

Thanks, I’ve tried the keyfile preference but no change unfortunately.
When I press CTRL+SHIFT+B it shows me both my Python and my Sikuli build systems as an option, but it is still not selecting the right build system automatically.

BTW without this preference in my build system it is still showing me my Sikuli build system as an option from CTRL+SHIFT+B so I don’t think this has made any difference.

I’ve tried two things in my build system:
"keyfile" : "$file_base_name.html"
(because besides the python file in the .sikuli parent folder there is an .html file with the same exact name as the python file.

And this:
"keyfile": "this.sikuli"

Same results, not really working unfortunately.

0 Likes

#8

the syntax is "keyfiles": ["this.sikuli"]

0 Likes

#9

I’ve changed it but now it is not even offering me my Sikuli build system as an option in CTRL+SHIFT+B!

This is my build system at the moment:

{
“cmd”: [“D:/SikuliX/runsikulix.cmd”, “-r”, “$file_path”],
“file_regex”: “^[ ]File "(…?)”, line ([0-9]*)",
“shell”: true,
“keyfiles”: [“this.sikuli”]
}

(with proper indentation, but that’s not showing up here)

0 Likes

#10

Bump.

So what do you think is the solution??

0 Likes

#11

BUMP

Any solution guys??!

0 Likes

#12

So, build systems work in a way that the last selected build system will be run until it doesn’t apply to a file you’re editing, in which case it will ask you with the candidates that apply. I believe that this is stored per project, but am not sure.

What that means is that as long as you are building on files that your sikuli build system applies to, st will continue using that build system. If you use many new projects and would have to set the sikuli build system frequently, it might make sense to select it in the Tools menu, which will override the automatic build system finding heuristic.

If that is still not enough for you, you’ll have to resort to writing a plugin that does je required magic for you, which is certainly possible.

0 Likes

#13

Thanks, I know what the build system is and how it works.
And no, this is not out of the scope of the build system, I do not need to write a plugin.
All this needs is for the built in functions to work properly.
The “keyfiles” concept is fine and would do what I need if it worked, but it is buggy.
This is why I am waiting for the devs to finally see this post so they can check out why the keyfiles flag is not working…

0 Likes

#14

Since you don’t have a solution because of bugs or other issues - here’s something viable but will need a little bit of work to finish - a few lines plus definitions.

Create a new plugin - I use _Acecool for simple development based tests, etc… and _AcecoolHotfix or similar when writing plugins to correct bugs introduced by other plugins, or sublime text, or to change generalized behavior while remaining backwards compatible, etc…

Creating a plugin to handle this for you is actually pretty easy… When a file is clicked, on activated or on activated async ( although I wouldn’t use that unless setting the var / setting for the build system does a lot in the background as it’s quick and easy ) update the build system based on rules - if applicable… if not then don’t touch it…

Create a new Event Listener - you want on_activated - it is called when a view is clicked…

If you look at the main menu you can see some of the basic commands which are run, but not all - but all you need to do is _view.window( ).run_command( ‘…’, args ) inside of on_activated…

The base plugin file would be:




##
## My Auto Build Selection Based on File Paths
##


## 
## Imports
## 

## We need this because of some of the splits...
import os

## We need this because of isinstance sublime.View...
import sublime

## We need this because of sublime_plugin.EventListener - we could do import sublime, sublime_plugin if we wanted to...
import sublime_plugin

##
## Event Listener - This monitors for callbacks - in our case, on_activated is triggered when a tab is clicked so we need to potentially update the build setting by running a command - we'll need to set up some rules somewhere too... we can do it here... a simple __rules__ = { } with path components ( and we can extend it to look for file extensions, or other data )
##
class MyAutoBuildSelectorPluginEventListener( sublime_plugin.EventListener ):
	## 
	## We need to set up some rules... basically components of a path...
	## 
	__rules__ = {
		## If AcecoolCodeMappingSystem is found in the file path, ie _text.find( ... ) > 0 then we can grab the result and perform the change... using a Dict as the = because we can store more data as to what to do...
		## The downside to using this method is it can become costly the more rules we have..
		## "AcecoolCodeMappingSystem": { },

		## We can define a FULL path which would be O( 1 ) to check using _rule = self.__rules__.get( _path, None )... if ( _rule != None ): Perform Actions stored in _rule - this is much quicker but it also requires the full path to be used for EVERY path available for the same exact build data...
		## "C:/Path/To/Files": { },

		## 
		## Instead of putting all of them in one glob, we can add nested tables so self.__rules__.partial_paths, partial_paths_startswith, file_extensions, full_paths, then process them that way so we always know...
		## 
	}


	##
	## Called when a view has taken focus by any means - We aren't using async because this is a quick and easy system - and on async can have multiples running so we'd need to set up a thread locker ( if var == True return False ... otherwise set var to True .. perform actions .. set var to False... end )
	##
	def on_activated( self, _view ):
		## If the view is invalid by not containing a valid file name or window then don't continue..
		if ( _view == None or not isinstance( _view, sublime.View ) or _view.file_name( ) == None or not isinstance( _view.window( ), sublime.Window ) ):
			return False

		## Helpers...

		## The full path... with the filename and extension
		_full_file_name				= _view.file_name( )

		## The filename with extension
		_file_name_only				= _view.file_name( ).split( '\\' )[ - 1 ]

		## The file name without the extension, and the extension by itself
		_base_file_name, _file_ext	= os.path.splitext( os.path.basename( _syntax_path ) )

		## The file path only
		_file_path_only				= _full_file_name[ : len( _full_file_name ) - len( _file_name_only ) ]

		## Grab the views window so we can run commands..
		_window = _view.window( )

		## Now - look at rules to see if part the path is the entire ( _text == ), starting ( _text.startswith ), ending ( _text.endswith ), or middle ( _text.find ) of the string
		## Then, the value can be a Dict, as suggested above so you can do multiple things... OR the result can be a basic string which can be used to call to command to update the build system when a file is selected..



		## These are the commands used in the menu... so all you need to do is use _window.run_command( 'set_build_system', { "file": "" } ) for automatic...
		## { "command": "set_build_system", "args": { "file": "" }, "caption": "Automatic", "checkbox": true },
		## { "caption": "-" },
		## { "command": "set_build_system", "args": {"index": 0}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 1}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 2}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 3}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 4}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 5}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 6}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 7}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 8}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 9}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 10}, "checkbox": true },
		## { "command": "set_build_system", "args": {"index": 11}, "checkbox": true },
		## { "caption": "-" },
		## { "command": "$build_systems" },
		## { "caption": "-" },
		## { "command": "new_build_system", "caption": "New Build System…" }

And, your best bet to let the devs know of a potential bug / issue is to post here: https://github.com/SublimeTextIssues/Core/issues

0 Likes

#15

Thank you very much for the detailed reply!
I’ll take a closer look at your code and I’ll also make sure to report that bug (thanks for that link!) and hopefully get them to fix it.

0 Likes