CodeMap - is a ST3 plugin for showing the code tree representing the code structure of the active view/document
MIT License
41
stars
4
forks
source link
Update code_map.py - Added Logic Fix, Corrected 2 Rubberbanding problems, and removed un-needed lambda function and extra timed function call - with sync_map function named as synch_map #30
Prevent rubberbanding of view being refocused by CodeMap under certain circumstances: by preventing Code - Map Panel from reclaiming focus for the view / file if we're no longer looking at the file / view mapped at the time the go function is called.
Prevent rubberbanding of view being refocused by CodeMap under certain circumstances: by ensuring the same window is still being used - ie if the user switches window in the short delta-time it takes between the sync_map function as synch_map to be called and the go function to be called - prevent the old window from being re-focused when it no longer interested the user...
Fix: Corrected issue where v == None: return wasn't included in go function - as T time has passed, and since we can't trust user input ( and users have control over views ) we need to make sure it wasn't closed to prevent a logical error: v ie None Type doesn't contain sub * function / variable..
Prevent 2 different timeouts from being created when only 1 is needed - we don't need 2 and we don't need a lambda function here.
That should be all...
Note: I could probably change the length of additional logic by simply comparing the VIEW_ID... VIEW_ID should be unique, even between windows ( but it may not - and since I'm not sure whether or not they change or reset between windows, I've opted for the other approach but depending how things go further along it may be something to look into because it'll enable us to remove the file-name comparison and the window check and simply change v == None to v != current_view ... We could actually get rid of the v == None check because if v is None then it'll be different from current_view anyway... so is streamlines the logic quite a bit )...
##
## Updated to include bug fix ( where ( v == None ) wasn't checked when go was called because ΔT has passed and the user could've closed the file. ). Prevented rubberbanding by making sure the same window was used ( so old window isn't refocused ) and make sure the same file is still being looked at ( to make sure the previous file isn't re-opened when the user switched from it - I could simply compare VIEW ID and then I don't need to look at window, etc.. so I may change from that ) - Acecool
##
def synch_map(v, give_back_focus=True):
## Grabs the active view from the active window and reads the filename from it...
## Note: We can do it this way, or use the view passed to the function - but we need to do it the former for the go function because v may have changed... For now we'll use v to grab the current file...
## last_current_file = = sublime.active_window( ).active_view( ).file_name( )
last_current_file = v.file_name( )
last_window = sublime.active_window( )
## Allow go to be called - but cancel it if the file switched...
def go():
## Since T time has passed - we relearn data that may have changed.. This includes looking at variables passed through our scope - v is the VIEW / file we're mapping... v could be None now so if it is, then there's no point in proceeding..
if ( v == None ):
return
## Grab the active window - again T time has passed so we need to relearn data that may have changed...
current_window = sublime.active_window( )
## If the active window has changed, prevent the previous window from refocusing... No need to proceed if the window has changed...
if ( current_window != last_window ):
return
## Set the current file ( after the timeout ) for a comparison.. We don't use v because this is a function called after T time has passed and v will still be the same... We need to grab the active window, the active view within it, and the file-name of that view... If they have changed, we don't resync it..
current_file = current_window.active_view( ).file_name( )
## If the current file isn't what the sync_map function was called with, then we do not allow sync_map to continue otherwise it'll cause rubberbanding back to a file we've lost interest in...
if ( current_file != last_current_file ):
return
map_view = get_code_map_view()
if map_view and map_view.size() > 0:
code_view_line, _ = v.rowcol(v.sel()[0].a)
prev_map_line = None
lines = map_view.lines(Region(0, map_view.size()))
entries = []
index = 0
for line in lines:
link = map_view.substr(line).split(':')[-1]
try:
entries.append((int(link), line))
except:
continue
entries.sort(key=lambda tup: tup[0])
for member_line_num, line in entries:
# added +1 so that it works for the first line of the function
if member_line_num > code_view_line + 1:
break
else:
prev_map_line = line
map_view.sel().clear()
if prev_map_line:
map_view.sel().add(prev_map_line)
map_view.show(prev_map_line.a)
map_view.window().focus_view(map_view)
## Make the give back focus a part of go because it uses timeout anyway...
if give_back_focus:
win().focus_view(v)
# apply a timeout to the whole function, add an additional timeout if it's
# necessary to focus back to the original view - Acecool: But only if we haven't switched to a different file...
sublime.set_timeout(go, 10)
Changelog:
Note: I could probably change the length of additional logic by simply comparing the VIEW_ID... VIEW_ID should be unique, even between windows ( but it may not - and since I'm not sure whether or not they change or reset between windows, I've opted for the other approach but depending how things go further along it may be something to look into because it'll enable us to remove the file-name comparison and the window check and simply change v == None to v != current_view ... We could actually get rid of the v == None check because if v is None then it'll be different from current_view anyway... so is streamlines the logic quite a bit )...