all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Carsten Dominik <carsten.dominik@gmail.com>
To: James TD Smith <ahktenzero@mohorovi.cc>
Cc: emacs-orgmode@gnu.org
Subject: Re: [PATCH] Add min/max/mean age operators to column view.
Date: Wed, 28 Oct 2009 18:01:44 +0100	[thread overview]
Message-ID: <4AD87891-4DD3-4B80-9FD3-2B6B65653E5B@gmail.com> (raw)
In-Reply-To: <1256515485-28476-1-git-send-email-ahktenzero@mohorovi.cc>

Hi James, hi everyone,

this is a reasonably complex patch - could we get some volunteers
putting this to the test?

Thanks.

- Carsten

On Oct 26, 2009, at 1:04 AM, James TD Smith wrote:

> I posted a patch to the list in July which added two new special  
> properties
> intended for displaying the age of an entry in column view. After some
> discussion with Bastien (who was maintainer at the time) we decided  
> I would
> reimplement this functionality using column summary operators. It  
> took me a
> while bit I've finally got a working version.
>
> The patch is also available in the misc-new-features branch at
> git://yog-sothoth.mohorovi.cc/org-mode.git.
>
> ---
> lisp/ChangeLog      |   38 +++++++---
> lisp/org-colview.el |  198 +++++++++++++++++++++++++++++++ 
> +-------------------
> lisp/org.el         |    4 +-
> 3 files changed, 156 insertions(+), 84 deletions(-)
>
> diff --git a/lisp/ChangeLog b/lisp/ChangeLog
> index 1b5848e..5677058 100755
> --- a/lisp/ChangeLog
> +++ b/lisp/ChangeLog
> @@ -1,3 +1,27 @@
> +2009-10-25  James TD Smith  <ahktenzero@mohorovi.cc>
> +
> +	* org-colview.el (org-format-time-period): Function to format
> +	times in fractional days for display.
> +	(org-columns-display-here): Add support for showing a calculated
> +	value in place of the property.
> +	(org-columns): Set `org-columns-time' to the current time so time
> +	difference calculations will work.
> +	(org-columns-time): Use to store the current time when column view
> +	is displayed, so all time differences will use the same reference
> +	point.
> +	(org-columns-compile-map): There is now an extra position in each
> +	entry specifying the function to use to calculate the displayed
> +	value for the non-calculated properties in the column,
> +	(org-columns-compute-all): Set `org-columns-time' to the current
> +	time so time difference calculations will work.
> +	(org-columns-compute): Handle column operators where the values
> +	used are calculated from the underlying property.
> +	(org-columns-number-to-string): Handle the 'age' column format
> +	(org-columns-string-to-number): Correct the function name (was
> +	org-column...). Add support for the 'age' column format.
> +	(org-columns-compile-format): Support the additional parameter in
> +	org-columns-compile-map.
> +
> 2009-10-25  Carsten Dominik  <carsten.dominik@gmail.com>
>
> 	* org-clock.el (org-clock-has-been-used): New variable.
> @@ -1543,20 +1567,14 @@
> 	* org-exp.el (org-export-format-source-code-or-example): Fix
> 	bad line numbering when exporting examples in HTML.
>
> -2009-07-12  James TD Smith  <ahktenzero@mohorovi.cc>
> -
> 	* org-colview.el (org-format-time-period): Formats a time in
> 	fractional days as days, hours, mins, seconds.
> 	(org-columns-display-here): Add special handling for SINCE and
> 	SINCE_IA to format for display.
>
> -	* org.el (org-time-since): Add a function to get the time since an
> -	org timestamp.
> -	(org-entry-properties): Add two new special properties: SINCE and
> -	SINCE_IA. These give the time since any active or inactive
> -	timestamp in an entry.
> -	(org-special-properties): Add SINCE, SINCE_IA.
> -	(org-tags-sort-function): Add custom declaration for tags
> +2009-07-12  James TD Smith  <ahktenzero@mohorovi.cc>
> +
> +	* org.el (org-tags-sort-function): Add custom declaration for tags
> 	sorting function.
> 	(org-set-tags): Sort tags if org-tags-sort-function is set
>
> @@ -4423,7 +4441,7 @@
> 	(org-agenda-change-all-lines, org-tags-sparse-tree)
> 	(org-time-string-to-absolute, org-small-year-to-year)
> 	(org-link-escape): Re-apply changes accidentially overwritten
> -	by last commit to Emacs.
> +	by last commit to Emacs
>
> 2008-11-23  Carsten Dominik  <carsten.dominik@gmail.com>
>
> diff --git a/lisp/org-colview.el b/lisp/org-colview.el
> index 374d22a..87c1412 100644
> --- a/lisp/org-colview.el
> +++ b/lisp/org-colview.el
> @@ -111,8 +111,8 @@ This is the compiled version of the format.")
> (org-defkey org-columns-map [(shift meta left)] 'org-columns-delete)
> (dotimes (i 10)
>   (org-defkey org-columns-map (number-to-string i)
> -              `(lambda () (interactive)
> -                 (org-columns-next-allowed-value nil ,i))))
> +	      `(lambda () (interactive)
> +		 (org-columns-next-allowed-value nil ,i))))
>
> (easy-menu-define org-columns-menu org-columns-map "Org Column Menu"
>   '("Column"
> @@ -165,7 +165,7 @@ This is the compiled version of the format.")
> 	 (face1 (list color 'org-agenda-column-dateline ref-face))
> 	 (pl (or (get-text-property (point-at-bol) 'prefix-length) 0))
> 	 (cphr (get-text-property (point-at-bol) 'org-complex-heading- 
> regexp))
> -	 pom property ass width f string ov column val modval s2 title)
> +	 pom property ass width f string ov column val modval s2 title calc)
>     ;; Check if the entry is in another buffer.
>     (unless props
>       (if (eq major-mode 'org-agenda-mode)
> @@ -189,19 +189,25 @@ This is the compiled version of the format.")
> 		      (nth 2 column)
> 		      (length property))
> 	    f (format "%%-%d.%ds | " width width)
> +	    calc (nth 7 column)
> 	    val (or (cdr ass) "")
> -	    modval (or (and org-columns-modify-value-for-display-function
> -			    (functionp
> -			     org-columns-modify-value-for-display-function)
> -			    (funcall
> -			     org-columns-modify-value-for-display-function
> -			     title val))
> -		       (if (equal property "ITEM")
> -			   (if (org-mode-p)
> -			       (org-columns-cleanup-item
> -				val org-columns-current-fmt-compiled)
> -			     (org-agenda-columns-cleanup-item
> -			      val pl cphr org-columns-current-fmt-compiled)))))
> +	    modval (cond ((and org-columns-modify-value-for-display-function
> +			       (functionp
> +				org-columns-modify-value-for-display-function))
> +			  (funcall org-columns-modify-value-for-display-function
> +				   title val))
> +			 ((equal property "ITEM")
> +			  (if (org-mode-p)
> +			      (org-columns-cleanup-item
> +			       val org-columns-current-fmt-compiled)
> +			    (org-agenda-columns-cleanup-item
> +			     val pl cphr org-columns-current-fmt-compiled)))
> +			 ((and calc (functionp calc)
> +			       (not (get-text-property 0 'org-computed val)))
> +			  (org-columns-number-to-string
> +			   (funcall calc (org-columns-string-to-number
> +					  val (nth 4 column)))
> +			   (nth 4 column)))))
>       (setq s2 (org-columns-add-ellipses (or modval val) width))
>       (setq string (format f s2))
>       ;; Create the overlay
> @@ -220,18 +226,18 @@ This is the compiled version of the format.")
> 	    (save-excursion
> 	      (goto-char beg)
> 	      (org-unmodified (insert " ")))))) ;; FIXME: add props and  
> remove later?
> -    ;; Make the rest of the line disappear.
> -    (org-unmodified
> -     (setq ov (org-columns-new-overlay beg (point-at-eol)))
> -     (org-overlay-put ov 'invisible t)
> -     (org-overlay-put ov 'keymap org-columns-map)
> -     (org-overlay-put ov 'intangible t)
> -     (push ov org-columns-overlays)
> -     (setq ov (org-make-overlay (1- (point-at-eol)) (1+ (point-at- 
> eol))))
> -     (org-overlay-put ov 'keymap org-columns-map)
> -     (push ov org-columns-overlays)
> -     (let ((inhibit-read-only t))
> -       (put-text-property (max (point-min) (1- (point-at-bol)))
> +      ;; Make the rest of the line disappear.
> +      (org-unmodified
> +       (setq ov (org-columns-new-overlay beg (point-at-eol)))
> +       (org-overlay-put ov 'invisible t)
> +       (org-overlay-put ov 'keymap org-columns-map)
> +       (org-overlay-put ov 'intangible t)
> +       (push ov org-columns-overlays)
> +       (setq ov (org-make-overlay (1- (point-at-eol)) (1+ (point-at- 
> eol))))
> +       (org-overlay-put ov 'keymap org-columns-map)
> +       (push ov org-columns-overlays)
> +       (let ((inhibit-read-only t))
> +	 (put-text-property (max (point-min) (1- (point-at-bol)))
> 			  (min (point-max) (1+ (point-at-eol)))
> 			  'read-only "Type `e' to edit property")))))
>
> @@ -257,6 +263,7 @@ for the duration of the command.")
>
> (defvar header-line-format)
> (defvar org-columns-previous-hscroll 0)
> +
> (defun org-columns-display-here-title ()
>   "Overlay the newline before the current line with the table title."
>   (interactive)
> @@ -347,6 +354,7 @@ for the duration of the command.")
>   s)
>
> (defvar org-agenda-columns-remove-prefix-from-item)
> +
> (defun org-agenda-columns-cleanup-item (item pl cphr fmt)
>   "Cleanup the time property for agenda column view.
> See also the variable `org-agenda-columns-remove-prefix-from-item'."
> @@ -366,6 +374,7 @@ See also the variable `org-agenda-columns-remove- 
> prefix-from-item'."
>     (message "Value is: %s" (or value ""))))
>
> (defvar org-agenda-columns-active) ;; defined in org-agenda.el
> +
> (defun org-columns-quit ()
>   "Remove the column overlays and in this way exit column editing."
>   (interactive)
> @@ -417,6 +426,7 @@ Where possible, use the standard interface for  
> changing this line."
> 				   (<= (overlay-start x) eol)
> 				   x))
> 			    org-columns-overlays)))
> +	 (org-columns-time (time-to-number-of-days (current-time)))
> 	 nval eval allowed)
>     (cond
>      ((equal key "CLOCKSUM")
> @@ -661,7 +671,8 @@ around it."
>   (org-verify-version 'columns)
>   (org-columns-remove-overlays)
>   (move-marker org-columns-begin-marker (point))
> -  (let (beg end fmt cache maxwidths)
> +  (let ((org-columns-time (time-to-number-of-days (current-time)))
> +	beg end fmt cache maxwidths)
>     (setq fmt (org-columns-get-format-and-top-level))
>     (save-excursion
>       (goto-char org-columns-top-level-marker)
> @@ -678,7 +689,7 @@ around it."
> 	    (narrow-to-region beg end)
> 	    (org-clock-sum))))
>       (while (re-search-forward (concat "^" outline-regexp) end t)
> -	(if (and org-columns-skip-arrchived-trees
> +	(if (and org-columns-skip-archived-trees
> 		 (looking-at (concat ".*:" org-archive-tag ":")))
> 	    (org-end-of-subtree t)
> 	  (push (cons (org-current-line) (org-entry-properties)) cache)))
> @@ -698,20 +709,34 @@ around it."
> 		(org-columns-display-here (cdr x)))
> 	      cache)))))
>
> +(eval-when-compile (defvar org-columns-time))
> +
> (defvar org-columns-compile-map
> -  '(("none"  none              +)
> -    (":"     add_times         +)
> -    ("+"     add_numbers       +)
> -    ("$"     currency          +)
> -    ("X"     checkbox          +)
> -    ("X/"    checkbox-n-of-m   +)
> -    ("X%"    checkbox-percent  +)
> -    ("max"   max_numbers       max)
> -    ("min"   min_numbers       min)
> -    ("mean"  mean_numbers      (lambda (&rest x) (/ (apply '+ x)  
> (float (length x)))))
> -    (":max"  max_times         max)
> -    (":min"  min_times         min)
> -    (":mean" mean_times        (lambda (&rest x) (/ (apply '+ x)  
> (float (length x))))))
> +  '(("none" none + identity)
> +    (":" add_times + identity)
> +    ("+" add_numbers + identity)
> +    ("$" currency + identity)
> +    ("X" checkbox + identity)
> +    ("X/" checkbox-n-of-m + identity)
> +    ("X%" checkbox-percent + identity)
> +    ("max" max_numbers max identity)
> +    ("min" min_numbers min identity)
> +    ("mean" mean_numbers
> +     (lambda (&rest x) (/ (apply '+ x) (float (length x))))
> +     identity)
> +    (":max" max_times max identity)
> +    (":min" min_times min identity)
> +    (":mean" mean_times
> +     (lambda (&rest x) (/ (apply '+ x) (float (length x))))
> +     identity)
> +    ("@min" age min
> +     (lambda (x) (- org-columns-time x)))
> +    ("@max" age max
> +     (lambda (x) (- org-columns-time x)))
> +    ("@mean" age
> +     (lambda (&rest x)
> +       (/ (apply '+ x) (float (length x))))
> +     (lambda (x) (- org-columns-time x)))))
>   "Operator <-> format,function map.
> Used to compile/uncompile columns format and completing read in
> interactive function org-columns-new.")
> @@ -860,7 +885,9 @@ Don't set this, this is meant for dynamic  
> scoping.")
>   "Compute all columns that have operators defined."
>   (org-unmodified
>    (remove-text-properties (point-min) (point-max) '(org-summaries  
> t)))
> -  (let ((columns org-columns-current-fmt-compiled) col)
> +  (let ((columns org-columns-current-fmt-compiled)
> +	(org-columns-time (time-to-number-of-days (current-time)))
> +	col)
>     (while (setq col (pop columns))
>       (when (nth 3 col)
> 	(save-excursion
> @@ -895,6 +922,7 @@ Don't set this, this is meant for dynamic  
> scoping.")
> 	 (format (nth 4 ass))
> 	 (printf (nth 5 ass))
> 	 (fun (nth 6 ass))
> +	 (calc (or (nth 7 ass) 'identity))
> 	 (beg org-columns-top-level-marker)
> 	 last-level val valflag flag end sumpos sum-alist sum str str1  
> useval)
>     (save-excursion
> @@ -927,10 +955,12 @@ Don't set this, this is meant for dynamic  
> scoping.")
> 				  (list 'org-summaries sum-alist))))
> 	  (when (and val (not (equal val (if flag str val))))
> 	    (org-entry-put nil property (if flag str val)))
> -	  ;; add current to current  level accumulator
> +	  ;; add current to current level accumulator
> 	  (when (or flag valflag)
> -	    (push (if flag sum
> -		    (org-column-string-to-number (if flag str val) format))
> +	    (push (if flag
> +		      sum
> +		    (funcall calc (org-columns-string-to-number
> +				   (if flag str val) format)))
> 		  (aref lvals level))
> 	    (aset lflag level t))
> 	  ;; clear accumulators for deeper levels
> @@ -940,8 +970,8 @@ Don't set this, this is meant for dynamic  
> scoping.")
> 	 ((>= level last-level)
> 	  ;; add what we have here to the accumulator for this level
> 	  (when valflag
> -	    (push (org-column-string-to-number val format)
> -		(aref lvals level))
> +	    (push (funcall calc (org-columns-string-to-number val format))
> +		  (aref lvals level))
> 	    (aset lflag level t)))
> 	 (t (error "This should not happen")))))))
>
> @@ -967,7 +997,6 @@ Don't set this, this is meant for dynamic  
> scoping.")
>   (if (eq major-mode 'org-agenda-mode)
>       (error "This command is only allowed in Org-mode buffers")))
>
> -
> (defun org-string-to-number (s)
>   "Convert string to number, and interpret hh:mm:ss."
>   (if (not (string-match ":" s))
> @@ -994,6 +1023,8 @@ Don't set this, this is meant for dynamic  
> scoping.")
>    (printf (format printf n))
>    ((eq fmt 'currency)
>     (format "%.2f" n))
> +   ((eq fmt 'age)
> +    (org-format-time-period n))
>    (t (number-to-string n))))
>
> (defun org-nofm-to-completion (n m &optional percent)
> @@ -1001,17 +1032,23 @@ Don't set this, this is meant for dynamic  
> scoping.")
>       (format "[%d/%d]" n m)
>     (format "[%d%%]"(floor (+ 0.5 (* 100. (/ (* 1.0 n) m)))))))
>
> -(defun org-column-string-to-number (s fmt)
> +(defun org-columns-string-to-number (s fmt)
>   "Convert a column value to a number that can be used for column  
> computing."
> -  (cond
> -   ((string-match ":" s)
> -    (let ((l (nreverse (org-split-string s ":"))) (sum 0.0))
> -      (while l
> -	(setq sum (+ (string-to-number (pop l)) (/ sum 60))))
> -      sum))
> -   ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent))
> -    (if (equal s "[X]") 1. 0.000001))
> -   (t (string-to-number s))))
> +  (if s
> +      (cond
> +       ((eq fmt 'age)
> +	(if (string= s "")
> +	    org-columns-time
> +	  (time-to-number-of-days (apply 'encode-time (org-parse-time- 
> string s t)))))
> +       ((string-match ":" s)
> +	(let ((l (nreverse (org-split-string s ":"))) (sum 0.0))
> +	  (while l
> +	    (setq sum (+ (string-to-number (pop l)) (/ sum 60))))
> +	  sum))
> +       ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent))
> +	(if (equal s "[X]") 1. 0.000001))
> +       (t (string-to-number s)))
> +    0))
>
> (defun org-columns-uncompile-format (cfmt)
>   "Turn the compiled columns format back into a string  
> representation."
> @@ -1045,7 +1082,9 @@ width        the column width in characters,  
> can be nil for automatic
> operator     the operator if any
> format       the output format for computed results, derived from  
> operator
> printf       a printf format for computed values
> -fun          the lisp function to compute values, derived from  
> operator"
> +fun          the lisp function to compute summary values, derived  
> from operator
> +calc         function to get values from base elements
> +"
>   (let ((start 0) width prop title op op-match f printf fun)
>     (setq org-columns-current-fmt-compiled nil)
>     (while (string-match
> @@ -1058,15 +1097,18 @@ fun          the lisp function to compute  
> values, derived from operator"
> 	    op (match-string 4 fmt)
> 	    f nil
> 	    printf nil
> -	    fun '+)
> +	    fun '+
> +	    calc nil)
>       (if width (setq width (string-to-number width)))
>       (when (and op (string-match ";" op))
> 	(setq printf (substring op (match-end 0))
> 	      op (substring op 0 (match-beginning 0))))
>       (when (setq op-match (assoc op org-columns-compile-map))
> 	(setq f (cadr op-match)
> -	      fun (caddr op-match)))
> -      (push (list prop title width op f printf fun) org-columns- 
> current-fmt-compiled))
> +	      fun (caddr op-match)
> +	      calc (cadddr op-match)))
> +      (push (list prop title width op f printf fun calc)
> +	    org-columns-current-fmt-compiled))
>     (setq org-columns-current-fmt-compiled
> 	  (nreverse org-columns-current-fmt-compiled))))
>
> @@ -1121,18 +1163,18 @@ PARAMS is a property list of parameters:
>
> :width    enforce same column widths with <N> specifiers.
> :id       the :ID: property of the entry where the columns view
> -          should be built.  When the symbol `local', call locally.
> -          When `global' call column view with the cursor at the  
> beginning
> -          of the buffer (usually this means that the whole buffer  
> switches
> -          to column view).  When \"file:path/to/file.org\", invoke  
> column
> -          view at the start of that file.  Otherwise, the ID is  
> located
> -          using `org-id-find'.
> +	  should be built.  When the symbol `local', call locally.
> +	  When `global' call column view with the cursor at the beginning
> +	  of the buffer (usually this means that the whole buffer switches
> +	  to column view).  When \"file:path/to/file.org\", invoke column
> +	  view at the start of that file.  Otherwise, the ID is located
> +	  using `org-id-find'.
> :hlines   When t, insert a hline before each item.  When a number,  
> insert
> -          a hline before each level <= that number.
> +	  a hline before each level <= that number.
> :vlines   When t, make each column a colgroup to enforce vertical  
> lines.
> :maxlevel When set to a number, don't capture headlines below this  
> level.
> :skip-empty-rows
> -          When t, skip rows where all specifiers other than ITEM  
> are empty."
> +	  When t, skip rows where all specifiers other than ITEM are empty."
>   (let ((pos (move-marker (make-marker) (point)))
> 	(hlines (plist-get params :hlines))
> 	(vlines (plist-get params :vlines))
> @@ -1351,7 +1393,7 @@ This will add overlays to the date lines, to  
> show the summary for each day."
> 			 (mapc (lambda (x)
> 				 (setq v (cdr (assoc prop x)))
> 				 (if v (setq lsum (+ lsum
> -						     (org-column-string-to-number
> +						     (org-columns-string-to-number
> 						      v stype)))))
> 			       entries)
> 			 (setq lsum (org-columns-number-to-string lsum stype))
> @@ -1390,6 +1432,18 @@ This will add overlays to the date lines, to  
> show the summary for each day."
> 			   (equal (nth 4 a) (nth 4 fm)))
> 		  (org-columns-compute (car fm)))))))))))
>
> +(defun org-format-time-period (interval)
> +  "Convert time in fractional days to days/hours/minutes/seconds"
> +  (if (numberp interval)
> +    (let* ((days (floor interval))
> +	   (frac-hours (* 24 (- interval days)))
> +	   (hours (floor frac-hours))
> +	   (minutes (floor (* 60 (- frac-hours hours))))
> +	   (seconds (floor (* 60 (- (* 60 (- frac-hours hours)) minutes)))))
> +      (format "%dd %02dh %02dm %02ds" days hours minutes seconds))
> +    ""))
> +
> +
> (provide 'org-colview)
>
> ;; arch-tag: 61f5128d-747c-4983-9479-e3871fa3d73c
> diff --git a/lisp/org.el b/lisp/org.el
> index dad2e83..24907d8 100644
> --- a/lisp/org.el
> +++ b/lisp/org.el
> @@ -3346,8 +3346,8 @@ Instead, use the key `v' to cycle the archives- 
> mode in the agenda."
>   :group 'org-agenda-skip
>   :type 'boolean)
>
> -(defcustom org-columns-skip-arrchived-trees t
> -  "Non-nil means, irgnore archived trees when creating column view."
> +(defcustom org-columns-skip-archived-trees t
> +  "Non-nil means, ignore archived trees when creating column view."
>   :group 'org-archive
>   :group 'org-properties
>   :type 'boolean)
> --
> 1.6.3.3
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

- Carsten

  reply	other threads:[~2009-10-28 17:01 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-26  0:04 [PATCH] Add min/max/mean age operators to column view James TD Smith
2009-10-28 17:01 ` Carsten Dominik [this message]
2009-10-28 19:36   ` James TD Smith
2009-10-29 11:12     ` Mikael Fornius
2009-10-29 13:17       ` Mikael Fornius
2009-10-29 20:10         ` Mikael Fornius
2009-10-30  3:36           ` James TD Smith
2009-10-29 21:15         ` James TD Smith
2009-10-31 13:41           ` Mikael Fornius
2009-11-01 17:24             ` Carsten Dominik
2009-11-01 18:59               ` James TD Smith
2009-12-30 11:32                 ` Manish
2009-12-30 14:01                   ` James TD Smith

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4AD87891-4DD3-4B80-9FD3-2B6B65653E5B@gmail.com \
    --to=carsten.dominik@gmail.com \
    --cc=ahktenzero@mohorovi.cc \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.