Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live updating HTML breadcrumbs #4

Open
qbolec opened this issue Aug 19, 2017 · 4 comments
Open

Live updating HTML breadcrumbs #4

qbolec opened this issue Aug 19, 2017 · 4 comments

Comments

@qbolec
Copy link
Owner

qbolec commented Aug 19, 2017

During the very stimulating discussion an idea emerged for a solution which would permanently display the breadcrumbs in a most natural way.

As a developer I am used to a certain way of making myself aware of the current scopes: I use the visual information about indentation (often helped by IDE's vertical guidlines) to find a line above the current one with a particular indentation. This leads to the idea, that perhaps we don't have to do anything for the scopes which are already visible on screen, but could help the developer with the scopes which are opened above the current viewport range.

A simplistic implementation would be to simply bring the important lines closer to the current line, so that they fit into the view - this could be achieved for example by contracting/hiding the non-important lines so that at the top of the window the first few lines would form a digest, of most important lines which would otherwise be above the window.

A more complicated, but perhaps more eye-pleasing idea would be to use something like this:
idea

Some open questions:

  • is it a good idea to remove any non-whitespace characters if the goal is to reuse brain circuitry for finding opened scopes? Wouldn't removing rightmost "{" mislead the user that it is not an opening scope?
  • is it a good idea to use colorful Breadcrumbs instead of the more natural syntax highlighting rules? If syntax highlighting is useful at all, I would expect it should be also useful for breadcrumbs?
  • in some situations when there are a lot of open scopes and the cursor is in a line near the top of the window, we might be unable to fit all breadcrumbs for opened scopes. Should we then scroll the viewport to show them? This might be a bit confusing, as using up arrow to move to previous line could sometimes lead to the screen scrolling in one direction or the other against the user expectation of the "background" staying in place while the cursor moves (is it a real expectation, or expectation of expectation? isn't this already violated by IDE when the cursor reaches the top line and the screen starts to scroll?)
  • performance
@qbolec
Copy link
Owner Author

qbolec commented Aug 21, 2017

A proof of concept implementation of auto-folding:
auto-fold-mode

In the screencast I use up and down arrows to stroll around my code, and the folding/unfolding happens automatically so that all the opened scopes are always visible on screen.

The code is quite simple:

    breadcrumbs.reverse()
    cursor_position = view.sel()[0].b
    cursor_layout = view.text_to_layout(cursor_position)
    viewport_offset = view.viewport_position()
    lines_fit_above = int(round((cursor_layout[1]-viewport_offset[1])/view.line_height()))
    cursor_row = view.rowcol(view.sel()[0].b)[0]
    visible_row = cursor_row - 1

    def row_of_region(region):
      return view.rowcol(region.begin())[0]

    original_top = cursor_row - lines_fit_above
    first_real_line = original_top

    moves = []
    for breadcrumb in breadcrumbs:
      breadcrumb_row = row_of_region(breadcrumb)
      if breadcrumb_row < first_real_line:
        moves.append((breadcrumb_row, first_real_line))
        first_real_line += 1
    lines_to_collapse = []
    total_collapsed = 0
    for (src, dst) in reversed(moves):
      offset = dst - src
      to_collapse = offset - total_collapsed
      first_collapsed = src + 1
      last_collapsed = min(first_collapsed + to_collapse - 1, visible_row - 1)
      if first_collapsed <= last_collapsed:
        lines_to_collapse.append((first_collapsed,last_collapsed))
      total_collapsed += to_collapse

    view.unfold(sublime.Region(0, cursor_position))
    for (start, end) in lines_to_collapse:
      view.fold(sublime.Region(get_row_start(start)-1,get_row_start(end+1)-1))

    if 0 < len(lines_to_collapse):
      desired_top = view.text_to_layout(breadcrumbs[0].begin())[1]
      view.set_viewport_position((viewport_offset[0], desired_top),False)

@Azeirah
Copy link

Azeirah commented Sep 3, 2017

@qbolec Wow, that looks fantastic

@qbolec
Copy link
Owner Author

qbolec commented Sep 3, 2017

Thanks! It lacks a horizontal line separating the "breadcrumbs" from the code, which could be achieved using a Phantom.

I am not sure if this should be developed as evolution of this plugin, or in a separate plugin which does this one thing only (Autofold, Autofolding, Autofolder?)

@Azeirah
Copy link

Azeirah commented Sep 3, 2017

I don't mind either, I'm just trying to extract hierarchical breadcrumbs from Markdown files, your solution looks really cool, this project is really cool.

Phantoms are the way forward though, so my vote goes out to evolution of this plugin, if you have the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants