Skip to content

Latest commit

 

History

History
453 lines (325 loc) · 20.1 KB

notes.org

File metadata and controls

453 lines (325 loc) · 20.1 KB

org-sidebar notes

Tasks

UNDERWAY [#A] Bookmark support

  • State “UNDERWAY” from “TODO” [2020-11-02 Mon 20:56]

Bookmark query sidebars

  • State “DONE” from “UNDERWAY” [2020-11-02 Mon 22:17]
  • State “UNDERWAY” from “TODO” [2020-11-02 Mon 20:56]

[2020-11-02 Mon 20:52] I just added some bookmark support to org-ql-view in the wip/bookmarks branch, but then I realized that in (defun org-sidebar …), source-buffer is set to the current buffer, not its filename, so the variable org-ql-view-buffers-files is set to the buffer, not its filename, so that variable in the bookmark gets set to the buffer, not the filename, which makes the bookmark fail to restore properly. So the buffer’s filename needs to be used instead of the buffer itself.

However:

  1. In the (probably very rare) case of using the sidebar on a non-file-backed buffer, it won’t restore properly. But I think that’s not a big deal, because non-file-backed buffers can’t be restored by bookmarks anyway if they don’t exist anymore.
  2. In the case of a file-backed, narrowed buffer (and probably also in the case of an indirect buffer backed by a file-backed buffer), the narrowing and indirectness might need to be handled specially. But I’m not sure if that’s practical, because saving and restoring narrowing would also require, e.g. saving the outline path and finding it again, which isn’t perfect (e.g. when a heading contains a link, it breaks, cf. Burly #10).

So in org-sidebar I need to:

  • [-] Change the source-buffer to source-file, or something like that.

[2020-11-02 Mon 22:13] I changed org-ql-view--bookmark-make-record so it replaces buffers with their filenames. And I changed org-sidebar to set mode-line-format as a window parameter instead of a buffer-local variable. And I changed Burly to save and restore that window parameter. So this all seems to work now. Making changes across 3 packages to do this is relatively easy when they’re all my own packages, but it involves a lot of jumping around.

I think that making the tree sidebar bookmarkable will be easier…I think

Bookmark tree sidebar

[#A] Document keymap

[#A] Way to refresh only one sidebar buffer

The current refresh command refreshes all sidebar buffers (or, at least, all of the ones that were launched by the same invocation). Sometimes that is what’s wanted, e.g. with the default sidebar, which is two buffers showing results from one buffer). But it works by deleting all org-sidebar windows first, which messes with window layout, which is especially a problem when only displaying one sidebar window in a sidebar containing other windows not made by org-sidebar.

So it would be good to be able to update just one sidebar window/buffer. The hard part is going to be doing so in a flexible, smart way. Maybe it would be simple enough to just do the single-buffer, no-window-delete refresh when the buffer being refreshed was originally made in a command that displayed a single sidebar window. That will require modifying several functions, but it shouldn’t be too hard.

[#B] Optionally don’t show empty sidebars

e.g. when the upcoming-items sidebar has no items.

[#B] Automatically cleanup old sidebar buffers

e.g. when an Org buffer is closed, any of its sidebar buffers shouldn’t be left open.

[#B] Automatically update sidebars in buffers’ after-save-hook

  • [ ] Add to hook in parent Org buffers when sidebar is opened
  • [ ] Remove from hook when sidebar killed

[#B] Improve fontification of tasks

e.g. emphasis like code isn’t applied, so the raw syntax is visible.

[#B] Set sidebar windows as dedicated

[#B] Use document title in tree sidebar header

[#C] Made sidebars more customizable

Customizable org-ql queries

Customizable window/buffer layout

[#C] Add note about binding mouse-2 in regular Org buffers

It’s a bit confusing that mouse-2 toggles outline visibility in the tree buffer, but then in the regular Org buffer, by default, it yanks/pastes. It would be helpful to rebind it in Org buffers. Of course, users will have to make that decision themselves, but I should note it in the documentation with an example.

Ideas

org-sidebar-tree: arguments for outline path and ID

It would be useful to be able to call org-sidebar-tree with an olp or id argument to show the tree for the tree at a location. It would make it easy to treat trees as projects and quickly access them with the sidebar, rather than having to navigate to the tree first, open it in an indirect buffer, and then open the tree.

Persistent list of nodes/searches

I’d like to be able to add certain nodes of interest (sometimes with child nodes) to a sidebar. It would also be nice to be able to add “views” or agenda searches for tags, etc (inspired by this screenshot).

[2018-08-02 Thu 10:55] Thinking through this a bit more, here’s how I think it could work:

defvar org-sidebar-persistent-items
A list of formatted strings for displaying in a sidebar window.
defun org-sidebar-add-item (&optional position)
Add item at position to persistent items. position defaults to point. Calls org-sidebar-show-persistent after adding item to list.
defcustom org-sidebar-persistent-slot
Side window slot for persistent items window.
defun org-sidebar-show-persistent
Show persistent items sidebar window. Places it in slot defined by org-sidebar-persistent-slot.
defun org-sidebar--update-persistent
Update persistent items buffer. Erases the buffer and inserts items from org-sidebar-persistent-items.
defun org-sidebar-persistent-remove
Remove item at point from persistent items buffer.

Sort hierarchically

Use a list of sorting functions, apply recursively, like in magit-todos.

[2020-10-31 Sat 18:57] This should be covered by using magit-section in org-ql-view.

MAYBE Automatically size windows

e.g. when there are only a few lines in one buffer but many in another, it doesn’t make sense for them to be equally sized.

MAYBE Automatically switch sidebar buffers when Org buffer changes

e.g. in the current window layout, if the Org buffer displayed in the main window is changed, maybe (optionally) the sidebar buffers should change, too.

MAYBE Automatically update sidebar buffers

For small Org buffers, it should be no problem, and might even work on a timer or a hook. For larger ones, it becomes expensive, and will probably have to be done manually.

It would probably make sense, at least, to update it on the after-save-hook…

MAYBE Combine org-now and org-sidebar?

  • State “MAYBE” from “TODO” [2019-09-08 Sun 15:33]

Seems like org-now should be rolled into org-sidebar as one of the panes that can be displayed.

MAYBE Customizeable grouping

Especially for tasks. It would be good to have a generalized implementation for grouping, printing items beneath headers, etc.

MAYBE More commands for sidebar buffers

e.g. changing TODO keyword, etc. It would be good to reuse as much Org Agenda functionality as possible, but since they aren’t actual agenda buffers (and since I think Org only allows one actual Agenda buffer), that may not be possible.

MAYBE [#A] Use font-locking to hide non-heading text in tree buffer

Suggested by itistheblurstoftimes here:

What about using font lock on the tree buffer? This is buggy, but seems promising. I have no idea if I am using font-lock properly, but regardless using overlays in the tree buffer seems the best way to change its appearance since they are not shared.

(setq org-sidebar-tree–hide-body-keyword `((“\(^[^*]+\)\n” (0 (progn (ov (match-beginning 1) (match-end 1) ‘(invisible t)) nil))))) (font-lock-add-keywords nil org-sidebar-tree–hide-body-keyword)

[2020-12-03 Thu 15:14] He posted a new package which seems to attempt to solve this problem. Looks like he might have done it!

[#A] Use org-ql-agenda

  • State “DONE” from “TODO” [2020-03-11 Wed 15:59]

Rather than formatting and making buffers in this package, org-ql-agenda does that. All we need to do is direct its output to buffers that we then display in sidebars. This will entail another refactoring.

[2020-03-11 Wed 15:59] Done using org-ql-view buffers.

Add outline-overview sidebar

  • State “DONE” from “MAYBE” [2019-10-02 Wed 05:59]
    org-sidebar-tree!

e.g. like what I have in my config, aka a minimap

Emacs 26 side windows

  • State “DONE” from “MAYBE” [2018-08-02 Thu 11:03]

e.g. as mentioned here. Also from the changelog:

Support for side windows is now official. The display action function ‘display-buffer-in-side-window’ will display its buffer in a side window. Functions for toggling all side windows on a frame, changing and reversing the layout of side windows and returning the main (major non-side) window of a frame are provided. For details consult the section “(elisp) Side Windows” in the ELisp manual.

Support for atomic windows - rectangular compositions of windows treated by ‘split-window’, ‘delete-window’ and ‘delete-other-windows’ like a single live window - is now official. For details consult the section “(elisp) Atomic Windows” in the ELisp manual.

Toggle for sidebar

  • State “DONE” from “MAYBE” [2020-10-31 Sat 18:48]
    That was done a long time ago.
  • State “MAYBE” from [2019-10-07 Mon 13:19]

As mentioned here.

Use library for window management

  • State “DONE” from “MAYBE” [2018-08-01 Wed 10:11]

display-buffer-in-side-window

I did not know about this before. It might be the right tool for the job…

GNU Emacs Lisp Reference Manual: Side Windows

[2018-08-01 Wed 10:10] Yep, this works very well! Going to consider this idea done unless we need more powerful window management in the future.

Libraries

splitter

splitter.el looks like it may be useful, especially the functions spl-grid and spl-split.

tile.el

This also looks like it might be useful, but I don’t see any examples, and it doesn’t seem obvious how to use it, so some experimentation would be required.

wconf

This might also be useful. From its readme:

* Concepts
The main idea is +stolen from+ inspired by =workgroups=.  We keep a list
of configuration pairs.  Each such pair consists of an /active/
configuration (what you see when you switch to this slot of the list),
and a /stored/ one (what you have in the back, and maybe save to disk at
some point).  In =workgroups= parlance, these are the working and base
configs.

At each point in time there is (at most) one configuration current.  You
can explictly store and restore the current active configuration to/from
the stored one, or do likewise for all configurations.  For example, you
might decide that you have a carefully hand-crafted set of
configurations that you always want to start from, but that you do not
wish to change this setup, except when doing so explicitly.  That's
easy: just remove the =(wconf-store-all)= call from the above hook
function.

A nice feature of =wconf= is that it does not alter any hooks or
settings outside its own small world, and I intend to keep it that way.
This implies that the currently active configuration is only updated
explicitly, via one the functions/commands in the package.
* Rationale, and Other Packages
I used https://github.com/tlh/workgroups.el for several years.  It is a
great package, which offers a lot of additional features besides the
core business of managing window configs.  It also has some
shortcomings, is somewhat complex (at 79k), and I occasionally
experienced minor glitches.  Most importantly, it has been unmaintained
for roughly 4 years now.

https://github.com/pashinin/workgroups2 promises to pick up where
workgroups left, and is actively maintained.  The main difference, as I
understand it, is the desire to restore "special" buffers as well (help,
info, org-mode agendas, notmuch mail, you name it).  Finally trying it,
it did not provide a lot of benefit for my personal needs, but added
still more complexity.  The functionality that I want should not require
179k of elisp.

Nowadays (at least since the GNU Emacs 24.4 release), there are proper
lisp-reader (de)serializations for both frame and window configurations,
and =window.el= and =frameset.el= provide functions to deal with them
(relatively) comfortably.  Desktop already (re)stores a single
configuration.  That's when I decided that it's time to roll my own:
build something light on top of what's already there, in order to
provide persistent switchable configurations.

window-layout

This looks like it might do what I need, as it has “recipes”:

Split a frame or window into some windows according to a layout
recipe.

Example code

Layout function
-> three pane layout.
(setq wm ; <-- window management object
      (wlf:layout
       '(| (:left-size-ratio 0.3)
           folder
           (- (:upper-max-size 15)
              summary
              message))
       '((:name folder
          :buffer "folder buffer")
         (:name summary
          :buffer "summary buffer")
         (:name message
          :buffer "message buffer")
        )))

Window controlling
(wlf:show    wm 'summary)
(wlf:hide    wm 'summary)
(wlf:toggle  wm 'summary)
(wlf:select  wm 'summary)
(wlf:toggle-maximize  wm 'summary)

Window updating
(wlf:refresh wm)
(wlf:reset-window-sizes wm)
(wlf:reset-init wm)

Accessing a buffer
(wlf:get-buffer wm 'summary) -> <#buffer object>
(wlf:set-buffer wm 'summary "*scratch*")

Accessing a window
(wlf:get-window wm 'summary)

Layout hook
(defun wlf:test-hook (wset) (message "HOOK : %s" wset))
(wlf:layout-hook-add wm 'wlf:test-hook)
(wlf:layout-hook-remove wm 'wlf:test-hook)

`wlf:layout' function

* Layout recipe:

( (split type) (split option)
               (left window name or recipe)
               (right window name or recipe) )

  - : split vertically
  | : split horizontally

split option (the prefix 'left' can be replaced by 'right', 'upper' and 'lower'.)
  :left-size  (column or row number) window size
  :left-max-size  (column or row number) if window size is larger than this value, the window is shrunken.
  :left-size-ratio  (0.0 - 1.0) window size ratio. the size of the other side is the rest.

Note:
The split option can be omitted.
The size parameters, :size, :max-size and :size-ratio, are mutually
exclusive.  The size of a window is related with one of the other
side window. So, if both side windows set size parameters, the
window size may not be adjusted as you write.

* Window options:

  :name  [*] the window name.
  :buffer  a buffer name or a buffer object to show the window. If nil or omitted, the current buffer remains. If symbol, it is evaluated as a global variable.
  :default-hide  (t/nil) if t, the window is hided initially. (default: nil)
  :fix-size  (t/nil) if t, when the windows are laid out again, the window size is remained. (default: nil)

* subwindow-p option:

If this option is not nil, this function splits the windows within
the current window. If this option is nil or omitted, this function
uses the entire space of the current frame. Because some user
actions and complicated window layouts may cause unexpected split
behaviors, it is easy to use the entire space of a frame.

* Return value (Window management object):

You should not access the management object directly, because it is not
intended direct access.
You can make some management objects to switch the window layout.

* Layout hook

After splitting windows, registered hook are called with one
argument, the window management object.

window-purpose

This looks like it might be useful too:

---------------------------------------------------------------------
Full information can be found on GitHub:
https://github.com/bmag/emacs-purpose/wiki
---------------------------------------------------------------------

Purpose is a package that introduces the concept of a "purpose" for
windows and buffers, and then helps you maintain a robust window
layout easily.

Installation and Setup:
Install Purpose from MELPA, or download it manually from GitHub. If
you download manually, add these lines to your init file:
   (add-to-list 'load-path "/path/to/purpose")
   (require 'window-purpose)
To activate Purpose at start-up, add this line to your init file:
   (purpose-mode)

Purpose Configuration:
Customize `purpose-user-mode-purposes', `purpose-user-name-purposes',
`purpose-user-regexp-purposes' and
`purpose-use-default-configuration'.

Basic Usage:
1. Load/Save window/frame layout (see `purpose-load-window-layout',
   `purpose-save-window-layout', etc.)
2. Use regular switch-buffer functions - they will not mess your
   window layout (Purpose overrides them).
3. If you don't want a window's purpose/buffer to change, dedicate
   the window:
   C-c , d: `purpose-toggle-window-purpose-dedicated'
   C-c , D: `purpose-toggle-window-buffer-dedicated'
4. To use a switch-buffer function that ignores Purpose, prefix it
   with C-u. For example, [C-u C-x b] calls
   `switch-buffer-without-purpose'.

Notes

[2019-10-01 Tue 04:50:38] org-sidebar-tree demo

Setup:

  1. With indirect buffer opened to test data heading
  2. Set org-sticky-header-full-path to ‘reversed
  3. Remove blank lines between entries to avoid them appearing in the tree buffer when headings are moved.
  4. Collapse drawers in source buffer.

Demo:

  1. M-x org-sidebar-tree
  2. Toggle some headings with mouse-2.
  3. Jump to some headings in indirect buffer with mouse-1.
  4. Jump to headings with children by dragging mouse-1.
  5. Change to-do keywords with S-<left>/<right>
  6. Change priority with S-<up>/<down>
  7. Move headings around with M-<up>/<down>
    1. (do not move headings up past their original location, may cause visual bug)
    2. Do not move headings with expanded children, as it causes the entry content to be displayed in the tree buffer.

Code

Testing

(org-super-agenda--test-with-org-today-date "2017-07-08 00:00"
  (org-sidebar))
(org-super-agenda--test-with-org-today-date "2017-07-08 00:00"
  (org-sidebar-ql '(and (todo "TODO") (priority > "C"))
                  "/home/me/src/emacs/org-super-agenda/test/test.org"
                  nil :priority 'date))