def rows_to_region(rows): """ Convert rows (line numbers) to a region (selection/cursor position). Keyword arguments: - rows -- Row number(s) to convert to region(s). """ # Get current active view view = sublime.active_window().active_view() # Unable to convert rows to regions when no view available if view is None: return # List for containing regions to return region = [] # Create list if it is a singleton if not isinstance(rows, list): rows = [rows] for row in rows: # Check if row is a digit if isinstance(row, int) or H.is_digit(row): # Convert from 1 based to a 0 based row (line) number row_number = int(row) - 1 # Calculate offset point for row offset_point = view.text_point(row_number, 0) # Get region for row by offset point region_row = view.line(offset_point) # Add to list for result region.append(region_row) return region
def generate_context_output(context, indent=0): """ Generate readable context from dictionary with context data. Keyword arguments: context -- Dictionary with context data. indent -- Indent level. """ # Generate output text for values values = H.unicode_string('') if not isinstance(context, dict): return values for variable in context.values(): has_children = False property_text = '' # Set indentation for i in range(indent): property_text += '\t' # Property with value if variable['value'] is not None: if variable['name']: property_text += '{name} = ' property_text += '({type}) {value}\n' # Property with children elif isinstance(variable['children'], dict) and variable['numchildren'] is not None: has_children = True if variable['name']: property_text += '{name} = ' property_text += '{type}[{numchildren}]\n' # Unknown property else: if variable['name']: property_text += '{name} = ' property_text += '<{type}>\n' # Remove newlines in value to prevent incorrect indentation value = '' if variable['value'] and len(variable['value']) > 0: value = variable['value'].replace("\r\n", "\n").replace("\n", " ") # Format string and append to output values += H.unicode_string(property_text \ .format(value=value, type=variable['type'], name=variable['name'], numchildren=variable['numchildren'])) # Append property children to output if has_children: # Get children for property (no need to convert, already unicode) values += generate_context_output(variable['children'], indent+1) # Use ellipsis to indicate that results have been truncated limited = False if isinstance(variable['numchildren'], int) or H.is_digit(variable['numchildren']): if int(variable['numchildren']) != len(variable['children']): limited = True elif len(variable['children']) > 0 and not variable['numchildren']: limited = True if limited: for i in range(indent+1): values += H.unicode_string('\t') values += H.unicode_string('...\n') return values
def generate_breakpoint_output(): """ Generate output with all configured breakpoints. """ # Get breakpoints for files values = H.unicode_string('') if S.BREAKPOINT is None: return values for filename, breakpoint_data in sorted(S.BREAKPOINT.items()): breakpoint_entry = '' if breakpoint_data: breakpoint_entry += '=> %s\n' % filename # Sort breakpoint data by line number for lineno, bp in sorted( breakpoint_data.items(), key=lambda item: (int(item[0]) if isinstance(item[0], int) or H.is_digit(item[ 0]) else float('inf'), item[0])): # Do not show temporary breakpoint if S.BREAKPOINT_RUN is not None and S.BREAKPOINT_RUN[ 'filename'] == filename and S.BREAKPOINT_RUN[ 'lineno'] == lineno: continue # Whether breakpoint is enabled or disabled breakpoint_entry += '\t' if bp['enabled']: breakpoint_entry += '|+|' else: breakpoint_entry += '|-|' # Line number breakpoint_entry += ' %s' % lineno # Conditional expression if bp['expression'] is not None: breakpoint_entry += ' -- "%s"' % bp['expression'] breakpoint_entry += '\n' values += H.unicode_string(breakpoint_entry) return values
def generate_breakpoint_output(): """ Generate output with all configured breakpoints. """ # Get breakpoints for files values = H.unicode_string('') if S.BREAKPOINT is None: return values for filename, breakpoint_data in sorted(S.BREAKPOINT.items()): breakpoint_entry = '' if breakpoint_data: breakpoint_entry += "=> %s\n" % filename # Sort breakpoint data by line number for lineno, bp in sorted(breakpoint_data.items(), key=lambda item: (int(item[0]) if isinstance(item[0], int) or H.is_digit(item[0]) else float('inf'), item[0])): # Do not show temporary breakpoint if S.BREAKPOINT_RUN is not None and S.BREAKPOINT_RUN['filename'] == filename and S.BREAKPOINT_RUN['lineno'] == lineno: continue # Whether breakpoint is enabled or disabled breakpoint_entry += '\t' if bp['enabled']: breakpoint_entry += '|+|' else: breakpoint_entry += '|-|' # Line number breakpoint_entry += ' %s' % lineno # Conditional expression if bp['expression'] is not None: breakpoint_entry += ' -- "%s"' % bp['expression'] breakpoint_entry += "\n" values += H.unicode_string(breakpoint_entry) return values
def init(self): if not is_connected(): return # Connection initialization init = S.SESSION.read() # More detailed internal information on properties S.SESSION.send(dbgp.FEATURE_SET, n='show_hidden', v=1) S.SESSION.read() # Set max children limit max_children = get_value(S.KEY_MAX_CHILDREN) if max_children is not False and max_children is not True and ( H.is_number(max_children) or H.is_digit(max_children)): S.SESSION.send(dbgp.FEATURE_SET, n=dbgp.FEATURE_NAME_MAX_CHILDREN, v=max_children) S.SESSION.read() # Set max data limit max_data = get_value(S.KEY_MAX_DATA) if max_data is not False and max_data is not True and ( H.is_number(max_data) or H.is_digit(max_data)): S.SESSION.send(dbgp.FEATURE_SET, n=dbgp.FEATURE_NAME_MAX_DATA, v=max_data) S.SESSION.read() # Set max depth limit max_depth = get_value(S.KEY_MAX_DEPTH) if max_depth is not False and max_depth is not True and ( H.is_number(max_depth) or H.is_digit(max_depth)): S.SESSION.send(dbgp.FEATURE_SET, n=dbgp.FEATURE_NAME_MAX_DEPTH, v=max_depth) S.SESSION.read() # Set breakpoints for files for filename, breakpoint_data in S.BREAKPOINT.items(): if breakpoint_data: for lineno, bp in breakpoint_data.items(): if bp['enabled']: self.set_breakpoint(filename, lineno, bp['expression']) debug('breakpoint_set: ' + filename + ':' + lineno) # Set breakpoints for exceptions break_on_exception = get_value(S.KEY_BREAK_ON_EXCEPTION) if isinstance(break_on_exception, list): for exception_name in break_on_exception: self.set_exception(exception_name) # Determine if client should break at first line on connect if get_value(S.KEY_BREAK_ON_START): # Get init attribute values fileuri = init.get(dbgp.INIT_FILEURI) filename = get_real_path(fileuri) # Show debug/status output self.status_message('Xdebug: Break on start') info('Break on start: ' + filename) # Store line number of breakpoint for displaying region marker S.BREAKPOINT_ROW = {'filename': filename, 'lineno': 1} # Focus/Open file window view self.timeout(lambda: show_file(filename, 1)) # Context variables context = self.get_context_values() self.timeout(lambda: show_content(DATA_CONTEXT, context)) # Stack history stack = self.get_stack_values() if not stack: stack = H.unicode_string( '[{level}] {filename}.{where}:{lineno}\n'.format( level=0, where='{main}', lineno=1, filename=fileuri)) self.timeout(lambda: show_content(DATA_STACK, stack)) # Watch expressions self.watch_expression() else: # Tell script to run it's process self.run_command('xdebug_execute', {'command': 'run'})
def init(self): if not is_connected(): return # Connection initialization init = S.SESSION.read() # More detailed internal information on properties S.SESSION.send(dbgp.FEATURE_SET, n='show_hidden', v=1) S.SESSION.read() # Set max children limit max_children = get_value(S.KEY_MAX_CHILDREN) if max_children is not False and max_children is not True and (H.is_number(max_children) or H.is_digit(max_children)): S.SESSION.send(dbgp.FEATURE_SET, n=dbgp.FEATURE_NAME_MAX_CHILDREN, v=max_children) S.SESSION.read() # Set max data limit max_data = get_value(S.KEY_MAX_DATA) if max_data is not False and max_data is not True and (H.is_number(max_data) or H.is_digit(max_data)): S.SESSION.send(dbgp.FEATURE_SET, n=dbgp.FEATURE_NAME_MAX_DATA, v=max_data) S.SESSION.read() # Set max depth limit max_depth = get_value(S.KEY_MAX_DEPTH) if max_depth is not False and max_depth is not True and (H.is_number(max_depth) or H.is_digit(max_depth)): S.SESSION.send(dbgp.FEATURE_SET, n=dbgp.FEATURE_NAME_MAX_DEPTH, v=max_depth) S.SESSION.read() # Set breakpoints for files for filename, breakpoint_data in S.BREAKPOINT.items(): if breakpoint_data: for lineno, bp in breakpoint_data.items(): if bp['enabled']: self.set_breakpoint(filename, lineno, bp['expression']) debug('breakpoint_set: ' + filename + ':' + lineno) # Set breakpoints for exceptions break_on_exception = get_value(S.KEY_BREAK_ON_EXCEPTION) if isinstance(break_on_exception, list): for exception_name in break_on_exception: self.set_exception(exception_name) # Determine if client should break at first line on connect if get_value(S.KEY_BREAK_ON_START): # Get init attribute values fileuri = init.get(dbgp.INIT_FILEURI) filename = get_real_path(fileuri) # Show debug/status output self.status_message('Xdebug: Break on start') info('Break on start: ' + filename) # Store line number of breakpoint for displaying region marker S.BREAKPOINT_ROW = {'filename': filename, 'lineno': 1} # Focus/Open file window view self.timeout(lambda: show_file(filename, 1)) # Context variables context = self.get_context_values() self.timeout(lambda: show_content(DATA_CONTEXT, context)) # Stack history stack = self.get_stack_values() if not stack: stack = H.unicode_string('[{level}] {filename}.{where}:{lineno}\n' .format(level=0, where='{main}', lineno=1, filename=fileuri)) self.timeout(lambda: show_content(DATA_STACK, stack)) # Watch expressions self.watch_expression() else: # Tell script to run it's process self.run_command('xdebug_execute', {'command': 'run'})
def generate_context_output(context, indent=0, values_only=False, multiline=True): """ Generate readable context from dictionary with context data. Keyword arguments: context -- Dictionary with context data. indent -- Indent level. """ # Generate output text for values values = H.unicode_string('') if not isinstance(context, dict): return values # make sure keys are displayed in correct order keys = [int(key) for key in context.keys()] keys.sort() sorted_keys = keys for key in sorted_keys: variable = context[key] is_last_element = (key == sorted_keys[-1]) has_children = False property_text = '' # Set indentation for i in range(indent): property_text += '\t' # Property with children if 'children' in variable and isinstance( variable['children'], dict) and variable['numchildren'] is not None: has_children = True if variable['name']: property_text += '{name} = ' property_text += '{type}[{numchildren}]' # Property with value elif variable['value'] is not None: name = variable['name'] if name == '<error>': property_text += '<error> ' elif name and not values_only: property_text += '{name} = ' #property_text += '({type}) {value}\n' property_text += '{value}' # Unknown property else: if variable['name']: property_text += '{name} = ' property_text += '<{type}>' # Remove newlines in value to prevent incorrect indentation value = '' if variable['value'] and len(variable['value']) > 0: value = variable['value'].replace("\r\n", "\n").replace("\n", " ") if multiline or has_children: property_text += '\n' else: if not is_last_element: property_text += ', ' # Format string and append to output values += H.unicode_string(property_text \ .format(value=value, type=variable['type'], name=variable['name'], numchildren=variable.get('numchildren', 0))) # Append property children to output if has_children: # Get children for property (no need to convert, already unicode) values += generate_context_output(variable['children'], indent + 1) # Use ellipsis to indicate that results have been truncated limited = False if isinstance(variable['numchildren'], int) or H.is_digit( variable['numchildren']): if int(variable['numchildren']) != len(variable['children']): limited = True elif len(variable['children']) > 0 and not variable['numchildren']: limited = True if limited: for i in range(indent + 1): values += H.unicode_string('\t') values += H.unicode_string('...\n') return values