Skip to content

Latest commit

 

History

History
440 lines (368 loc) · 15.8 KB

TODOs.org

File metadata and controls

440 lines (368 loc) · 15.8 KB

overview, design

because parsing the text file is tedious store in elisp format and have a special mode to read it and show it in a buffer.

persistent file is project based or global

must have something like project based management mechanism to share

such as tide.

when a buffer with icl mode on started up it will locate its project root which resolves to global or project root. The project root is now a unique key to indentify the comment store

there is a global comment store which is a map of project root -> project comment store

project comment store:

  • comments: (file (line . comment)…)
  • count: number of active buffers reading this store, when is is down to zero comments will be set to nil
  • hook: this hook runs on store changed

use case:

in project A, buffer a starts up and gets its project unique key as A, From the global comment stores it gets it project comment store. It is nil and the count is now set to 0. With the count value it knows that it is the first one to access this store. It updates the count to one and initializes comments value for project. Then it reads the comments from the store and show the comments in buffers.

Next a buffer b in project A starts up, and follows the same procedure but the count is already greater than 0 so it means the project comment store is already set up to go. So buffer b will just use the store and increase the count.

Some time later buffer b closes, it will decrease the count. It check the count is still greater than 0

And finally buffer a is about to close. After decreasing the count to 0, that means it is the last consumer of the store so it set the comment variable to nil. Persist the data to a .ilc file

No memory leak this way.

how buffer updates data

occur mode add marker info to text

(get-text-property (point) ‘occur-target)

use propertize to make string

test setup

cask install cask exec ert-runner

data stucture for project

hash table project: file -> comments { line: comment }

((#<overlay from 8503 to 8503 in ipa.el> .
            #("need to forward-char here" 0 25
              (fontified nil)))
 (#<overlay from 22765 to 22765 in ipa.el> .
            #("use project
multiple line really" 0 11
(fontified nil)
12 32
(fontified nil)))
 (#<overlay from 23192 to 23192 in ipa.el> .
            #("take care of project option" 0 27
              (fontified nil))))

https://github.com/sigma/pcache

virtual-comment-store: singleton

default: virtual-comment-project

projects: {project-id: virtual-comment-project}

  • project-id: md5

virtual-comment-project

count: Number
files: {filename: virtual-comment-buffer-data}
virtual-comment-buffer-data
filenamecomments: [virtual-comment-unit]virtual-comment-unitpointcommenttarget

uml

@startjson
{
   "virtual-comment-store" : {
      "default" : {},
      "projects" : {
         "project-id" : {
            "count" : "Number",
            "files" : {
               "file-id" : {
                  "comments" : [
                     {
                        "comment" : "String",
                        "point" : "Number",
                        "target" : "String"
                     },
                     {
                        "comment" : "String",
                        "point" : "Number",
                        "target" : "String"
                     }
                  ],
                  "file-name" : "String"
               },
               "file-id-2" : []
            }
         },
         "project-id-2" : {}
      }
   }
}
@endjson

overlay structure

(overlay-put (make-overlay (point) (point) (current-buffer)) ‘before-string “crap”)

(overlay-put (make-overlay (point) (point) (current-buffer)) ‘before-string “crap”)

problem with overlay moving

if only data structure is kept i.e line number and string then when overlay is moved because of buffer change then we lose track of overlay

overlay should stick to the line it belongs to, eg symbol-overlay

in buffer

we don’t manage the ov list anymore sorting it keep it in order is a headache just grab all the overlays in the buffer which has the tag then this is it.

https://www.gnu.org/software/emacs/manual/html_node/elisp/Finding-Overlays.html

for next and previous next-overlay-change pos previous-overlay-change pos

CANCELED merge comments when the lines they are on are joined into one line

next and previous comment

indentation comment

how to extract and make/separate comment from indentation the real string stored in ‘virtual-comment tag ‘before-string is to store the presentational text

handle comment when its line moves is a big headache

there is a hook but it won’t get triggered on some occasions so we won’t handle it. instead we provide functions to repair, copy and paste comment

yank, paste

data layer

function that grabs all the current overlays in buffer

function that takes overlays list and produces comment data structure

read-from-string is a built-in function in ‘C source code’.

(read-from-string STRING &optional START END)

Read one Lisp expression which is represented as text by STRING. Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX). FINAL-STRING-INDEX is an integer giving the position of the next remaining character in STRING. START and END optionally delimit a substring of STRING from which to read; they default to 0 and (length STRING) respectively. Negative values are counted from the end of STRING.

