changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate emacs/lib/uml-mode.el

changeset 698: 96958d3eb5b0
parent: 74a55d5decce
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
604
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 ;;; uml-mode.el --- Minor mode for ascii uml sequence diagrams -*- lexical-binding: t -*-
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 ;; Copyright (C) 2015-2020 Ian Martins
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 ;; Author: Ian Martins <ianxm@jhu.edu>
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
6
 ;; URL: http://github.com/ianxm/emacs-uml
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
7
 ;; Version: 0.0.4
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
8
 ;; Keywords: docs
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
9
 ;; Package-Requires: ((emacs "24.4") seq)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
10
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
11
 ;; This file is not part of GNU Emacs.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
12
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
13
 ;; This program is free software: you can redistribute it and/or modify
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
14
 ;; it under the terms of the GNU General Public License as published by
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
15
 ;; the Free Software Foundation, either version 3 of the License, or
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
16
 ;; (at your option) any later version.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
17
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
18
 ;; This program is distributed in the hope that it will be useful,
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
19
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
20
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
21
 ;; GNU General Public License for more details.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
22
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
23
 ;; For a full copy of the GNU General Public License
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
24
 ;; see <http://www.gnu.org/licenses/>.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
25
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
26
 ;;; Commentary:
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
27
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
28
 ;; provides functions that help in writing ascii uml sequence diagrams.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
