596 lines
27 KiB
EmacsLisp
596 lines
27 KiB
EmacsLisp
;;; my.el --- Personal library -*- lexical-binding: t -*-
|
|
|
|
;;; Commentary:
|
|
;; Org:
|
|
;; Colored text in Org buffer and export.
|
|
;; [[color:gray][text]]
|
|
;; [[color:#cccccc][text]]
|
|
|
|
;;; Code:
|
|
;; ELisp:
|
|
;; (equal (symbol-name 'tmp) "tmp") ;; get symbol as string and compare with string
|
|
;; (equal (intern "tmp") 'tmp) ;; get string as symbol and compare with symbol
|
|
;; (regexp-quote "/foo/baz/*") ;; => "/foo/baz/\\*"
|
|
;; (add-hook 'help-mode-hook 'virtual-auto-fill-mode) ;; add a mode-hook
|
|
;; (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook 'a-test-save-hook nil t))) ;; add local hook to a mode-hook
|
|
;; Org:
|
|
;; https://orgmode.org/worg/dev/org-element-api.html
|
|
;; https://orgmode.org/worg/dev/org-syntax.html
|
|
;; Over an element, like a table. The key must start with attr_.
|
|
;; The lower line shows the plist elements inside the org element context.
|
|
|
|
(require 'my-view)
|
|
|
|
(defgroup my nil
|
|
"My concept mapping"
|
|
:prefix "my-"
|
|
:group 'emacs)
|
|
|
|
(defun my-help ()
|
|
"Display help"
|
|
(interactive)
|
|
(let ((buffer-name "*Quick Help*")
|
|
(org-link-descriptive t)
|
|
(org-hide-emphasis-markers t))
|
|
(with-current-buffer (get-buffer-create buffer-name)
|
|
(define-derived-mode my-org-help-mode org-mode "Org help mode"
|
|
"Major mode for help buffers using Org mode")
|
|
(insert "\
|
|
|
|
*General Commands* /S: shift, C: control, M: alt or ⌘/
|
|
|
|
[[help:save-buffer][Save]] ................... =C-x= =C-s= [[help:help-for-help][Help]] ................... =C-h= =C-h=
|
|
[[help:write-file][Save as]] ................ =C-x= =C-w= [[help:keyboard-quit][Cancel]] ..................... =C-g=
|
|
[[help:find-file][Open file]] .............. =C-x= =C-f= [[help:undo][Undo]] ....................... =C-/=
|
|
[[help:counsel-recentf][Open recent]] ............ =C-x= =C-r= [[help:kill-buffer][Close buffer]] ............. =C-x= =k=
|
|
[[help:dired][Browse directory]] ......... =C-x= =d= [[help:counsel-switch-buffer][Switch buffer]] ............ =C-x= =b=
|
|
[[help:previous-buffer][Previous buffer]] ....... =C-x= =left= [[help:next-buffer][Next buffer]] .......... =C-x= =right=
|
|
[[help:winner-undo][Undo window layout]] .... =C-c= =left= [[help:winner-redo][Redo window layout]] ... =C-c= =right=
|
|
[[help:save-buffers-kill-terminal][Quit]] ................... =C-x= =C-c= [[toggle-window-split][Toggle 2 window split]] ... =C-x= =|=
|
|
|
|
[[help:swiper][Search]] ..................... =C-s= [[help:goto-line][Go to line]] ............. =M-g= =M-g=
|
|
[[help:query-replace][Replace]] .................... =M-%= [[help:counsel-M-x][Execute]] .................... =M-x=
|
|
[[help:begin-of-buffer][Begin of buffer]] ............ =M-<= [[help:beginning-of-line][Begin of line]] .............. =C-a=
|
|
[[help:end-of-buffer][End of buffer]] .............. =M->= [[help:end-of-line][End of line]] ................ =C-e=
|
|
|
|
[[help:set-mark-command][Mark]] ..................... =C-SPC= [[help:kill-ring-save][Copy]] ....................... =M-w=
|
|
[[help:rectangle-mark-mode][Mark rectangular]] ....... =C-x SPC= [[help:yank][Paste]] ...................... =C-y=
|
|
[[help:mark-whole-buffer][Mark whole buffer]] ........ =C-x= =h= [[help:counsel-yank-pop][Paste older]] ................ =M-y=
|
|
[[help:kill-region][Cut]] ........................ =C-w= [[help:move-line-up][Move line up]] .............. =M-up=
|
|
[[help:kill-line][Cut rest of line]] ........... =C-k= [[move-line-down][Move line down]] .......... =M-down=
|
|
[[help:indent-rigidly][Indent lines]] ........... =C-x= =TAB=
|
|
|
|
*Help*
|
|
[[help:helpful-at-point][Symbol at point]] ........ =C-c= =C-d= [[help:describe-variable][Variable]] ................. =C-h= =v=
|
|
[[help:helpful-command][Commands]] ................. =C-h= =C= [[help:helpful-variable][Variable (extended)]] ...... =C-h= =V=
|
|
[[help:describe-function][Functions]] ................ =C-h= =f= [[help:describe-key][Key]] ...................... =C-h= =k=
|
|
[[help:helpful-function][Functions (extended)]] ..... =C-h= =F= [[help:helpful-key][Key (extended)]] ........... =C-h= =K=
|
|
|
|
*Multiple cursors* [[help:mc/mark-all-dwim][Mark all at point]] .... =M-m= =s= =m= =a=
|
|
, Jump to next cursor ...... =C-v= , (un)hide other lines ..... =C-'=
|
|
, Jump to previous cursor .. =M-v=
|
|
/[[info:emacs#Key%2520Bindings][Other key bindings]]/
|
|
*Mouse*
|
|
[[help:mwheel-scroll][Scroll right]] ........... =mouse-6= [[help:previous-buffer][Previous buffer]] ........ =mouse-8=
|
|
[[help:mwheel-scroll][Scroll left]] ............ =mouse-7= [[help:next-buffer][Next buffer]] ............ =mouse-9=
|
|
[[help:mouse-wheel-text-scale][Zoom in]] ............. =C-wheel-up= [[help:mouse-wheel-global-text-scale][Zoom in global]] .... =C-M-wheel-up=
|
|
[[help:mouse-wheel-text-scale][Zoom out]] .......... =C-wheel-down= [[help:mouse-wheel-global-text-scale][Zoom out global]] . =C-M-wheel-down=
|
|
|
|
*Spelling* (flyspell ispell)
|
|
Spell check whole buffer ........................... [[help:flyspell-buffer][flyspell-buffer]]
|
|
On-the-fly spell checking ............................ [[help:flyspell-mode][flyspell-mode]]
|
|
, [[help:flyspell-correct-wrapper][Correct word]] ............. =C-;= , [[help:flyspell-goto-next-error][Next error]] ............... =C-,=
|
|
, [[help:flyspell-correct-word][Correct word]] ......... =mouse-2=
|
|
|
|
|
|
*Org* see also [[elisp:(my-org-article-help)][Article help]] and YASnippet templates
|
|
|
|
[[help:org-toggle-pretty-entities][Pretty entities]] (\\xyz to UTF8 char) ...................... =C-c= =C-x= =\\=
|
|
[[help:org-redisplay-images][Redisplay inline images]] .............................. =C-c= =C-x= =C-M-v=
|
|
|
|
*Table*
|
|
[[help:org-shiftleft][Move cell left]] .......... =S-left= [[help:org-shiftup][Move cell up]] .............. =S-up=
|
|
[[help:org-shiftright][Move cell right]] ........ =S-right= [[help:org-shiftdown][Move cell down]] .......... =S-down=
|
|
[[help:org-table-blank-field][Clear cell]] ................. =SPC= [[help:org-table-shrink][Shrink columns]] ..... =C-u C-c TAB=
|
|
[[help:org-table-toggle-column-width][Shrink/expand column]] ... =C-c TAB= [[help:org-table-expand][Expand columns]] . =C-u C-u C-c TAB=
|
|
|
|
[[help:org-table-create-or-convert-from-region][Convert seperator (1. tab, 2. comma, 3. space)]] ............... =C-c= =|=
|
|
, comma .............. =C-u= =C-c= =|= , tab separator .. =C-u= =C-u= =C-c= =|=
|
|
, spaces ..... =C-u= =INTEGER= =C-c= =|= , regex ........ =C-u= =REGEX= =C-c= =|=
|
|
|
|
*SRC*
|
|
[[help:org-babel-tangle][write src block to file]] (=:tangle filename=) ............... =C-c= =C-v= =t=
|
|
|
|
*SRC figures generating tex output, e.g. gnuplot*
|
|
Do not use =%= but =\\%= or in a format command =\\%%=
|
|
- =%= starts a comment in LaTeX and therefore stops further interpre-
|
|
tations like a closing bracket =}= etc.
|
|
- Gnuplot graphics are imported as .tex (text, axis, legend) and
|
|
.eps (figure) files.
|
|
- =\\%= and =\\%%= can also be used for HTML SVG export
|
|
|
|
*Export*
|
|
[[help:org-html-export-to-html][HTML]] ............... =C-c= =C-e= =h= =h= [[help:org-latex-export-to-pdf][PDF (LaTeX)]] ........ =C-c= =C-e= =l= =l=
|
|
[[help:my-org-article-html-export-to-html][HTML article]] ....... =C-c= =C-e= =h= =a= [[help:my-org-article-latex-export-to-pdf][PDF article (LaTeX)]] =C-c= =C-e= =l= =a=
|
|
[[help:my-org-article-html-export-to-html-notify-async][HTML article (async)]] ........ =F5= [[help:my-org-article-latex-export-to-pdf-notify-async][PDF article (LaTeX, async)]] .. =F6=
|
|
[[help:my-org-letter-latex-export-to-pdf][PDF letter (LaTeX)]] . =C-c= =C-e= =l= =t=
|
|
|
|
*Export LaTeX* [[help:org-latex-remove-logfiles][Logfiles are removed]] (deactivate for debugging)
|
|
|
|
|
|
*Programming languages*
|
|
|
|
[[help:completion-at-point][Completion]] ............... =C-M-i= [[help:xref-find-definitions][Definitions]] ................ =M-.=
|
|
[[help:eldoc][Help]] ................... =C-c e d= [[help:xref-find-references][References]] ................. =M-?=
|
|
|
|
*Python*
|
|
IDE view ........ [[help:my-view-python][my-view-python]]
|
|
|
|
*Elisp*
|
|
[[help:eval-expression][Evaluate expression]] ........ =M-:= [[help:forward-sexp][Jump to next expression]] .. =C-M-f=
|
|
- [[help:eval-last-sexp][last to echo]] ......... =C-x= =C-e= [[help:backward-sexp][Jump tp prev. expression]] . =C-M-b=
|
|
- [[help:eval-print-last-sexp][last to buffer]] [[help:kill-sexp][Cut expression]] ........... =C-M-k=
|
|
[[help:mark-sexp][Mark expression]] .......... =C-M-@= [[help:backward-kill-sexp][Cut last expression]] . =C-M-backsp=
|
|
[[help:counsel-set-variable][Set variable]] .............. =F2 j=
|
|
|
|
|
|
*IBuffer*
|
|
|
|
[[help:ibuffer-filter-by-unsaved][Filter unsaved files]] ....... =/= =u= [[help:ibuffer-filter-disable][Disable filter]] ............. =/= =/=
|
|
|
|
")
|
|
(my-org-help-mode)
|
|
(when (featurep 'org-appear) (org-appear-mode -1))
|
|
(goto-char (point-min))
|
|
(font-lock-ensure)
|
|
(local-set-key (kbd "q") 'kill-buffer-and-window)
|
|
(local-set-key (kbd "C-g") 'kill-buffer-and-window)
|
|
(not-modified)
|
|
(read-only-mode))
|
|
(pop-to-buffer buffer-name '((display-buffer-below-selected)
|
|
(window-parameters . ((no-other-window . nil)))
|
|
(window-height . fit-window-to-buffer)))
|
|
(message "C-g - Quit, q - Quit")))
|
|
|
|
(defun my-eval-string (string)
|
|
"Evaluate elisp code stored in a string."
|
|
(eval (car (read-from-string (format "(progn %s)" string)))))
|
|
|
|
(defun my-list-delete (element list)
|
|
"Destructive version of `delete'.
|
|
LIST will be nil if the last ELEMENT was deleted.
|
|
Example:
|
|
(setq my-list '(\"a\"))
|
|
(my-list-delete \"a\" 'my-list)
|
|
(setq my-list '(a))
|
|
(my-list-delete 'a 'my-list)
|
|
(add-to-list 'my-list '(\"a\"))
|
|
(my-list-delete '(\"a\") 'my-list)"
|
|
(set list (delete element (symbol-value list))))
|
|
|
|
(defun my-list-to-org-table (lst)
|
|
"Convert list into an Org table."
|
|
(let ((lines lst)
|
|
(rows)
|
|
(tbl))
|
|
(while lines
|
|
(setq rows (car lines))
|
|
(setq tbl (concat tbl "|"))
|
|
(while rows
|
|
(setq tbl (concat tbl (format "%s|" (car rows))))
|
|
(setq rows (cdr rows)))
|
|
(setq tbl (concat tbl "\n"))
|
|
(setq lines (cdr lines)))
|
|
tbl))
|
|
|
|
(defmacro my-plist-put (plist &rest args)
|
|
"Example usage:
|
|
(my-plist-put my-org-table-colored-cells 'table-name '(\"@23$3\" \"blue\"))
|
|
(my-plist-put my-org-table-colored-cells
|
|
'table-name-1 '(\"@13$3\" \"red\") 'table-name-2 '(\"@33$3\" \"green\"))"
|
|
(let ((list nil))
|
|
(while args
|
|
(push `(setq ,plist (plist-put ,plist ,(pop args) ,(pop args))) list))
|
|
(cons 'progn (nreverse list))))
|
|
|
|
(defun my-interpolate (low high r rlow rhigh)
|
|
"Return the point between LOW and HIGH that corresponds to where R is \
|
|
between RLOW and RHIGH.
|
|
|
|
Linear interpolate of R in the interval RLOW RHIGH.
|
|
|
|
RESULT - LOW HIGH - LOW
|
|
------------ = ------------
|
|
R - RLOW RHIGH - RLOW
|
|
|
|
HIGH - LOW
|
|
RESULT = LOW + (R - RLOW) * ------------
|
|
RHIGH - RLOW
|
|
|
|
Example:
|
|
(my-interpolate 0 100 12 0 10) => 120"
|
|
(+ low (/ (* (- high low) (- r rlow)) (- rhigh rlow))))
|
|
|
|
(defun my-color-luminance (R G B)
|
|
"Luminosity, relative luminance.
|
|
|
|
L = 0.2126*R' + 0.7152*G' + 0.0722*B' with
|
|
[R',G',B'] = [R,G,B] / 12.92 if [R,G,B] <= 0.03928 else (([R,G,B]+0.055)/1.055)^2.4
|
|
earlier
|
|
L = 0.2126*R^2.2 + 0.7152*G^2.2 + 0.0722*B^2.2
|
|
|
|
R,G,B,L = [0, 1]
|
|
See also `my-color-contrast'"
|
|
;; https://www.w3.org/Graphics/Color/sRGB.html
|
|
(let ((R (if (<= R 0.03928) (/ R 12.92) (expt (/ (+ R 0.055) 1.055) 2.4)))
|
|
(G (if (<= G 0.03928) (/ G 12.92) (expt (/ (+ G 0.055) 1.055) 2.4)))
|
|
(B (if (<= B 0.03928) (/ B 12.92) (expt (/ (+ B 0.055) 1.055) 2.4))))
|
|
(+ (* 0.2126 R) (* 0.7152 G) (* 0.0722 B)))
|
|
;; earlier
|
|
;;(+ (* 0.2126 (expt R 2.2)) (* 0.7152 (expt G 2.2)) (* 0.0722 (expt B 2.2)))
|
|
)
|
|
|
|
(defun my-color-contrast (R1 G1 B1 &optional R2 G2 B2)
|
|
"Luminosity contrast ratio.
|
|
Calculate the difference between the given colors R1, G1, B1 and R2,
|
|
G2, B2. The returned value should be greater than or equal to 4.5
|
|
\(earlier greater than 5) for best readability. Using
|
|
`my-color-luminance'. R2, G2, B2 defaults to black. See also
|
|
`color-dark-p'."
|
|
;; https://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
|
;; https://www.w3.org/TR/2016/NOTE-WCAG20-TECHS-20161007/G18
|
|
(let* ((L1 (my-color-luminance R1 G1 B1))
|
|
(R2 (if R2 R2 0)) (G2 (if G2 G2 0)) (B2 (if B2 B2 0))
|
|
(L2 (my-color-luminance R2 G2 B2)))
|
|
(if (> L1 L2) ;; normally L1 defined as the lighter color and L2 as the darker color
|
|
(/ (+ L1 0.05) (+ L2 0.05))
|
|
(/ (+ L2 0.05) (+ L1 0.05)))))
|
|
|
|
(defun my-color-rgb-gradient (rgbsteps position)
|
|
"RGBSTEPS is a list of four element lists.
|
|
The list consists
|
|
- a start position value for the color d
|
|
- and the three color parameters r g b
|
|
- example
|
|
'((d1 r1 g1 b1)
|
|
(d2 r2 g2 b2)
|
|
(d3 r3 g3 b3)
|
|
(d4 r4 g4 b4))
|
|
with d1 < d2 < d3 < d4
|
|
if POSITION <= d1 then return (r1 g1 b1)
|
|
else remove the rgbstep_i where POSITION > di+1 from RGBSTEPS
|
|
if there is only one rgbstep left in RGBSTEPS return the (rn gn bn) values
|
|
otherwise interpolate of the first two rgbstep elements of the remaining
|
|
RGBSTEPS list.
|
|
|
|
Examples:
|
|
(my-rgb-gradient '((1 1 1 1) (2 2 2 2) (3 3 3 3)) 2)
|
|
(my-rgb-gradient '((1 1 1 1) (2 2 2 2)) 2)"
|
|
;; if position <= first element of first element (d1)
|
|
;; then return other elements of first element (r1 g1 b1)
|
|
(if (<= position (caar rgbsteps))
|
|
(cdar rgbsteps)
|
|
;; if there are other elements and if position > d1(,new) of the first other element
|
|
;; then remove first element
|
|
(while (and (cdr rgbsteps) (> position (caadr rgbsteps)))
|
|
(setq rgbsteps (cdr rgbsteps)))
|
|
;; if there is no other element, return other elements (rn gn bn) of the element in list
|
|
(if (null (cdr rgbsteps))
|
|
(cdar rgbsteps)
|
|
;; else there are at least two elements left.
|
|
;; return interpolation of the first two elements
|
|
(list
|
|
;; r1 g1 b1 r2 g2 b2 d1 d2
|
|
(my-interpolate (nth 1 (car rgbsteps)) (nth 1 (cadr rgbsteps)) position (caar rgbsteps) (caadr rgbsteps))
|
|
(my-interpolate (nth 2 (car rgbsteps)) (nth 2 (cadr rgbsteps)) position (caar rgbsteps) (caadr rgbsteps))
|
|
(my-interpolate (nth 3 (car rgbsteps)) (nth 3 (cadr rgbsteps)) position (caar rgbsteps) (caadr rgbsteps))))))
|
|
|
|
(defun my-filename ()
|
|
"Copy the full path of the current buffer into the `kill-ring' and
|
|
print it in the message buffer."
|
|
(interactive)
|
|
(let ((fn (buffer-file-name (window-buffer (minibuffer-selected-window)))))
|
|
(kill-new fn)
|
|
(message fn)))
|
|
|
|
(defun my-filename-basename ()
|
|
"Copy the basename of the current buffer into the `kill-ring' and
|
|
print it in the message buffer."
|
|
(interactive)
|
|
(let ((fn (file-name-nondirectory (my-filename))))
|
|
(kill-new fn)
|
|
(message fn)))
|
|
|
|
(defun my-gui-elements-toggle ()
|
|
"Function to toggle gui elements on/off."
|
|
(interactive)
|
|
(menu-bar-mode 'toggle)
|
|
(tool-bar-mode 'toggle))
|
|
|
|
(with-eval-after-load 'org
|
|
|
|
;;; colored table cells
|
|
;; https://emacs.stackexchange.com/questions/7375/can-i-format-cells-in-an-org-mode-table-differently-depending-on-a-formula
|
|
(require 'ov)
|
|
|
|
(defun my-org-toggle-emphasis ()
|
|
"Toggle hiding/showing of org emphasize markers."
|
|
(interactive)
|
|
(if org-hide-emphasis-markers
|
|
(set-variable 'org-hide-emphasis-markers nil)
|
|
(set-variable 'org-hide-emphasis-markers t))
|
|
(org-mode-restart))
|
|
(define-key org-mode-map (kbd "C-c C-x C-e") 'my-org-toggle-emphasis)
|
|
|
|
(defun my-org-keywords ()
|
|
"Parse the buffer and return a cons list of (key . value)
|
|
from lines like:
|
|
#+KEY: value"
|
|
(org-element-map (org-element-parse-buffer 'greater-element) 'keyword
|
|
(lambda (keyword) (cons (org-element-property :key keyword)
|
|
(org-element-property :value keyword)))))
|
|
|
|
(defun my-org-keyword (keyword)
|
|
"Get the value of a KEYWORD in the form of #+KEYWORD: value
|
|
|
|
Using `my-org-keywords' to find all keywords."
|
|
(cdr (assoc keyword (my-org-keywords))))
|
|
|
|
(defun my-org-keyword-re (KEYWORD)
|
|
"Get the value from a line like this
|
|
#+KEYWORD: value
|
|
in a buffer.
|
|
|
|
Using a case-insensitive regular expressions search in the buffer to grab the value."
|
|
(interactive)
|
|
(let ((case-fold-search t)
|
|
(re (format "^#\\+%s:[ \t]+\\([^\t\n]+\\)" KEYWORD)))
|
|
(if (not (save-excursion
|
|
(or (re-search-forward re nil t)
|
|
(re-search-backward re nil t))))
|
|
(error (format "No line containing #+%s: value found" KEYWORD)))
|
|
(match-string 1)))
|
|
|
|
(defun my-org-attr-to-list (attr)
|
|
"
|
|
ATTR is the for example (plist-get table :attr_color)
|
|
|
|
#+ATTR_MY_KEY: this and that
|
|
:attr_my_key (\"this and that\")
|
|
|
|
#+ATTR_MY_KEY: this and that
|
|
#+ATTR_MY_KEY: foo baz
|
|
:attr_my_key (\"this and that\" \"foo baz\")"
|
|
;;(split-string (car attr)) ;; this was only the first string, meaning only one (the last) attr_color line.
|
|
;;(split-string (string-join attr " ")) ;; splits on space but also inside quotes
|
|
(split-string-and-unquote (string-join attr " ")))
|
|
|
|
(defun my-org-table-get ()
|
|
"Check if cursor is inside an Org table or on #+TBLFM lines \
|
|
then return the table element otherwise return nil.
|
|
`org-at-table-p' is nil if cursor on #+TBLFM"
|
|
(let ((element (org-element-at-point))) ;; get org element
|
|
(while (and element (not (eq (car element) 'table))) ;; check if it is table
|
|
(setq element (plist-get (cadr element) :parent))) ;; if not check if parent element is table
|
|
(cond
|
|
((equal (car element) 'table) ;; only if table found
|
|
(cadr element))))) ;; return element
|
|
|
|
(defun my-org-table-range-to-list (desc &optional val)
|
|
"
|
|
Example usage:
|
|
\(my-org-table-range-to-list \"@3$1\") -> (@3$1)
|
|
\(my-org-table-range-to-list \"@3$1\" \"red\") -> (@3$1 red)
|
|
\(my-org-table-range-to-list \"@3$1..@3$3\") -> (@3$1 @3$2 @3$3)
|
|
\(my-org-table-range-to-list \"@3$1..@3$3\" \"red\") -> (@3$1 red @3$2 red @3$3 red)
|
|
|
|
Used in `my-org-table-list-of-range-to-list'"
|
|
(if (string-match-p (regexp-quote "..") desc)
|
|
(let (from-row from-column to-row to-column result)
|
|
(string-match "@\\([0-9]+\\)\$\\([0-9]+\\)\\.\\.@\\([0-9]+\\)\$\\([0-9]+\\)" desc)
|
|
(setq from-row (string-to-number (match-string 1 desc))) ;; 1st parentheses match from string-match
|
|
(setq from-column (string-to-number (match-string 2 desc))) ;; 2nd parentheses match from string-match
|
|
(setq to-row (string-to-number (match-string 3 desc))) ;; 3rd parentheses match from string-match
|
|
(setq to-column (string-to-number (match-string 4 desc))) ;; 4th parentheses match from string-match
|
|
(loop for i upfrom to-row downto from-row ;; push prepends
|
|
do
|
|
(cl-loop for j upfrom to-column downto from-column
|
|
do
|
|
(when val (push val result)) ;; push prepends
|
|
(push (concat "@" (number-to-string i) "$" (number-to-string j)) result)
|
|
))
|
|
result)
|
|
(if val (list desc val) (list desc))))
|
|
|
|
(defun my-org-table-list-of-range-to-list (seq)
|
|
"
|
|
@3$1..@3$3 red @1$3 #0055aa -> (@3$1 red @3$2 red @3$3 red @1$3 #0055aa)
|
|
|
|
Used in `my-org-table-cell-color-attr'
|
|
uses `my-org-table-range-to-list'"
|
|
(when seq
|
|
(let (result)
|
|
;;(message "%s" seq)
|
|
(while seq
|
|
(setq result
|
|
(append result
|
|
(my-org-table-range-to-list (car seq) (cadr seq))))
|
|
(setq seq (cddr seq)))
|
|
result)))
|
|
|
|
(defun my-org-table-cell-color (beg end seq)
|
|
"BEG and END are the beginning and the end of the table.
|
|
SEQ is a list of cell name and color name pairs."
|
|
(save-excursion ;; save cursor and go back to it after, important for other features
|
|
(goto-char beg) ;; go inside the table, required for org-table-analyse
|
|
(org-table-analyze) ;; required for org-table-goto-field
|
|
(ov-clear beg end)
|
|
(while seq ;; run as long elements are in list
|
|
(let* ((cell (car seq)) ;; get first "key"
|
|
(color-name (cadr seq)) ;; get first "value"
|
|
(color-rgb (color-name-to-rgb color-name))
|
|
(bg (apply #'color-rgb-to-hex color-rgb))
|
|
;;(fg (if (>= (apply #'my-color-contrast color-rgb) 4.5) "#000000" "#ffffff"))
|
|
(fg (if (>= (apply #'my-color-contrast (append color-rgb (color-name-to-rgb "gray10"))) 4.5) "gray10" "gray80"))
|
|
;;(fg (if (>= (apply #'my-color-contrast color-rgb) 4.5) "gray10" 'default))
|
|
(beg (progn (org-table-goto-field cell) (backward-char) (point))) ;; beginning of the cell
|
|
;;(end (progn (org-table-end-of-field 1) (forward-char) (point))) ;; for left aligned cells end is end of content not of cell
|
|
(end (1- (plist-get (cadr (org-element-context)) :end)))
|
|
)
|
|
(ov beg end 'face (list :background bg
|
|
:foreground fg))
|
|
(setq seq (cddr seq)))))) ;; remove first element from list
|
|
|
|
(defvar-local my-org-table-cell-color-list
|
|
nil
|
|
"Plist of table names with list of cells to color.
|
|
It is used for the function `my-org-table-cell-color-var'.
|
|
Example usage:
|
|
(my-plist-put my-org-table-cell-color-list 'table-name '(\"@23$3\" \"blue\"))
|
|
(setq my-org-table-cell-color-list '(
|
|
table-name-1 (
|
|
\"@33$3\" \"blue\"
|
|
\"@34$2\" \"red\"
|
|
\"@34$3\" \"green\"
|
|
)
|
|
table-name-2 (\"@13$3\" \"blue\" \"@14$2\" \"red\" \"@14$3\" \"green\")
|
|
))")
|
|
|
|
(defun my-org-table-cell-color-var ()
|
|
"Function to color cells.
|
|
It uses the variable `my-org-table-cell-color-list'.
|
|
Example usage to add a (normal, global) hook:
|
|
(add-hook 'org-ctrl-c-ctrl-c-hook 'my-org-table-cell-color-var)
|
|
Example usage to add a local hook:
|
|
(add-hook 'org-ctrl-c-ctrl-c-hook 'my-org-table-cell-color-var nil t)"
|
|
(let* ((table (my-org-table-get)) ;; get table element
|
|
(table-name (plist-get table :name))) ;; get table name (string)
|
|
(cond
|
|
(table-name ;; only if table found
|
|
(let ((begcont (plist-get table :contents-begin)) ;; :begin at the beginning of #+NAME:, #+ATTR_...
|
|
(endcont (plist-get table :contents-end)) ;; :end at the end of #+TBLFM: ...
|
|
(tmp-list (plist-get my-org-table-cell-color-list (intern table-name)))) ;; get value of key (string to symbol)
|
|
(my-org-table-cell-color begcont endcont tmp-list))))))
|
|
|
|
(defun my-org-table-cell-color-attr ()
|
|
"Function to color cells.
|
|
It uses the Org keyword #+ATTR_COLOR: CELL COLOR ...
|
|
COLOR is either a color name (see `list-colors-display') or a
|
|
Multiple #+ATTR_COLOR are possible. They are joint together.
|
|
Example usage to add a (normal, global) hook:
|
|
(add-hook 'org-ctrl-c-ctrl-c-hook 'my-org-table-cell-color-attr)
|
|
Example usage to add a local hook:
|
|
(add-hook 'org-ctrl-c-ctrl-c-hook 'my-org-table-cell-color-attr nil t)
|
|
Example usage
|
|
#+ATTR_COLOR: @1$3 #0055aa @1$1 #887744 @1$2 #008822
|
|
#+ATTR_COLOR: @2$3 blue @2$1 yellow @2$2 green
|
|
#+ATTR_COLOR: @3$1..@4$3 #cc0000 @5$3 red
|
|
"
|
|
(let* ((table (my-org-table-get)) ;; get table element
|
|
(table-attr (plist-get table :attr_color))) ;; nil if attr not set, table can be nil
|
|
(cond
|
|
(table-attr ;; only if table attr found
|
|
(let ((begcont (plist-get table :contents-begin)) ;; :begin at the beginning of #+NAME:, #+ATTR_...
|
|
(endcont (plist-get table :contents-end)) ;; :end at the end of #+TBLFM: ...
|
|
(color-list
|
|
(my-org-table-list-of-range-to-list
|
|
(my-org-attr-to-list table-attr))))
|
|
(my-org-table-cell-color begcont endcont color-list))))))
|
|
|
|
;; colored text in org-mode using links
|
|
;; http://kitchingroup.cheme.cmu.edu/blog/2016/01/16/Colored-text-in-org-mode-with-export-to-HTML/
|
|
;; https://en.wikibooks.org/wiki/LaTeX/Colors
|
|
;; this will be evaluated during export
|
|
(require 'ol)
|
|
(require 'color)
|
|
(require 'ov)
|
|
(org-link-set-parameters
|
|
"color"
|
|
:follow
|
|
;;(org-add-link-type
|
|
;; "color"
|
|
'(lambda (path)
|
|
"No follow action.")
|
|
:export
|
|
'(lambda (color description backend)
|
|
"if link description is empty use color as description.
|
|
[[color:COLOR][DESCRIPTION]]"
|
|
(cond
|
|
((eq backend 'html)
|
|
(let ((rgb (color-name-to-rgb color))
|
|
r g b)
|
|
(if rgb
|
|
(progn
|
|
(setq r (truncate (* 255 (nth 0 rgb))))
|
|
(setq g (truncate (* 255 (nth 1 rgb))))
|
|
(setq b (truncate (* 255 (nth 2 rgb))))
|
|
(format "<span style=\"color: rgb(%s,%s,%s)\">%s</span>"
|
|
r g b
|
|
(or description color)))
|
|
(format "No Color RGB for %s" color))))
|
|
((eq backend 'latex)
|
|
(let ((rgb (color-name-to-rgb color)))
|
|
(if rgb
|
|
(progn
|
|
(format "\\textcolor[rgb]{%s,%s,%s}{%s}"
|
|
(nth 0 rgb) (nth 1 rgb) (nth 2 rgb)
|
|
(or description color)))
|
|
(format "No Color RGB for %s" color))))
|
|
)))
|
|
(defun my-org-link-color (limit)
|
|
"Helper function for colored text in buffer.
|
|
Usage:
|
|
[[color:gray][text]]
|
|
[[color:#cccccc][text]]"
|
|
(when (re-search-forward
|
|
"color:[#0-9a-zA-Z]\\{2,\\}" limit t)
|
|
(forward-char -2)
|
|
(let ((link (org-element-context))
|
|
color beg end post-blanks)
|
|
(if link
|
|
(progn
|
|
(setq color (org-element-property :path link)
|
|
beg (org-element-property :begin link)
|
|
end (org-element-property :end link)
|
|
post-blanks (org-element-property :post-blank link))
|
|
(set-match-data
|
|
(list beg
|
|
(- end post-blanks)))
|
|
(ov-clear beg end 'color)
|
|
(ov beg
|
|
(- end post-blanks)
|
|
'color t
|
|
'face
|
|
`((:foreground ,color)))
|
|
(goto-char end))
|
|
(goto-char limit)
|
|
nil))))
|
|
(defun my-org-link-color-hook ()
|
|
"activate with e.g. (add-hook 'org-mode-hook 'my-org-link-color-hook)"
|
|
(font-lock-add-keywords
|
|
nil
|
|
'((my-org-link-color (0 'org-link t)))
|
|
t)
|
|
)
|
|
|
|
) ;; with-eval-after-load 'org
|
|
|
|
(defun my-magit-repo-status (directory branch &optional with-update as-text)
|
|
(when (featurep 'magit)
|
|
(let* ((default-directory directory)
|
|
(remotes (magit-list-remotes))
|
|
(diff))
|
|
(when (= (length remotes) 1)
|
|
(when with-update (magit-git-string "fetch" (car remotes) branch))
|
|
(let* ((remote-branch-name (concat (car remotes) "/" branch)) ;; @{u} may not configured, TODO: (if (magit-rev-parse "@{u}") ...)
|
|
(diff-count (magit-rev-diff-count "@" remote-branch-name))) ;; i.e. git rev-list @...origin/master --count --left-right
|
|
(setq diff (- (cadr diff-count) (car diff-count)))))
|
|
(if as-text
|
|
(if (= diff 0) "Up-to-date"
|
|
(if (> diff 0) "Need to pull"
|
|
"Need to push"))
|
|
diff))))
|
|
|
|
(provide 'my)
|
|
;;; my.el ends here
|