dump dat to file and load

it’s a experiment

repair should take into account of indentation beside point-at-bol

unused sorting

(defun virtual-comment-buffer-overlays--add (ov my-list)
  "MY-LIST has at least one element and its head is smaller than OV."
  (let ((start (overlay-start ov))
        (head (car my-list))
        (tail (cdr my-list)))
    (if (or (not tail)
            (<= start (overlay-start (car tail))))
        (setcdr my-list (cons ov tail))
      (virtual-comment-buffer-overlays--add ov tail))))

(defun virtual-comment-buffer-overlays-add (ov)
  "Add OV to `virtual-comment-buffer-overlays' in order."
  (if (or (not virtual-comment-buffer-overlays)
          (< (overlay-start ov) (overlay-start (car virtual-comment-buffer-overlays))))
      (push ov virtual-comment-buffer-overlays)
    (virtual-comment-buffer-overlays--add ov virtual-comment-buffer-overlays)))

a timer to update buffer data when idle

tbd run-with-idle-timer https://www.gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html

virtual-comment–update-async functions that needs to call this yank make paste realign should we make it as a hook

clear all on mode disabled

mode to show commnents in buffer and projects

  • show list of commnents of current buffer
  • show list of files with comments of projects
  • jump to place

based on outline mode or occur mode how about org mode, outline mode lacks some commands

org mode is the best but unable to bind RET key when evil is on so use outline mode instead

how to open buffer with file path and point

from helm-ag it’s find-file

keymap action on line

http://ergoemacs.org/emacs/elisp_text_properties.html

handle overlays when their point is out of range

sort buffer data

BUG file-name is nil and put in into project

how come? was that because of async? probably the async get runs on and buffers that it doesn’t belong to

hook on save should only run when there is a time scheduled

timer flag can tell if the update should do or not

some persistent and store access should only work when mode is on

delete make paste align

quit-window command for show

make a show mode so its keybindings can be reset by evil local-set-key applies everywhere to major mode anywhere, not recommended it applies to outline mode, it will apply to org mode because org mode is based on outline mode.

enable

(add-hook 'find-file-hook 'virtual-comment-mode)
(add-hook 'virtual-comment-show-mode 'outline-minor-mode)

(evilified-state-evilify virtual-comment-show-mode virtual-comment-show-mode-map
  "q" quit-window)

