Fix: Improve code folding functionality and gutter rendering
- Updated folding actions and engine for more consistent behavior. - Added helper function `is_fold_hidden()` to check fold visibility state. - Improved gutter renderer to handle collapsible code blocks more reliably. - Refined tag handling for invisible folds to prevent desync issues. - Removed code fold Fix related entry in `TODO.md`.
This commit is contained in:
5
TODO.md
5
TODO.md
@@ -12,7 +12,10 @@ ___
|
|||||||
|
|
||||||
___
|
___
|
||||||
### Fix
|
### Fix
|
||||||
|
- Fix <Ctrl\>z in multi-insert mode being funky. Insure updates happen on block level.
|
||||||
|
I.E, maybe push updates to queue to insure block undo/redo?
|
||||||
|
- Fix multi-insert not acting properly with - in word.
|
||||||
|
I.E leader desync on <Ctrl\>left/right
|
||||||
- Fix on lsp client unload to close files lsp side and unload server endpoint
|
- Fix on lsp client unload to close files lsp side and unload server endpoint
|
||||||
- Fix Collapsable code blocks icon desync on new/old lines or text cut/pasted
|
|
||||||
|
|
||||||
___
|
___
|
||||||
|
|||||||
@@ -20,3 +20,5 @@ def expand_range(view, fold):
|
|||||||
end = buffer.get_iter_at_line(fold["end_line"] + 1)
|
end = buffer.get_iter_at_line(fold["end_line"] + 1)
|
||||||
|
|
||||||
buffer.remove_tag_by_name("invisible", start, end)
|
buffer.remove_tag_by_name("invisible", start, end)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,7 @@ from .fold_types import FOLD_NODES
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_folding_ranges(lang_name: str, ast):
|
def visit_node(fold_types, node, ranges):
|
||||||
root = ast.root_node
|
|
||||||
fold_types = FOLD_NODES.get(lang_name, set())
|
|
||||||
ranges = []
|
|
||||||
|
|
||||||
def visit(node):
|
|
||||||
if node.type in fold_types:
|
if node.type in fold_types:
|
||||||
start_line = node.start_point[0]
|
start_line = node.start_point[0]
|
||||||
end_line = node.end_point[0]
|
end_line = node.end_point[0]
|
||||||
@@ -25,7 +20,13 @@ def get_folding_ranges(lang_name: str, ast):
|
|||||||
})
|
})
|
||||||
|
|
||||||
for child in node.children:
|
for child in node.children:
|
||||||
visit(child)
|
visit_node(fold_types, child, ranges)
|
||||||
|
|
||||||
visit(root)
|
def get_folding_ranges(lang_name: str, ast):
|
||||||
|
root = ast.root_node
|
||||||
|
fold_types = FOLD_NODES.get(lang_name, set())
|
||||||
|
ranges = []
|
||||||
|
|
||||||
|
visit_node(fold_types, root, ranges)
|
||||||
return ranges
|
return ranges
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ from .folding_actions import collapse_range, expand_range
|
|||||||
def handle_collapse(view, fold):
|
def handle_collapse(view, fold):
|
||||||
collapse_range(view, fold)
|
collapse_range(view, fold)
|
||||||
|
|
||||||
for inner in view.fold_starts:
|
|
||||||
if fold["start_line"] < inner["start_line"] <= fold["end_line"]:
|
|
||||||
view.fold_states[inner["id"]] = False
|
|
||||||
|
|
||||||
def handle_expand(view, fold):
|
def handle_expand(view, fold):
|
||||||
expand_range(view, fold)
|
expand_range(view, fold)
|
||||||
|
|
||||||
@@ -29,6 +25,11 @@ def handle_block_toggle(collapsed, view, fold):
|
|||||||
else:
|
else:
|
||||||
handle_expand(view, fold)
|
handle_expand(view, fold)
|
||||||
|
|
||||||
|
def is_fold_hidden(buffer, fold):
|
||||||
|
iter_ = buffer.get_iter_at_line(fold["start_line"] + 1)
|
||||||
|
tags = iter_.get_tags()
|
||||||
|
return any(tag.get_property("invisible") for tag in tags)
|
||||||
|
|
||||||
|
|
||||||
def on_query_data(renderer, start_iter, end_iter, state, view):
|
def on_query_data(renderer, start_iter, end_iter, state, view):
|
||||||
line = start_iter.get_line()
|
line = start_iter.get_line()
|
||||||
@@ -37,10 +38,13 @@ def on_query_data(renderer, start_iter, end_iter, state, view):
|
|||||||
renderer.set_text("", -1)
|
renderer.set_text("", -1)
|
||||||
return
|
return
|
||||||
|
|
||||||
fold = next((f for f in view.fold_starts if f["start_line"] == line), None)
|
fold = next(
|
||||||
collapsed = fold and view.fold_states.get(fold["id"], False)
|
(f for f in view.fold_starts if f["start_line"] == line), None
|
||||||
|
)
|
||||||
|
|
||||||
renderer.set_text( "▶" if collapsed else "▼", -1 )
|
collapsed = fold and is_fold_hidden(view.get_buffer(), fold)
|
||||||
|
|
||||||
|
renderer.set_text("▶" if collapsed else "▼", -1)
|
||||||
|
|
||||||
def on_click(view, event, renderer):
|
def on_click(view, event, renderer):
|
||||||
if not event.button == 1: return False
|
if not event.button == 1: return False
|
||||||
@@ -59,9 +63,7 @@ def on_click(view, event, renderer):
|
|||||||
for fold in view.fold_starts:
|
for fold in view.fold_starts:
|
||||||
if not fold["start_line"] == line: continue
|
if not fold["start_line"] == line: continue
|
||||||
|
|
||||||
collapsed = view.fold_states.get(fold["id"], False)
|
collapsed = is_fold_hidden(view.get_buffer(), fold)
|
||||||
view.fold_states[fold["id"]] = not collapsed
|
|
||||||
|
|
||||||
handle_block_toggle(collapsed, view, fold)
|
handle_block_toggle(collapsed, view, fold)
|
||||||
|
|
||||||
renderer.queue_draw()
|
renderer.queue_draw()
|
||||||
@@ -74,13 +76,8 @@ def setup_gutter(view):
|
|||||||
gutter = view.get_gutter(Gtk.TextWindowType.LEFT)
|
gutter = view.get_gutter(Gtk.TextWindowType.LEFT)
|
||||||
buffer = view.get_buffer()
|
buffer = view.get_buffer()
|
||||||
|
|
||||||
if not buffer.get_tag_table().lookup("invisible"):
|
|
||||||
tag = buffer.create_tag("invisible")
|
|
||||||
tag.set_property("invisible", True)
|
|
||||||
|
|
||||||
view.fold_starts = []
|
view.fold_starts = []
|
||||||
view.fold_start_set = set()
|
view.fold_start_set = set()
|
||||||
view.fold_states = {}
|
|
||||||
|
|
||||||
renderer = GtkSource.GutterRendererText()
|
renderer = GtkSource.GutterRendererText()
|
||||||
renderer.set_size(12)
|
renderer.set_size(12)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from libs.event_factory import Event_Factory, Code_Event_Types
|
|||||||
from plugins.plugin_types import PluginCode
|
from plugins.plugin_types import PluginCode
|
||||||
|
|
||||||
from .fold_types import FOLD_NODES
|
from .fold_types import FOLD_NODES
|
||||||
|
from .folding_actions import collapse_range
|
||||||
from .folding_engine import get_folding_ranges
|
from .folding_engine import get_folding_ranges
|
||||||
from .gutter_renderer import setup_gutter
|
from .gutter_renderer import setup_gutter
|
||||||
|
|
||||||
@@ -34,6 +35,11 @@ class Plugin(PluginCode):
|
|||||||
if file.ftype not in FOLD_NODES: return
|
if file.ftype not in FOLD_NODES: return
|
||||||
if not hasattr(file, "ast"): return
|
if not hasattr(file, "ast"): return
|
||||||
|
|
||||||
|
buffer = file.buffer
|
||||||
|
if not buffer.get_tag_table().lookup("invisible"):
|
||||||
|
tag = buffer.create_tag("invisible")
|
||||||
|
tag.set_property("invisible", True)
|
||||||
|
|
||||||
self.update_gutter(file, self.view)
|
self.update_gutter(file, self.view)
|
||||||
elif isinstance(event, Code_Event_Types.TextChangedEvent):
|
elif isinstance(event, Code_Event_Types.TextChangedEvent):
|
||||||
if event.file.ftype not in FOLD_NODES: return
|
if event.file.ftype not in FOLD_NODES: return
|
||||||
@@ -78,21 +84,7 @@ class Plugin(PluginCode):
|
|||||||
view.fold_update_source = GLib.timeout_add(delay, callback)
|
view.fold_update_source = GLib.timeout_add(delay, callback)
|
||||||
|
|
||||||
def update_gutter(self, file, view):
|
def update_gutter(self, file, view):
|
||||||
old_states = getattr(view, "fold_states", {})
|
|
||||||
|
|
||||||
view.fold_starts = get_folding_ranges(file.ftype, file.ast)
|
view.fold_starts = get_folding_ranges(file.ftype, file.ast)
|
||||||
view.fold_start_set = {
|
view.fold_start_set = {
|
||||||
fold["start_line"] for fold in view.fold_starts
|
fold["start_line"] for fold in view.fold_starts
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = view.get_buffer()
|
|
||||||
if not buffer.get_tag_table().lookup("invisible"):
|
|
||||||
tag = buffer.create_tag("invisible")
|
|
||||||
tag.set_property("invisible", True)
|
|
||||||
|
|
||||||
new_states = {}
|
|
||||||
for fold in view.fold_starts:
|
|
||||||
if not fold["id"] in old_states: continue
|
|
||||||
new_states[fold["id"]] = old_states[fold["id"]]
|
|
||||||
|
|
||||||
view.fold_states = new_states
|
|
||||||
|
|||||||
Reference in New Issue
Block a user