29
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
30
 ;;; Code:
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
31
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
32
 (require 'seq)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
33
 (require 'subr-x)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
34
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
35
 (defun uml-forward-timeline ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
36
   "Move the point to the next timeline bar."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
37
   (interactive)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
38
   (let ((start (point))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
39
         word)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
40
     (forward-word)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
41
     (setq word (point))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
42
     (goto-char start)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
43
     (forward-char)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
44
     (while (and
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
45
             (not (eq ?| (char-after)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
46
             (< (point) word))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
47
       (forward-char))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
48
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
49
 (defun uml-back-timeline ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
50
   "Move the point to the previous timeline bar."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
51
   (interactive)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
52
   (let ((start (point))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
53
         word)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
54
     (forward-word -1)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
55
     (setq word (point))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
56
     (goto-char start)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
57
     (forward-char -1)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
58
     (while (and
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
59
             (not (eq ?| (char-after)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
60
             (> (point) word))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
61
       (forward-char -1))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
62
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
63
 (defun uml-swap-left ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
64
   "Swap the timeline at the point with the timeline to its left."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
65
   (interactive)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
66
   (uml--redraw-sequence-diagram (list 'name :swapleft 'col (current-column))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
67
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
68
 (defun uml-swap-right ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
69
   "Swap the timeline at the point with the timeline to its right."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
70
   (interactive)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
71
   (uml--redraw-sequence-diagram (list 'name :swapright 'col (current-column))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
72
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
73
 (defun uml-delete-timeline ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
74
   "Delete the timeline at point."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
75
   (interactive)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
76
   (uml--redraw-sequence-diagram (list 'name :delete 'col (current-column))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
77
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
78
 (defun uml-insert-timeline ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
79
   "Insert a timeline to the right of the point."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
80
   (interactive)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
81
   (uml--redraw-sequence-diagram (list 'name :insert 'col (current-column))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
82
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
83
 (defun uml-sequence-diagram ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
84
   "Formats a sequence diagram."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
85
   (interactive)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
86
   (uml--redraw-sequence-diagram nil))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
87
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
88
 (defun uml--write-text-centered-on (text target)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
89
   "Write TEXT centered on the TARGET column."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
90
   (let* ((halfname (floor (/ (length text) 2)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
91
          (col (- target halfname))) ; target-pos-len/2
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
92
     (move-to-column col t)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
93
     (insert (format "%s" text))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
94
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
95
 (defun uml--write-vertical-space (timelines prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
96
   "Write a row of empty timeline bars for TIMELINES after writing PREFIX."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
97
   (if prefix
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
98
       (insert prefix))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
99
   (dolist (elt timelines)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
100
     (let* ((col (plist-get elt 'center)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
101
       (move-to-column col t)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
102
       (insert (format "|")))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
103
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
104
 (defun uml--find-nearest-timeline (timelines col)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
105
   "Return the index of the nearest of TIMELINES to the column COL."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
106
   (let ((ii 0)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
107
         olddelta
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
108
         ret
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
109
         delta)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
110
     (dolist (elt timelines)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
111
       (setq delta (abs (- col (plist-get elt 'origcenter))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
112
       (when (or (not ret) (< delta olddelta))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
113
         (setq ret ii)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
114
         (setq olddelta delta))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
115
       (setq ii (1+ ii)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
116
     ret))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
117
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
118
 (defun uml--write-arrow (from to dashed)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
119
   "Write an arrow from FROM timeline to TO timeline, possibly with a DASHED line."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
120
   (let ((delta (abs (- to from)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
121
         (ii 0)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
122
         on)                             ; bool to toggle between dash or space
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
123
     (move-to-column (1+ (min to from)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
124
     (if (> from to)                     ; <---
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
125
         (insert ?<))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
126
     (while (< ii (- delta 2))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
127
       (insert (if (or (not dashed) on) ?- ? ))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
128
       (if on (setq on nil) (setq on t)) ; toggle dash
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
129
       (setq ii (1+ ii)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
130
     (if (< from to)                     ; --->
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
131
         (insert ?>))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
132
     (delete-char (- delta 1))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
133
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
134
 (defun uml--write-label-and-arrow (timelines prefix fromcol tocol text dashed)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
135
   "Write TIMELINES with PREFIX then label and arrow for a message from column FROMCOL to column TOCOL with label TEXT which may be DASHED."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
136
   ;; write label
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
137
   (if text
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
138
       (let (center)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
139
         (dotimes (ii (length text))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
140
           (uml--write-vertical-space timelines prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
141
           (newline)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
142
           (forward-line -1)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
143
           (setq center (floor (/ (+ fromcol tocol) 2)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
144
           (uml--write-text-centered-on (nth ii text) center)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
145
           (delete-char (length (nth ii text)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
146
           (forward-line))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
147
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
148
   ;; write arrow
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
149
   (uml--write-vertical-space timelines prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
150
   (newline)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
151
   (forward-line -1)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
152
   (uml--write-arrow fromcol tocol dashed)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
153
   (forward-line))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
154
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
155
 (defun uml--write-self-arrow (timelines prefix col text)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
156
   "Write TIMELINES with PREFIX and an arrow from and to column COL, labeled with TEXT."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
157
   (let ((numrows (max 2 (length text)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
158
         arrow part-index text-part)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
159
     (dotimes (ii numrows)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
160
       (setq arrow (cond
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
161
                    ((= (- numrows ii) 2)  " --.")
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
162
                    ((= (- numrows ii) 1)  "<--'")
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
163
                    (t "    ")))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
164
       (if (not text)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
165
           (setq text-part "")
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
166
         (setq part-index (+ (- ii numrows) (length text)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
167
         (setq text-part (if (< part-index 0) "" (nth part-index text))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
168
       (uml--write-vertical-space timelines prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
169
       (newline)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
170
       (forward-line -1)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
171
       (move-to-column (1+ col))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
172
       (insert (format "%s %s" arrow text-part))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
173
       (delete-char (min (+ 5 (length text-part)) (- (line-end-position) (point))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
174
       (forward-line))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
175
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
176
 (defun uml--fit-label-between (timelines left right width)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
177
   "Spread out TIMELINES so that LEFT and RIGHT have WIDTH space between them."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
178
   (let (leftcol
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
179
         rightcol
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
180
         needed)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
181
     (setq leftcol (plist-get (nth left timelines) 'center))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
182
     (setq rightcol (plist-get (nth right timelines) 'center))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
183
     (setq needed (- (+ leftcol  width) rightcol))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
184
     (if (> needed 0)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
185
       (uml--shift-to-the-right timelines right needed))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
186
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
187
 (defun uml--shift-to-the-right (timelines right needed)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
188
   "Shift all TIMELINES greater than or equal to RIGHT to the right by NEEDED."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
189
   (let ((ii right)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
190
         elt)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
191
     (while (< ii (length timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
192
       (setq elt (nth ii timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
193
       (plist-put elt 'center (+ (plist-get elt 'center) needed))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
194
       (setq ii (1+ ii)))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
195
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
196
 (defun uml--swap-timelines (timelines messages col1 col2)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
197
   "Given all TIMELINES and MESSAGES, swap COL1 and COL2."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
198
   (let (tmp)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
199
     (setq tmp (nth col1 timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
200
     (setcar (nthcdr col1 timelines) (nth col2 timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
201
     (setcar (nthcdr col2 timelines) tmp))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
202
   (dolist (elt messages)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
203
     (if (= (plist-get elt 'from) col1) (plist-put elt 'from col2)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
204
       (if (= (plist-get elt 'from) col2) (plist-put elt 'from col1)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
205
     (if (= (plist-get elt 'to) col1) (plist-put elt 'to col2)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
206
       (if (= (plist-get elt 'to) col2) (plist-put elt 'to col1)))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
207
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
208
 (defun uml--find-top-or-bottom (direction)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
209
   "Return the position at the top or bottom of the diagram depending on DIRECTION (:top or :bottom)."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
210
   (let ((end-of-buffer (if (eq direction :top) (point-min) (point-max)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
211
         (step (if (eq direction :top) -1 1)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
212
     (while (and
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
213
             (not (= (point) end-of-buffer))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
214
             (not (looking-at "^[^[:word:]|]*$")))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
215
       (forward-line step))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
216
     (cond
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
217
      ((eq direction :top)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
218
       (if (looking-at "^[^[:word:]|]*$")
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
219
           (forward-line))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
220
       (point))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
221
      ((eq direction :bottom)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
222
       (if (not (= (point) (point-max)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
223
           (forward-line -1))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
224
       (line-end-position)))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
225
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
226
 (defun uml--calc-middle (start end)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
227
   "This just computes the integer mean of START and END."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
228
   (floor (/ (+ start end) 2)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
229
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
230
 (defun uml--determine-prefix ()
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
231
   "Determine the prefix (if there is one).
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
232
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
233
 The prefix is made up of any characters on the left margin that
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
234
 aren't part of the diagram, such as comment characters.  Prefixes
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
235
 can be any length but must be made up of only special
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
236
 characters.  Prefixes can have leading spaces but cannot contain
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
237
 spaces in the middle or at the end."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
238
   (if (looking-at "\\([[:blank:]]*[^[:word:][:blank:]]+\\) ")
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
239
       (match-string 1)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
240
     nil))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
241
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
242
 (defun uml--parse-timelines (prefix bottom)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
243
   "Parse the timeline names.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
244
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
245
 Parse timeline names after the PREFIX of each line until we hit
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
246
 BOTTOM or see a pipe indicating we're past the timeline names and
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
247
 into the messages.  For each timeline, determine the name and
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
248
 center column.  The return structure looks like:
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
249
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
250
     [ (name \"timeline1\" origcenter 5) ... ]
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
251
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
252
 Names can contain any characters except whitespace or pipes."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
253
   (let (timelines eob)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
254
     (while (and (looking-at (concat prefix "[^|]+$"))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
255
                 (< (point) bottom))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
256
       (forward-char (length prefix))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
257
       ;; the first "[:blank:]" allows whitespace leading to the name,
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
258
       ;; but doesn't let the while loop go to the next line.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
259
       (while (looking-at "[[:blank:]]*\\([^[:blank:]|\n]+\\)")
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
260
         (let* ((name (match-string 1))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
261
                (beg (- (match-beginning 1) (line-beginning-position)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
262
                (end (- (match-end 1) (line-beginning-position)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
263
                (center (uml--calc-middle beg end))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
264
                (index (uml--find-nearest-timeline timelines center))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
265
                (halflen (and index (/ (uml--max-length-multipart-name (plist-get (nth index timelines) 'name) 2) 2))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
266
           ;; if this is the first timeline or center is outside of the
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
267
           ;; nearest existing timeline, then this is a new timeline
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
268
           ;; and we should create a new timeline, else append to an
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
269
           ;; existing one
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
270
           (if (or (not timelines)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
271
                   (or (> beg (+ (plist-get (nth index timelines) 'origcenter) halflen))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
272
                       (< end (- (plist-get (nth index timelines) 'origcenter) halflen))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
273
               (setq timelines (append timelines (list (list 'name (list name)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
274
                                                                    'origcenter center))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
275
             (nconc (plist-get (nth index timelines) 'name) (list name))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
276
         (goto-char (match-end 1)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
277
       (setq eob (= 1 (forward-line 1))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
278
     (if (not eob)            ; if we didn't hit the end of the buffer,
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
279
         (forward-line -1))   ; back up so message parsing can pick up from the last header line
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
280
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
281
     (sort timelines (lambda (a b) (< (plist-get a 'origcenter)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
282
                                      (plist-get b 'origcenter))))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
283
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
284
 (defun uml--parse-messages (timelines prefix bottom)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
285
   "Parse the messages from the diagram.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
286
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
287
 Parse messages from the diagram given the TIMELINES and PREFIX
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
288
 until we reach the BOTTOM.  Messages is a mixed list of plists of
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
289
 arrows and separators.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
290
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
291
 Arrows look like:
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
292
     (from 0 to 2 label (\"doIt()\") dashed nil)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
293
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
294
 Labels must start with a number or letter and cannot contain
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
295
 spaces, angle brackets or dashes.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
296
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
297
 Separators look like:
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
298
     (text \"title for next part\")"
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
299
   (let (messages label dashed found)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
300
     (while (and (< (line-end-position) (- bottom (length prefix)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
301
                 (< (line-end-position) (buffer-end 1)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
302
       (forward-line 1)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
303
       (forward-char (length prefix))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
304
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
305
       ;; the label may be above the message or on the same line
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
306
       (when (re-search-forward "[[:word:]][^\n|<>\-]*" (line-end-position) t)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
307
         (if (not label)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
308
             (setq label (list (string-trim-right (match-string 0)))) ; single part
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
309
           (nconc label (list (string-trim-right (match-string 0))))) ; multi part
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
310
         (beginning-of-line))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
311
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
312
       ;; FOUND is (from . to) where FROM and TO are timeline indices
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
313
       (setq found (uml--find-message-bounds-maybe timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
314
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
315
       (when found
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
316
         (beginning-of-line)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
317
         (setq dashed (re-search-forward "\- \-" (line-end-position) t))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
318
         (setq messages (append messages (list (list 'label  label
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
319
                                                     'from   (car found)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
320
                                                     'to     (cdr found)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
321
                                                     'dashed dashed))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
322
         (setq label nil)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
323
     messages))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
324
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
325
 (defun uml--find-message-bounds-maybe (timelines)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
326
   "Find which timelines a message connects.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
327
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
328
 Return the indices in TIMELINES between which the message passes
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
329
 as (from . to), else nil if there is no message on the current
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
330
 line"
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
331
   (let (from to found)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
332
     (cond
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
333
      ((re-search-forward "\-.*>" (line-end-position) t) ; ->
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
334
       (setq from (uml--find-nearest-timeline timelines (- (match-beginning 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
335
       (setq to (uml--find-nearest-timeline timelines (- (match-end 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
336
       (setq found t))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
337
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
338
      ((re-search-forward "<.*\-" (line-end-position) t) ; <-
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
339
       (setq from (uml--find-nearest-timeline timelines (- (match-end 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
340
       (setq to (uml--find-nearest-timeline timelines (- (match-beginning 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
341
       (setq found t))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
342
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
343
      ((re-search-forward "<" (line-end-position) t)     ; <
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
344
       (setq from (uml--find-nearest-timeline timelines (- (match-end 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
345
       (setq to (uml--find-nearest-timeline timelines (- (match-beginning 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
346
       (setq found t))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
347
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
348
      ((re-search-forward "|\-" (line-end-position) t)   ; |-
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
349
       (setq from (uml--find-nearest-timeline timelines (- (match-beginning 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
350
       (setq to (1+ from))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
351
       (if (< to (length timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
352
           (setq found t)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
353
         (message "Ignoring out of bounds message.")))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
354
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
355
      ((re-search-forward "\-|" (line-end-position) t)   ; -|
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
356
       (setq from (uml--find-nearest-timeline timelines (- (match-beginning 0) (line-beginning-position))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
357
       (setq to (- from 1))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
358
       (if (>= to 0)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
359
           (setq found t)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
360
         (message "Ignoring out of bounds message."))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
361
     (if found (cons from to) nil)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
362
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
363
 (defun uml--apply-adjustments (adjust timelines messages)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
364
   "Apply ADJUST to TIMELINES and MESSAGES.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
365
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
366
 Return (TIMELINES . MESSAGES) since we mucked with both of them."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
367
   (cond
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
368
    ((eq :swapleft (plist-get adjust 'name))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
369
     (let (current swapwith)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
370
       (setq current (uml--find-nearest-timeline timelines (plist-get adjust 'col)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
371
       (setq swapwith (- current 1))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
372
       (if (or (< swapwith 0) (>= swapwith (length timelines)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
373
           (plist-put adjust 'movetocol current)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
374
         (plist-put adjust 'movetocol swapwith)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
375
         (uml--swap-timelines timelines messages current swapwith))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
376
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
377
    ((eq :swapright (plist-get adjust 'name))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
378
     (let (current swapwith)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
379
       (setq current (uml--find-nearest-timeline timelines (plist-get adjust 'col)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
380
       (setq swapwith (1+ current))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
381
       (if (or (< swapwith 0) (>= swapwith (length timelines)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
382
           (plist-put adjust 'movetocol current)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
383
         (plist-put adjust 'movetocol swapwith)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
384
         (uml--swap-timelines timelines messages current swapwith))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
385
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
386
    ((eq :delete (plist-get adjust 'name))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
387
     (let (current col)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
388
       (setq current (uml--find-nearest-timeline timelines (plist-get adjust 'col))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
389
             col current)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
390
       (plist-put adjust 'movetocol (max 0 (1- col)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
391
       (when (>= col 0)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
392
         (setq timelines (delete (nth col timelines) timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
393
         (dolist (elt messages)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
394
           (let ((from (plist-get elt 'from))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
395
                 (to   (plist-get elt 'to)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
396
             (if (or (= from col) (= to col))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
397
                 (setq messages (delete elt messages))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
398
               (if (> from col) (plist-put elt 'from (- from 1)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
399
               (if (> to col) (plist-put elt 'to (- to 1)))))))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
400
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
401
    ((eq :insert (plist-get adjust 'name))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
402
     (let (current new rest)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
403
       (setq current (uml--find-nearest-timeline timelines (plist-get adjust 'col)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
404
       (plist-put adjust 'movetocol current)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
405
       (setq current (1+ current))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
406
       (setq new (list (list 'name (list "new")
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
407
                             'origcenter nil)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
408
       (setq rest (nthcdr current timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
409
       (setcdr (nthcdr (- current 1) timelines) new)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
410
       (setcdr new rest)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
411
       (dolist (elt messages)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
412
         (let ((from (plist-get elt 'from))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
413
               (to   (plist-get elt 'to)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
414
           (if (>= from current) (plist-put elt 'from (1+ from)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
415
           (if (>= to current) (plist-put elt 'to (1+ to))))))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
416
   (cons timelines messages))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
417
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
418
 (defun uml--max-length-multipart-name (multipart-name min)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
419
   "Convenience function to compute the longest string.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
420
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
421
 Return the longest string in MULTIPART-NAME, which is a list of
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
422
 strings, or MIN if it is longer."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
423
   (seq-reduce (lambda (namelength namepart) (max namelength (length namepart)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
424
               multipart-name
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
425
               min))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
426
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
427
 (defun uml--space-out-timelines (timelines messages prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
428
   "Space out TIMELINES to fit MESSAGES' labels and PREFIX."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
429
     (dotimes (ii (length timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
430
       (plist-put (nth ii timelines) 'center (+ (* 12 ii) 6 (length prefix))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
431
     (let (elt needed namelen)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
432
       (dotimes (ii (length timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
433
         (setq elt (nth ii timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
434
         (setq namelen (uml--max-length-multipart-name (plist-get elt 'name) 8))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
435
         (setq needed (floor (/ (- namelen 8) 2)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
436
         (when (> needed 0)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
437
             (uml--shift-to-the-right timelines ii      needed)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
438
             (uml--shift-to-the-right timelines (1+ ii) needed))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
439
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
440
     (dolist (elt messages)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
441
       (let* ((to    (plist-get elt 'to))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
442
              (from  (plist-get elt 'from))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
443
              (left  (min to from))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
444
              (right (max to from)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
445
         (if (= left right)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
446
             (if (< (1+ left) (length timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
447
                 (uml--fit-label-between timelines ; self arrow
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
448
                                         left
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
449
                                         (1+ left)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
450
                                         (+ (uml--max-length-multipart-name (plist-get elt 'label) 0) 8)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
451
           (uml--fit-label-between timelines
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
452
                                   left
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
453
                                   right
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
454
                                   (+ (uml--max-length-multipart-name (plist-get elt 'label) 0) 4))))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
455
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
456
 (defun uml--count-timeline-name-rows (timelines)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
457
   "Count the rows of the TIMELINES' names."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
458
   (seq-reduce (lambda (val elt) (max val (length (plist-get elt 'name))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
459
                               timelines 0))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
460
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
461
 (defun uml--write-diagram (timelines messages prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
462
   "Write the TIMELINES and MESSAGES using PREFIX to the buffer.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
463
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
464
 This is done in two steps:
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
465
 1. write timeline names
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
466
 2. write messages"
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
467
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
468
   ;; 1. write timeline names
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
469
   (let (numrows)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
470
     ;; determine the number of rows needed for the timeline names
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
471
     (setq numrows (uml--count-timeline-name-rows timelines))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
472
     ;; then write them out to the buffer
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
473
     (dotimes (ii numrows)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
474
       (if prefix
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
475
           (insert prefix))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
476
       (dolist (elt timelines)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
477
         (let* ((parts (plist-get elt 'name))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
478
                (index (+ (- (length parts) numrows) ii))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
479
                (part (and (>= index 0) (nth index parts))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
480
           (if part
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
481
               (uml--write-text-centered-on part
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
482
                                            (plist-get elt 'center)))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
483
       (newline)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
484
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
485
   ;; 2. write messages
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
486
   (dolist (elt messages)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
487
     (uml--write-vertical-space timelines prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
488
     (newline)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
489
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
490
     (let* ((text       (plist-get elt 'label))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
491
            (from       (plist-get elt 'from))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
492
            (to         (plist-get elt 'to))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
493
            (fromcenter (plist-get (nth from timelines) 'center))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
494
            (tocenter   (plist-get (nth to timelines) 'center))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
495
            (dashed     (plist-get elt 'dashed))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
496
            selfmessage)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
497
       (setq selfmessage (= (plist-get elt 'from) (plist-get elt 'to)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
498
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
499
       (if selfmessage
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
500
           (uml--write-self-arrow timelines prefix fromcenter text)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
501
         (uml--write-label-and-arrow timelines prefix fromcenter tocenter text dashed))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
502
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
503
   (uml--write-vertical-space timelines prefix))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
504
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
505
 (defun uml--redraw-sequence-diagram (adjust)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
506
   "Redraws a sequence diagram after applying ADJUST.  This is the main routine."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
507
   (let (top         ; first line in buffer of diagram
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
508
         bottom      ; last line in buffer of diagram
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
509
         prefix      ; comment character or nil
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
510
         timelines   ; list of timeline data
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
511
         messages)   ; list of arrow data
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
512
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
513
     (beginning-of-line)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
514
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
515
     ;; find the top and bottom of the diagram
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
516
     (setq top (uml--find-top-or-bottom :top))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
517
     (setq bottom (uml--find-top-or-bottom :bottom))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
518
     ;; (message "top: %d bottom: %d" top bottom)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
519
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
520
     (goto-char top)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
521
     (setq prefix (uml--determine-prefix))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
522
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
523
     ;; parse timeline names from old diagram
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
524
     (setq timelines (uml--parse-timelines prefix bottom))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
525
     ;; (message "timelines %s" timelines)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
526
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
527
     ;; parse messages from old diagram
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
528
     (setq messages (uml--parse-messages timelines prefix bottom))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
529
     ;; (message "messages %s" messages)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
530
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
531
     ;; clear the old diagram content from the buffer
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
532
     (goto-char top)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
533
     (delete-char (- bottom top))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
534
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
535
     ;; apply adjustments such as shifts or swaps
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
536
     (let (ret)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
537
       (setq ret (uml--apply-adjustments adjust timelines messages))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
538
       (setq timelines (car ret)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
539
             messages (cdr ret)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
540
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
541
     ;; calculate timeline center columns
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
542
     (uml--space-out-timelines timelines messages prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
543
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
544
     ;; render the diagram into the buffer
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
545
     (uml--write-diagram timelines messages prefix)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
546
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
547
     ;; move the cursor back to the column where it was before we did anything
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
548
     (goto-char top)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
549
     (when (plist-get adjust 'movetocol)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
550
       (forward-line (1- (uml--count-timeline-name-rows timelines)))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
551
       (move-to-column (plist-get (nth (plist-get adjust 'movetocol) timelines) 'center)))))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
552
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
553
 ;;;###autoload
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
554
 (define-minor-mode uml-mode
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
555
   "Toggle uml mode.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
556
 Interactively with no argument, this command toggles the mode.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
557
 A positive prefix argument enables the mode, any other prefix
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
558
 argument disables it.  From Lisp, argument omitted or nil enables
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
559
 the mode, `toggle' toggles the state.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
560
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
561
 When uml mode is enabled, C-c while the point is in a
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
562
 sequence diagram cleans up the formatting of the diagram.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
563
 See the command \\[uml-seqence-diagram]."
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
564
  ;; The initial value.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
565
  :init-value nil
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
566
  ;; The indicator for the mode line.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
567
  :lighter " uml"
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
568
  ;; The minor mode bindings.
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
569
  :keymap
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
570
  `((,(kbd "C-c C-c") . uml-sequence-diagram)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
571
    (,(kbd "<M-left>") . uml-swap-left)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
572
    (,(kbd "<M-right>") . uml-swap-right)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
573
    (,(kbd "<M-S-left>") . uml-delete-timeline)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
574
    (,(kbd "<M-S-right>") . uml-insert-timeline)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
575
    (,(kbd "M-f") . uml-forward-timeline)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
576
    (,(kbd "M-b") . uml-back-timeline))
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
577
  :group 'uml)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
578
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
579
 (provide 'uml-mode)
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
580
 
74a55d5decce emacs org libraries and upgrades
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
581
 ;;; uml-mode.el ends here