(spacemacs/declare-prefix "cv" "virtual-comments")
(spacemacs/set-leader-keys
  "cvv" #'virtual-comment-make
  "cvd" #'virtual-comment-delete
  "cvs" #'virtual-comment-show
  "cvj" #'virtual-comment-next
  "cvn" #'virtual-comment-next
  "cvN" #'virtual-comment-previous
  "cvk" #'virtual-comment-previous
  "cvp" #'virtual-comment-paste
  "cvr" #'virtual-comment-realign)

comments won’t get saved when emacs closed or restarted

unconfirmed

comments scattered away or lost when buffer changed not by user’s input but by revert-buffer

revert-buffer does it work like we open the file again? it is seems to be the case

revert-buffer default option will reload all mode but auto-revert-buffer won’t. it keeps current modes

we need to handle after-revert-buffer-hook

but we can’t tell hard and soft reload apart. Yes we set the flag virtual-comment–is-initialized

we can’t do anything to undo

when undo applies to region having comments, we lose them

use notify to listen to change in evc file

  • [x] we only persist to project .evc when the last buffer closed
  • [x] must have a function to replace active data with data loaded from store
    • first call virtual-comment–reload-project once for the project
    • next each buffer calls virtual-comment–reload-data
  • [ ] get all buffers belonging to the project and run the init again in a with-current-buffer. This way alleviates the doubled pubsub between buffers and store

tie comment with line content

(point comment target)

and then before any update or a timer we run a function to reconcile any mismatch between point and line-content then find the right line and move the ov to it

(thing-at-point ‘line t)

ov has virtual-comment virtual-comment-target

virtual-comment–ovs-to-cmts could be the place to reconcile the change

[ovwl] now line is tied to ov comment should ov cover the whole line?

and a notification inside ov can be added and the ov can self correct when there is change inside it and update its position and its virtual properties

if so we don’t need the reconcile process anymore

must decide where is the source of truth of ‘virtual-comment-target

line at point or overlay where do we assign the point value that’s where we pick up the target but point can be moved but target can be fixed on created

  • point can be moved freely
  • target should be fixed
  • [x] target created by -make
  • [x] target can be changed by -paste
  • [x] target can be changed by repair fn

how to reconcile

org-open-at-point which calls org-link-open-as-file finally (org-link-search ”When”)

(words (split-string s))) (s-multi-re (mapconcat #’regexp-quote words “\(?:[ \t\n]+\)”))

((catch :fuzzy-match (goto-char (point-min)) (while (re-search-forward s-multi-re nil t) ;; Skip match if it contains AVOID-POS or it is included in ;; a link with a description but outside the description. (unless (or (and avoid-pos (<= (match-beginning 0) avoid-pos) (> (match-end 0) avoid-pos)) (and (save-match-data (org-in-regexp org-link-bracket-re)) (match-beginning 3) (or (> (match-beginning 3) (point)) (<= (match-end 3) (point))) (org-element-lineage (save-match-data (org-element-context)) ‘(link) t))) (goto-char (match-beginning 0)) (setq type ‘fuzzy) (throw :fuzzy-match t))) nil)) file:virtual-comment.el::unless (string= org-target current-target

overlays-in vs overlays-at

this is a headache for (virtual-comment–get-overlay-at point) we use (overlays-at point) to get all overlays but this function can’t get empty overlays. (overlays-in point point) can get the empty overlays but then it can’t get overlays when at the beginning of the overlay start

we may risk to use save-excursion to check for empty line which is not clean. fix is (overlays-in point (1+ point)), may need to consider the point-max

before emacs is killed, persistence won’t kick it

it seems that kill-buffer-hook is not triggered in this case

insprired by flycheck-global-teardown we would do the same add have a function to kill buffer hook this function will go through the buffer list if mode is active it will call

ref/location feature

a function to produce this string: symbol | project-file-path:line-number a function to get read the string and extract project-file-path:line-number then allows us to go there

how can we add the string to the comment? we store the string in a list ((string . project)) then we invoke a function to append the string to the comment

Issue with multiple frame for emacs 28

on emacs 28 read-from-minibuffer will be unable to focus to the prompt on first try if the prompt or the initial text has new line character. (read-from-minibuffer “what: \n”)

this is because emacs 28 has a new behavior for minibuffer

Improved handling of minibuffers on switching frames. By default, when you switch to another frame, an active minibuffer now moves to the newly selected frame. Nevertheless, the effect of what you type in the minibuffer happens in the frame where the minibuffer was first activated. An alternative behavior is available by customizing ‘minibuffer-follows-selected-frame’ to nil. Here, the minibuffer stays in the frame where you first opened it, and you must switch back to this frame to continue or abort its command. The old behavior, which mixed these two, can be approximated by customizing ‘minibuffer-follows-selected-frame’ to a value which is neither nil nor t.

The old behavior is desired (setq minibuffer-follows-selected-frame nil)

probably need to move away from minibuffer to prompt for a block of text string-edit and phantom-inline-comment are examples

create buffer

run a callback

delete comments from evcs

on evcs buffer get the virtual-comment-unit at point

remove it from virtual-comment-buffer-data

delete the the comment and the target line in the buffer

check if the target buffer is open. If so trigger update on that buffer

default case when handle non project files

handle string-p is nil when strayed comments are stacked on top

prevent data loss

the best way is to have evc data per git branch: .ecv.branh-name but it would be tedious how to transfer common data accross branch

a simple solution is to create a backup file every time we persist

never delete strayed comments

if we can’t place them then put them in a lost and found place

only save when data is changed

solution: diff data and validate saved data

how to tell if data is changed?

  • when you add a comment then mark a flag
  • but comments can be moved a round without user action due to file changes

what now?

  • each comment emit and event on change? too complicated
  • can we diff the project data? yes we can
  • before persist data we diff the data if they are different then back up and save otherwise do nothing

diff data

https://stackoverflow.com/questions/18180393/compare-hash-table-in-emacs-lisp

(defun hash-equal (hash1 hash2)
  "Compare two hash tables to see whether they are equal."
  (and (= (hash-table-count hash1)
          (hash-table-count hash2))
       (catch 'flag (maphash (lambda (x y)
                               (or (equal (gethash x hash2) y)
                                   (throw 'flag nil)))
                             hash1)
              (throw 'flag t))))