[O] (no subject)

2015-10-11 Thread Shankar Rao
I have multiple savings accounts, some of which I want to partition into
mutiple virtual "subaccounts" that don't merit their own savings account. I
want to use org-mode tables to keep track how much money is each
subaccount. Given the following table:

#+TBLNAME: trans-150925
| ! | Amount | From   | To | Subacct |
|---++++-|
|   | 50 | Short Term | Inbox  | Bond|
|   |200 | Inbox  | Short Term | Bond|
|   |120 | Gifts  | Inbox  | Baby Gifts  |
|   | 75 | Short Term | Inbox  | Furnishings |

In this example, I have accounts "Inbox", "Short Term", and "Gifts". Of
these accounts, "Short Term" has two subaccounts "Bond" and "Furnishings",
and "Gifts" has a subaccount "Baby Gifts". I want to create a function that
given a subaccount name, calculates the net amount to be
withdrawn/deposited to the subaccount. Note that "Inbox" doesn't have any
subaccounts, which I want to use to determine if a given transaction is a
withdrawal or deposit to the subaccount.

I have created the following two functions to implement this:

(defun sbr/org-lookup-trans (category date s-name r-name)
  (let* ((table (concat "trans-" date))
 (s-range (format "@I%s..@>%s" s-name s-name))
 (s-col (org-table-get-remote table s-range))
 (r-range (format "@I%s..@>%s" r-name r-name))
 (r-col (org-table-get-remote table r-range)))
(org-lookup-all category s-col r-col)))

(defun sbr/get-net-subacct (category date)
  (let* ((from-vec (sbr/org-lookup-trans category date "$Subacct" "$From"))
  (to-vec (sbr/org-lookup-trans category date "$Subacct" "$To"))
 (amount-vec (sbr/org-lookup-trans category date "$Subacct"
"$Amount"))
 (from-inbox-ind ) ; A
   (to-inbox-ind  )
; B
   (adds amount-vec[from-inbox-ind]) ; C
   (subs amount-vec[to-inbox-ind]))  ; D
(calc-eval (if (zerop (length subs))
 adds
 (concat adds "-" subs)

I need help filling in the pseudo code in lines A through D, namely:

1. how to get a list of all indices of elements in a vector that satisfy a
predicate?
2. how to reference a vector by a list of indices?

In this example the function should return the following values:

(sbr/get-net-subacct "Bond" "150925") ==> 150
(sbr/get-net-subacct "Furnishings" "150925") ==> -75
(sbr/get-net-subacct "Baby Gifts" "150925") ==> -120

How do I implement the above pseudocode functions? Is there a simpler way
to accomplish this task?


Re: [O] How to cross reference more than two table columns?

2015-10-11 Thread Shankar Rao
Sorry forgot to put in a subject

On Sun, Oct 11, 2015 at 12:51 PM, Shankar Rao  wrote:

> I have multiple savings accounts, some of which I want to partition into
> mutiple virtual "subaccounts" that don't merit their own savings account. I
> want to use org-mode tables to keep track how much money is each
> subaccount. Given the following table:
>
> #+TBLNAME: trans-150925
> | ! | Amount | From   | To | Subacct |
> |---++++-|
> |   | 50 | Short Term | Inbox  | Bond|
> |   |200 | Inbox  | Short Term | Bond|
> |   |120 | Gifts  | Inbox  | Baby Gifts  |
> |   | 75 | Short Term | Inbox  | Furnishings |
>
> In this example, I have accounts "Inbox", "Short Term", and "Gifts". Of
> these accounts, "Short Term" has two subaccounts "Bond" and "Furnishings",
> and "Gifts" has a subaccount "Baby Gifts". I want to create a function that
> given a subaccount name, calculates the net amount to be
> withdrawn/deposited to the subaccount. Note that "Inbox" doesn't have any
> subaccounts, which I want to use to determine if a given transaction is a
> withdrawal or deposit to the subaccount.
>
> I have created the following two functions to implement this:
>
> (defun sbr/org-lookup-trans (category date s-name r-name)
>   (let* ((table (concat "trans-" date))
>  (s-range (format "@I%s..@>%s" s-name s-name))
>  (s-col (org-table-get-remote table s-range))
>  (r-range (format "@I%s..@>%s" r-name r-name))
>  (r-col (org-table-get-remote table r-range)))
> (org-lookup-all category s-col r-col)))
>
> (defun sbr/get-net-subacct (category date)
>   (let* ((from-vec (sbr/org-lookup-trans category date "$Subacct" "$From"))
>   (to-vec (sbr/org-lookup-trans category date "$Subacct" "$To"))
>  (amount-vec (sbr/org-lookup-trans category date "$Subacct"
> "$Amount"))
>  (from-inbox-ind  "Inbox">) ; A
>(to-inbox-ind   "Inbox">) ; B
>(adds amount-vec[from-inbox-ind]) ; C
>(subs amount-vec[to-inbox-ind]))  ; D
> (calc-eval (if (zerop (length subs))
>  adds
>  (concat adds "-" subs)
>
> I need help filling in the pseudo code in lines A through D, namely:
>
> 1. how to get a list of all indices of elements in a vector that satisfy a
> predicate?
> 2. how to reference a vector by a list of indices?
>
> In this example the function should return the following values:
>
> (sbr/get-net-subacct "Bond" "150925") ==> 150
> (sbr/get-net-subacct "Furnishings" "150925") ==> -75
> (sbr/get-net-subacct "Baby Gifts" "150925") ==> -120
>
> How do I implement the above pseudocode functions? Is there a simpler way
> to accomplish this task?
>


Re: [O] Recursive formulaes in org-mode tables

2015-10-13 Thread Shankar Rao
I posted the following on Stack Overflow:

I recommend using the following range formula:

| Year (Beginn) |Price | Increase |
|---+--+--|
|  2016 | 2.00 |  1000.00 |
|  2017 |  |  1000.00 |
|  2018 |  |  1000.00 |
|  2019 |  |  1000.00 |
|  2020 |  |  1000.00 |
|  2021 |  |  1000.00 |
|  2022 |  |  1000.00 |
|  2023 |  |  1000.00 |
|  2024 |  |  1000.00 |
|  2025 |  |  1000.00 |
|  2026 |  |  1000.00 |
|  2027 |  |  1000.00 |
|  2028 |  |  1000.00 |
|  2029 |  |  1000.00 |
|  2030 |  |  1000.00 |
|---+--+--|
#+TBLFM: @<<<$2..@>$2=@<<$0+2*vsum(@<<$3..@-1$3);%.2f

You could write a recursive formula, but that would propagate one row at a
time. Even org-table-iterate (C-u C-u C-c * on any table cell) would have
to be called more than once, since it stops after 10 iterations.

Shankar Rao



On Tue, Oct 13, 2015 at 8:35 AM,  wrote:

> Hi,
>
> I have the following table:
>
> | Year (Beginn) |Price | Increase |
> |---+--+--|
> |  2016 | 2.00 |  1000.00 |
> |  2017 |  |  1000.00 |
> |  2018 |  |  1000.00 |
> |  2019 |  |  1000.00 |
> |  2020 |  |  1000.00 |
> |  2021 |  |  1000.00 |
> |  2022 |  |  1000.00 |
> |  2023 |  |  1000.00 |
> |  2024 |  |  1000.00 |
> |  2025 |  |  1000.00 |
> |  2026 |  |  1000.00 |
> |  2027 |  |  1000.00 |
> |  2028 |  |  1000.00 |
> |  2029 |  |  1000.00 |
> |  2030 |  |  1000.00 |
> |---+--+--|
>
> I want to compute the price recursively such that the final table looks
> like this:
>
> | Year (Beginn) |Price | Increase |
> |---+--+--|
> |  2016 | 2.00 |  1000.00 |
> |  2017 | 22000.00 |  1000.00 |
> |  2018 | 24000.00 |  1000.00 |
> |  2019 | 26000.00 |  1000.00 |
> |  2020 | 28000.00 |  1000.00 |
> |  2021 | 3.00 |  1000.00 |
> |  2022 | 32000.00 |  1000.00 |
> |  2023 | 34000.00 |  1000.00 |
> |  2024 | 36000.00 |  1000.00 |
> |  2025 | 38000.00 |  1000.00 |
> |  2026 | 4.00 |  1000.00 |
> |  2027 | 42000.00 |  1000.00 |
> |  2028 | 44000.00 |  1000.00 |
> |  2029 | 46000.00 |  1000.00 |
> |  2030 | 48000.00 |  1000.00 |
> |---+--+--|
> After reading a related SO question I tried the formula
>
> #+TBLFM: @<<<..>$2=@<<..>>$2+2*$3
>
> but it doesn't work. It gives an error and also seems to operate on
> column one instead of the specified column two. Any idea how to
> correctly compute column two? I am using org-mode version 8.2.5c with
> Emacs version 24.5.1.
>
> Disclaimer: I posted this question also on Stack Overflow:
>
>
> http://stackoverflow.com/questions/33063425/recursive-formulaes-in-org-mode-tables
>
> Feel free to answer here or there.
>
> Thanks!
>
> Best,
> Michael
>
>
>


[O] Show first leaf heading on startup

2015-10-19 Thread Shankar Rao
If I have the following org document:

* Heading A
** Subheading AA
*** Subsubheading AAA
Stuff about topic AAA
*** Subsubheading AAB
Stuff about topic AAB
** Subheading AB
*** Subheading ABA
Stuff about topic ABA
*** Subheading ABB
Stuff about topic ABB
* Heading B
** Subheading BA
*** Subheading BAA
Stuff about topic BAA

How can I make it so that on startup, only the content of the first "leaf"
heading is revealed, so that the document looks like:

* Heading A
** Subheading AA
*** Subsubheading AAA
Stuff about topic AAA
*** Subsubheading AAB ...
** Subheading AB ...
* Heading B ...

Shankar Rao


[O] insert aligned table using capture template

2015-11-03 Thread Shankar Rao
I'm trying to use to org-capture insert tables into a datetree that I use
to manage my finances. Below is the capture template I set up for it. Is
there a way to make the table be aligned after I finalize the capture?

Shankar

-

(setq org-capture-templates
   '(...
("f" "Add Tables" plain
(file+datetree+prompt "~/my-table-file.org")
 ,(concat "#+TBLNAME: accounts-%<%y%m%d>\n"
  "| Account | Initial | Final | Calculations |\n"
  "|-\n"
  "| Account A | | | |\n"
  "| Account B | | | |\n"
  "| Account C | | | |\n")
:immediate-finish t
:jump-to-captured t)
...))


Re: [O] insert aligned table using capture template

2015-11-03 Thread Shankar Rao
Oops.

(set org-capture-templates '(...

should be

(set org-capture-templates `(...



On Tue, Nov 3, 2015 at 12:28 PM, Nick Dokos  wrote:

> Shankar Rao  writes:
>
> > I'm trying to use to org-capture insert tables into a datetree that I
> use to manage my finances. Below is the capture template I set up for it.
> Is there a way to make the table be aligned
> > after I finalize the capture?
> >
> > Shankar
> >
> > -
> >
> > (setq org-capture-templates
> >'(...
> > ("f" "Add Tables" plain
> > (file+datetree+prompt "~/my-table-file.org")
> >  ,(concat "#+TBLNAME: accounts-%<%y%m%d>\n"
> >   "| Account | Initial | Final | Calculations |\n"
> >   "|-\n"
> >   "| Account A | | | |\n"
> >   "| Account B | | | |\n"
> >   "| Account C | | | |\n")
> > :immediate-finish t
> > :jump-to-captured t)
> > ...))
>
> The ,(concat ...) stuff did not work for me: is is supposed to? I get
> "invalid capture template".
>
> Be that as it may, you can do this (maybe with more safeguards):
>
> --8<---cut here---start->8---
> (add-hook 'org-capture-prepare-finalize-hook (function
> my-capture-table-align))
>
> (defun my-capture-table-align ()
>   (forward-line 1) ;; skip the #+name line
>   (if (org-at-table-p 'any)
>   (org-table-align)))
> --8<---cut here---end--->8---
>
> --
> Nick
>
>
>


[O] org-capture-template: file+datetree+prompt not using prompted date in template

2015-11-04 Thread Shankar Rao
For the following org capture template:

(setq org-capture-templates
  '(("d" "Date Tree Test" plain
(file+datetree+prompt "~/org/testdt.org")
"This date should be the date i picked: %<%y%m%d>")))

Though this is filed under the correct date in the datetree, no matter what
date I select in the prompt, the date displayed in the template is the
current date. Is this a bug or a feature?

How do I use the prompt-selected date in the template?

Shankar


Re: [O] org-capture-template: file+datetree+prompt not using prompted date in template

2015-11-04 Thread Shankar Rao
Earlier in org-capture-fill-template, there is the following:

(let* (...
   (ct (org-capture-get :default-time))
   ...

The property :default-time defaults to the current time and is overwritten
by file+datetree+prompt,

If ct was passed as a 2nd argument to format-time-string in your code
snippet:

  ;; The current time
  (goto-char (point-min))
  (while (re-search-forward "%<\\([^>\n]+\\)>" nil t)
(replace-match (format-time-string (match-string 1) ct) t t))

this should provide the behavior I'm looking for with file+datetree+prompt,
but still use the current time for other capture types. Will this solution
break anything?

Shankar

On Wed, Nov 4, 2015 at 2:15 PM, Nick Dokos  wrote:

> Shankar Rao  writes:
>
> > For the following org capture template:
> >
> > (setq org-capture-templates
> >   '(("d" "Date Tree Test" plain
> > (file+datetree+prompt "~/org/testdt.org")
> > "This date should be the date i picked: %<%y%m%d>")))
> >
> > Though this is filed under the correct date in the datetree, no matter
> what date I select in the prompt,
> > the date displayed in the template is the current date. Is this a bug or
> a feature?
> >
>
> It's a feature I guess - org-capture.el says:
>
>   ;; The current time
>   (goto-char (point-min))
>   (while (re-search-forward "%<\\([^>\n]+\\)>" nil t)
> (replace-match (format-time-string (match-string 1)) t t))
>
> and there is no provision for another time to be given here. I don't
> think there is any provision in the template for a time other than the
> current time: at least I can't see a %-escape that takes a different
> time.
>
> --
> Nick
>
>
>


Re: [O] org-capture-template: file+datetree+prompt not using prompted date in template

2015-11-04 Thread Shankar Rao
Looks like a similar issue was addressed earlier here:

http://sachachua.com/blog/2015/02/org-mode-reusing-date-file-datetree-prompt/

Shankar

On Wed, Nov 4, 2015 at 2:54 PM, Shankar Rao  wrote:

> Earlier in org-capture-fill-template, there is the following:
>
> (let* (...
>(ct (org-capture-get :default-time))
>...
>
> The property :default-time defaults to the current time and is overwritten
> by file+datetree+prompt,
>
> If ct was passed as a 2nd argument to format-time-string in your code
> snippet:
>
>   ;; The current time
>   (goto-char (point-min))
>   (while (re-search-forward "%<\\([^>\n]+\\)>" nil t)
> (replace-match (format-time-string (match-string 1) ct) t t))
>
> this should provide the behavior I'm looking for with
> file+datetree+prompt, but still use the current time for other capture
> types. Will this solution break anything?
>
> Shankar
>
> On Wed, Nov 4, 2015 at 2:15 PM, Nick Dokos  wrote:
>
>> Shankar Rao  writes:
>>
>> > For the following org capture template:
>> >
>> > (setq org-capture-templates
>> >   '(("d" "Date Tree Test" plain
>> > (file+datetree+prompt "~/org/testdt.org")
>> > "This date should be the date i picked: %<%y%m%d>")))
>> >
>> > Though this is filed under the correct date in the datetree, no matter
>> what date I select in the prompt,
>> > the date displayed in the template is the current date. Is this a bug
>> or a feature?
>> >
>>
>> It's a feature I guess - org-capture.el says:
>>
>>   ;; The current time
>>   (goto-char (point-min))
>>   (while (re-search-forward "%<\\([^>\n]+\\)>" nil t)
>> (replace-match (format-time-string (match-string 1)) t t))
>>
>> and there is no provision for another time to be given here. I don't
>> think there is any provision in the template for a time other than the
>> current time: at least I can't see a %-escape that takes a different
>> time.
>>
>> --
>> Nick
>>
>>
>>
>


[O] Tag hierarchies

2015-08-21 Thread Shankar Rao
I've read about tag hierarchies in the manual
(http://orgmode.org/manual/Tag-hierarchy.html#Tag-hierarchy) and my
understanding is that searching for a group tag A will search for
headlines tagged either with A or any of A's descendants. However this
isn't the behavior I observe. In the example below, if I do a agenda
tag search for :agroup:, :dgroup, or :egroup:, nothing shows up in the
search. Only tags that are explicitly in a headline, like :foo:,:bar:,
or :bgroup:, show up in searches. Is this a bug or a misunderstanding
of how tag hierarchies are supposed to work? org-group-tag is set to t
(the default).

Shankar Rao
Aquamacs 3.2 GNU Emacs 24.4.51.2
Org 8.2.10

-- begin example
#+STARTUP: overview
#+TAGS: [ agroup : foo baz ]
#+TAGS: [ bgroup : bar ]
#+TAGS: [ cgroup ]
#+TAGS: [ dgroup : gah ]
#+TAGS: [ egroup : doh meh ]

* TODO Cure cancer  :foo:
** DONE Sequence human genome
** WAIT Obtain funding from government
** DONE Find cancer causing genes
** DONE Genetically engineer rate with gene
CLOSED: [2015-08-12 Wed 16:00]
** DONE Test for cancer in rats
CLOSED: [2015-08-13 Thu 11:00]
** DONE Develop gene therapy for humans
CLOSED: [2015-08-17 Mon 16:19]
** TODO Find human test subjects
* End homelessness  :foo:
** DONE Find all homeless people
CLOSED: [2015-08-17 Mon 16:15]
** DONE Get money to build a bunch of homes
CLOSED: [2015-08-21 Fri 12:07]
** DONE Build homes for homeless people
CLOSED: [2015-08-21 Fri 10:07]
** DONE Give homes to homeless people
CLOSED: [2015-08-21 Fri 13:07]
* Write paper on cancer gene therapy:foo:
** TODO Make outline for paper
* DONE Make presentation on ending homelessness :foo:
CLOSED: [2015-08-14 Fri 17:15]
* TODO Provide inputs for cancer research progress report   :foo:
DEADLINE: <2015-09-02 Wed>
* TODO Determine hardware requirements for cold fusion  :baz:
* DONE Provide inputs for cold fusion research progress report  :baz:
CLOSED: [2015-08-12 Wed 14:20]
* Investigate methods for hot, but not that hot fusion  :baz:
* TODO Brainstorm with Stephen Hawking on new laws of robotics  :gah:
* DONE Look at papers on chilly superconductors :doh:
* Investigate models for chilly superconductors :doh:
* WAIT Proposal for trip to Mars :doh:cgroup:
** DONE E-mail reminder to NASA director
** DONE Rehearse proposal presentation
* TODO Proposal for autonomous car project  :bgroup::doh:
** DONE Go over papers on autonomous cars
CLOSED: [2015-08-20 Thu 14:08]
** DONE Discuss them with Elon Musk
CLOSED: [2015-08-20 Thu 16:08]
** DONE Add charts on new ideas to proposal presentation
CLOSED: [2015-08-20 Thu 17:10]
* TODO Respond to critiques of economic plan:meh:
** TODO Paragraph explaining more about how OneTrueTax works
* TODO Develop new fungi that taste like chicken:bar:
** DONE Find chicken genes that contribute to taste
CLOSED: [2015-08-19 Wed 21:18]
** DONE Splice chicken genes into fungi DNA
CLOSED: [2015-08-19 Wed 21:18]
** DONE Breed new fungi
CLOSED: [2015-08-19 Wed 21:18]
** DONE Cook basic dishes with new fungi
CLOSED: [2015-08-19 Wed 21:18]
** TODO Explore different kinds of seasoning
** TODO Explore difference between frying, baking, boiling fungi
** TODO Test cooked chicken-fungi with food scientists
** TODO Test cooked chicken-fungi with blind panel
-- end example



Unintended consequences of removing org-speed-commands-user

2021-11-24 Thread Shankar Rao
Hello all,

I discovered that upgrading to 9.5 broke my configuration because the
variable `org-speed-commands-user' was removed. I read the thread
(https://list.orgmode.org/87v9hzzhrn@gmail.com/) where this change
was proposed and I completely agree that exposing the whole set of
`org-speeds-commands' to the user for customization is an improvement
over the previous state of affairs. However, I believe there were some
unintended consequences of this change that can make it difficult to
customize `org-speed-commands' for users that are not elisp gurus.

The main problem is that `org-speed-commands' serves two purposes
simultaneously:

1.) It contains all the mappings between speed keys and commands
2.) It contains headlines for command categories.

Because of this second purpose, both the contents and order of entries
in `org-speed-commands' are important. For example, suppose I want to
replace the usual "n" command with my own. According to the usual
conventions for alists
(https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html),
new associations such as this are added to the front of the list. But
if I do so, by doing something like:

  (setq org-speed-commands (cons '("n" . #'my-org-next-heading)
org-speed-commands))

Then the speed key "n" will show up twice when
`org-speed-command-help' is invoked. I could first delete the old
association by replacing `org-speed-commands' in the above with
`(assoc-delete-all "n" org-speed-commands)', but then my modified
command will no longer appear in the "Outline Navigation" section of
the speed command help. Alternatively, I could replace the association
for "n" using `alist-get':

  (setf (alist-get "n" org-speed-commands nil nil #'equal)
#'my-org-next-heading)

However, this solution won't work for new speed commands (e.g., if I
want to bind `my-org-next-heading' to "N" instead), because in that
case `alist-get' will return `nil'.

Below is the relevant portion of my config file where I customize
`org-speed-commands':
-
  (defun alist-set (key value alist-symbol &optional testfn)
"Set KEY to VALUE in alist referenced by ALIST-SYMBOL.

  If KEY is not present in the alist, then add (KEY. VALUE) to the
  front of the alist. Compare keys with TESTFN. Defaults to equal."
(if-let ((keyval (assoc key (eval alist-symbol) testfn)))
(setf (cdr keyval) value)
  (set alist-symbol (cons (cons key value) (eval alist-symbol)


  (defvar sbr-org-speed-commands-user '(("User Custom Speed Commands")
("N" . ded-org-show-next-heading-tidily)
("P" .
ded-org-show-previous-heading-tidily)
("h" . sbr-org-speed-insert-subheading)
("u" . org-up-heading-or-item)
("b" . org-backward-heading-or-item)
("f" . org-forward-heading-or-item)
("p" . org-prev-heading-or-item)
("n" . org-next-heading-or-item))
"My custom Org speed commands")

  (dolist (keyval (reverse sbr-org-speed-commands-user))
(alist-set (car keyval) (cdr keyval) 'org-speed-commands))
-

As you can see, I defined my own function `alist-set', which modifies
an association in an alist if the key is already present, or adds the
new association to the front of the list otherwise. In my opinion,
functionality like `alist-set' should be built into Emacs itself. My
code then constructs my own list of custom speed commands with its own
section header and uses `alist-set' to add/modify speed commands.
While this code works, it's a bit unsatisfying because

1.) It relies on my custom `alist-set' function
2.) It relies on knowledge of the structure of `org-speed-commands'

More specifically, it requires that my new speed commands need to be
inserted in reverse order into `org-speed-commands' in order to be
displayed properly in `org-speed-commands-help'.

I don't know what is the best solution to enable Org users to add
and/or modify speed commands while also keeping the display of
`org-speed-commands-help' organized. Here is what I propose:

1.) Keep the whole set of `org-speed-commands' exposed to user
customization for power users
2.) Bring back `org-speed-commands-user', but instead of just
appending it to `org-speed-commands' as was done prior to Org 9.5, use
something like my `alist-set' above to add/modify speed command
associations as needed while preserving the display order in
`org-speed-commands-help'.

With my proposal, Org users wouldn't have to concern themselves with
the section headers in `org-speed-commands', but they would still be
able to add/modify/remove commands as they wish.

Let me know if anyone has a simpler alternative to achieve these
goals. If there is sufficient interest in my proposal, I would be
happy to provide a patch.

T

Re: Unintended consequences of removing org-speed-commands-user

2021-11-30 Thread Shankar Rao
Thank you for the tip. I didn't realize that `member' could be used in
this way to insert an element at a particular point in a list. But
this doesn't address the main issue in my post, that the user has two
different approaches for adding commands to `org-speed-commands'
depending on whether it is a brand new command or overwriting an old
one.

After thinking about it over the weekend, I believe I've come up with
a simple solution that will achieve easy addition to/ modification of
`org-speed-commands' without bringing reverting back to
`org-speed-commands-user'. I'll submit a patch for this soon

Shankar

On Sun, Nov 28, 2021 at 1:15 PM  wrote:
>
>
> Hi,
>
> If you want to insert a new element in the list after a particular
> element, you could do :
>
> #+begin_src emacs-lisp
> (let ((bk (cdr (member '("Agenda Views etc") org-speed-commands
>   (setf (cdr (member '("Agenda Views etc") org-speed-commands))
> (cons '("@" . my-foobarized-speed-command) bk)))
> #+end_src
>
> Use append to insert a list of new elements instead of one.
>
> Also simply add a new list at the end, use append :
>
> #+begin_src emacs-lisp :results code
> (setq org-speed-commands
>   (append org-speed-commands '(("my foo commands!")
>("@" . my-foobarized-speed-command)
>("&" . my-barfooized-speed-command
> #+end_src
>
> However if you define many new commands, simply redefining the whole
> list is simpler ;)



[PATCH] New function org-speed-command-add for adding/modifying speed commands

2021-11-30 Thread Shankar Rao
Over the weekend I thought about this issue of configuring
`org-speed-commands' more easily, and I believe I have come up with a
simpler solution that I have provided in the attached patch.

This patch creates a new function `org-speed-command-add' that can be
used to add new speed command shortcuts to `org-speed-commands', as
well as modify existing shortcuts. This function takes as argument an
alist in the same format as `org-speed-commands'. For each command for
which the shortcut key is already present in `org-speed-commands', the
old command is replaced with the new command at the same position.
Commands with brand new shortcut keys are added to the user section of
`org-speed-commands'.

I believe this patch strikes a balance between power users, who can
still directly customize `org-speed-commands', and non-experts, who
may want to add/modify some speed commands without having to
understand the structure and organization of `org-speed-commands'.

Shankar

On Wed, Nov 24, 2021 at 10:36 AM Shankar Rao  wrote:
>
> Hello all,
>
> I discovered that upgrading to 9.5 broke my configuration because the
> variable `org-speed-commands-user' was removed. I read the thread
> (https://list.orgmode.org/87v9hzzhrn@gmail.com/) where this change
> was proposed and I completely agree that exposing the whole set of
> `org-speeds-commands' to the user for customization is an improvement
> over the previous state of affairs. However, I believe there were some
> unintended consequences of this change that can make it difficult to
> customize `org-speed-commands' for users that are not elisp gurus.
>
> The main problem is that `org-speed-commands' serves two purposes
> simultaneously:
>
> 1.) It contains all the mappings between speed keys and commands
> 2.) It contains headlines for command categories.
>
> Because of this second purpose, both the contents and order of entries
> in `org-speed-commands' are important. For example, suppose I want to
> replace the usual "n" command with my own. According to the usual
> conventions for alists
> (https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html),
> new associations such as this are added to the front of the list. But
> if I do so, by doing something like:
>
>   (setq org-speed-commands (cons '("n" . #'my-org-next-heading)
> org-speed-commands))
>
> Then the speed key "n" will show up twice when
> `org-speed-command-help' is invoked. I could first delete the old
> association by replacing `org-speed-commands' in the above with
> `(assoc-delete-all "n" org-speed-commands)', but then my modified
> command will no longer appear in the "Outline Navigation" section of
> the speed command help. Alternatively, I could replace the association
> for "n" using `alist-get':
>
>   (setf (alist-get "n" org-speed-commands nil nil #'equal)
> #'my-org-next-heading)
>
> However, this solution won't work for new speed commands (e.g., if I
> want to bind `my-org-next-heading' to "N" instead), because in that
> case `alist-get' will return `nil'.
>
> Below is the relevant portion of my config file where I customize
> `org-speed-commands':
> -
>   (defun alist-set (key value alist-symbol &optional testfn)
> "Set KEY to VALUE in alist referenced by ALIST-SYMBOL.
>
>   If KEY is not present in the alist, then add (KEY. VALUE) to the
>   front of the alist. Compare keys with TESTFN. Defaults to equal."
> (if-let ((keyval (assoc key (eval alist-symbol) testfn)))
> (setf (cdr keyval) value)
>   (set alist-symbol (cons (cons key value) (eval alist-symbol)
>
>
>   (defvar sbr-org-speed-commands-user '(("User Custom Speed Commands")
> ("N" . 
> ded-org-show-next-heading-tidily)
> ("P" .
> ded-org-show-previous-heading-tidily)
> ("h" . 
> sbr-org-speed-insert-subheading)
> ("u" . org-up-heading-or-item)
> ("b" . org-backward-heading-or-item)
> ("f" . org-forward-heading-or-item)
> ("p" . org-prev-heading-or-item)
> ("n" . org-next-heading-or-item))
> "My custom Org speed commands")
>
>   (dolist (keyval (reverse sbr-org-speed-commands-user))
> (alist-set (car keyval) (cdr keyval) &#x

Re: [PATCH] New function org-speed-command-add for adding/modifying speed commands

2022-05-17 Thread Shankar Rao
Thank you for looking into this. As you recommended, I tried modifying
``org-speed-commands'' using the customize interface. While it did
enable me to configure and organize ``org-speed-commands'' in just the
way I would like, I found using the customize interface to be a bit
cumbersome. Using the customize interface, for each command that I
wished to add, I had to visually scan over the whole structure of
``org-speed-commands'' to see if the key for this command was already
present in the list, and replace it with my command if it is, or
prepend my command to the top of the list if not it was already
present. Then after I saved the customization, it added the whole new
value of ``org-speed-commands'' to the end of my init.el, making it
more cluttered.

Alternatively using my ``org-speed-command-add'' requires me to add a
single command to my init.el containing only my modifications:

(org-speed-command-add
'(("N" . ded-org-show-next-heading-tidily)
  ("P" . ded-org-show-previous-heading-tidily)
  ("h" . sbr-org-speed-insert-subheading)
  ("f" . org-forward-heading-or-item)
  ("b" . org-backward-heading-or-item)
  ("u" . org-up-heading-or-item)
  ("n" . org-next-heading-or-item)
  ("p" . org-prev-heading-or-item)))

Using ``org-speed-command-add'', I don't have to be concerned with
whether or not a given key is already present in
``org-speed-commands''.

I agree that ``org-speed-command-add'' has undefined behavior when
provided with only a descriptive headline as its first element. Would
you be more amenable to this command if it either ignored or
explicitly disallowed descriptive headline entries?

Shankar


On Tue, May 3, 2022 at 12:23 PM Ihor Radchenko  wrote:
>
> Shankar Rao  writes:
>
> > Over the weekend I thought about this issue of configuring
> > `org-speed-commands' more easily, and I believe I have come up with a
> > simpler solution that I have provided in the attached patch.
> >
> > This patch creates a new function `org-speed-command-add' that can be
> > used to add new speed command shortcuts to `org-speed-commands', as
> > well as modify existing shortcuts. This function takes as argument an
> > alist in the same format as `org-speed-commands'. For each command for
> > which the shortcut key is already present in `org-speed-commands', the
> > old command is replaced with the new command at the same position.
> > Commands with brand new shortcut keys are added to the user section of
> > `org-speed-commands'.
> >
> > I believe this patch strikes a balance between power users, who can
> > still directly customize `org-speed-commands', and non-experts, who
> > may want to add/modify some speed commands without having to
> > understand the structure and organization of `org-speed-commands'.
>
> I am not sure about usefulness of the proposed command. For non-power
> users, we have cusomize interface. It should work just fine without a
> need to introduce another function.
>
> Also, org-speed-command-add may behave strangely if the argument
> contains descriptive headline like ("My command group title") as its
> first element.
>
> Best,
> Ihor



[PATCH] Add mode for automatically unhiding emphasis markers in the current region

2020-06-01 Thread Shankar Rao
* lisp/org.el:
(org-auto-emphasis-unhide-at-point): Parameter that controls the
behavior of Org Auto Emphasis mode.  It can be one of the values nil, t, and
'right-edge, and works similarly to the parameter
`prettify-symbols-unprettify-at-point' for `prettify-symbols-mode'.
(org-do-emphasis-faces): When hiding emphasis markers, add additional
text properties 'org-emph-start and org-emph-end to the emphasized
region.
(org-auto-emphasis--current-region-bounds): Local variable containing
the bounds of the region whose emphasis markers are currently
unhidden.
(org-auto-emphasis--get-prop-as-list): Helper function that returns
Org Auto Emphasis properties as a list.
(org-auto-emphasis--post-command-hook): Function added to
`post-command-hook' that rehides emphasis markers for the previous
region and unhides emphasis marks for the current region.
(org-auto-emphasis-mode): Toggles Org Auto Emphasis mode.  Can be
added to `org-mode-hook' to be enabled for all org-mode files.

This code was adapted from prettify-symbols-mode in prog-mode.el

I have not yet signed the papers assigning copyright to the FSF.  I sent a
request for the papers to ass...@gnu.org, but have not yet received a
response.

Shankar Rao

---
 lisp/org.el | 98 +++--
 1 file changed, 87 insertions(+), 11 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 7ff7ec685..870c5c958 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -3644,6 +3644,19 @@ following symbols:
   :type 'boolean
   :safe #'booleanp)

+(defcustom org-auto-emphasis-unhide-at-point nil
+  "If non-nil, unhide the emphasis markers for the region when point is on
it.
+If set to the symbol `right-edge', also unhide the emphasis
+markers if point is immediately after the emphasized region.  The
+emphasis markers will be rehidden as soon as point moves away
+from the region.  If set to nil, the emphasis markers remain
+hidden even when point is in the region."
+  :version "25.1"
+  :type '(choice (const :tag "Never unhide emphasis markers" nil)
+ (const :tag "Unhide emphasis markers when point is
inside" t)
+ (const :tag "Unhide emphasis markers when point is inside
or at right edge" right-edge))
+  :group 'org-appearance)
+
 (defcustom org-hide-macro-markers nil
   "Non-nil mean font-lock should hide the brackets marking macro calls."
   :group 'org-appearance
@@ -5056,12 +5069,77 @@ stacked delimiters is N.  Escaping delimiters is
not possible."
'(font-lock-multiline t org-emphasis t))
   (when (and org-hide-emphasis-markers
  (not (org-at-comment-p)))
- (add-text-properties (match-end 4) (match-beginning 5)
- '(invisible org-link))
- (add-text-properties (match-beginning 3) (match-end 3)
- '(invisible org-link)))
+ (let ((s1 (match-beginning 3))
+  (e1 (match-end 3))
+  (s2 (match-end 4))
+  (e2 (match-beginning 5)))
+  (add-text-properties s2 e2 '(invisible org-link))
+  (add-text-properties s1 e1 '(invisible org-link))
+  (add-text-properties s1 e2
+   `(org-emph-start ,s1 org-emph-end ,e2
   (throw :exit t

+(defvar-local org-auto-emphasis--current-region-bounds nil)
+
+(defun org-auto-emphasis--get-prop-as-list (prop)
+  "Helper function to get org-auto-emphasis properties as a list.
+If `org-auto-emphasis-unhide-at-point' is set to `t' then return
+the text property PROP at point in a list. If
+`org-auto-emphasis-unhide-at-point' is set to `right-edge', the
+also include the text property PROP at point-1 unless we are at
+the beginning of the buffer."
+  (remove nil
+  (list (get-text-property (point) prop)
+ (when (and (eq org-auto-emphasis-unhide-at-point 'right-edge)
+   (not (bobp)))
+  (get-text-property (1- (point)) prop)
+
+(defun org-auto-emphasis--post-command-hook ()
+  ;; Rehide emphasis markers for the previous region.
+  (when (and org-auto-emphasis--current-region-bounds
+ (or (< (point) (car org-auto-emphasis--current-region-bounds))
+ (> (point) (cadr org-auto-emphasis--current-region-bounds))
+ (and (not (eq org-auto-emphasis-unhide-at-point 'right-edge))
+  (= (point) (cadr org-auto-emphasis--current-region-bounds)
+ (apply #'font-lock-flush org-auto-emphasis--current-region-bounds)
+ (setq org-auto-emphasis--current-region-bounds nil))
+  ;; Unhide emphasis markers for the current region.
+  (when-let* ((s (org-auto-emphasis--get-prop-as-list 'org-emph-start))
+  (e (org-auto-emphasis--get-prop-as-list 'org-emph-end))
+  (s (apply #'min s))
+  (e (apply #'max e)))
+(with-silent-modifications
+  (setq org-auto-emphasis--current-region-bounds (list s e))
+  (remove-text-properties s (1+ s) '(invisible org-link))
+  (remove-text-properties (1- e) e '(invisible o

Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region

2020-06-01 Thread Shankar Rao
Sorry, I've never submitted a patch before. Looking through this mailing
list, I see that you're supposed to attach the .patch file to the e-mail,
so here it is.

This patch adds a minor mode that makes emphasis markers be automatically
unhidden when the point is inside the region of emphasis and then the
markers are rehidden when the point is moved elsewhere. I posted this on
/r/orgmode on reddit (
https://www.reddit.com/r/orgmode/comments/gss1g4/update_i_made_my_own_sbrorgemphasizemode_that/),
and people there suggested that I submit this here as a patch.

Shankar

On Mon, Jun 1, 2020 at 4:14 PM Shankar Rao  wrote:

> * lisp/org.el:
> (org-auto-emphasis-unhide-at-point): Parameter that controls the
> behavior of Org Auto Emphasis mode.  It can be one of the values nil, t,
> and
> 'right-edge, and works similarly to the parameter
> `prettify-symbols-unprettify-at-point' for `prettify-symbols-mode'.
> (org-do-emphasis-faces): When hiding emphasis markers, add additional
> text properties 'org-emph-start and org-emph-end to the emphasized
> region.
> (org-auto-emphasis--current-region-bounds): Local variable containing
> the bounds of the region whose emphasis markers are currently
> unhidden.
> (org-auto-emphasis--get-prop-as-list): Helper function that returns
> Org Auto Emphasis properties as a list.
> (org-auto-emphasis--post-command-hook): Function added to
> `post-command-hook' that rehides emphasis markers for the previous
> region and unhides emphasis marks for the current region.
> (org-auto-emphasis-mode): Toggles Org Auto Emphasis mode.  Can be
> added to `org-mode-hook' to be enabled for all org-mode files.
>
> This code was adapted from prettify-symbols-mode in prog-mode.el
>
> I have not yet signed the papers assigning copyright to the FSF.  I sent a
> request for the papers to ass...@gnu.org, but have not yet received a
> response.
>
> Shankar Rao
>
> ---
>  lisp/org.el | 98 +++--
>  1 file changed, 87 insertions(+), 11 deletions(-)
>
> diff --git a/lisp/org.el b/lisp/org.el
> index 7ff7ec685..870c5c958 100644
> --- a/lisp/org.el
> +++ b/lisp/org.el
> @@ -3644,6 +3644,19 @@ following symbols:
>:type 'boolean
>:safe #'booleanp)
>
> +(defcustom org-auto-emphasis-unhide-at-point nil
> +  "If non-nil, unhide the emphasis markers for the region when point is
> on it.
> +If set to the symbol `right-edge', also unhide the emphasis
> +markers if point is immediately after the emphasized region.  The
> +emphasis markers will be rehidden as soon as point moves away
> +from the region.  If set to nil, the emphasis markers remain
> +hidden even when point is in the region."
> +  :version "25.1"
> +  :type '(choice (const :tag "Never unhide emphasis markers" nil)
> + (const :tag "Unhide emphasis markers when point is
> inside" t)
> + (const :tag "Unhide emphasis markers when point is
> inside or at right edge" right-edge))
> +  :group 'org-appearance)
> +
>  (defcustom org-hide-macro-markers nil
>"Non-nil mean font-lock should hide the brackets marking macro calls."
>:group 'org-appearance
> @@ -5056,12 +5069,77 @@ stacked delimiters is N.  Escaping delimiters is
> not possible."
> '(font-lock-multiline t org-emphasis t))
>(when (and org-hide-emphasis-markers
>   (not (org-at-comment-p)))
> - (add-text-properties (match-end 4) (match-beginning 5)
> - '(invisible org-link))
> - (add-text-properties (match-beginning 3) (match-end 3)
> - '(invisible org-link)))
> + (let ((s1 (match-beginning 3))
> +  (e1 (match-end 3))
> +  (s2 (match-end 4))
> +  (e2 (match-beginning 5)))
> +  (add-text-properties s2 e2 '(invisible org-link))
> +  (add-text-properties s1 e1 '(invisible org-link))
> +  (add-text-properties s1 e2
> +   `(org-emph-start ,s1 org-emph-end ,e2
>(throw :exit t
>
> +(defvar-local org-auto-emphasis--current-region-bounds nil)
> +
> +(defun org-auto-emphasis--get-prop-as-list (prop)
> +  "Helper function to get org-auto-emphasis properties as a list.
> +If `org-auto-emphasis-unhide-at-point' is set to `t' then return
> +the text property PROP at point in a list. If
> +`org-auto-emphasis-unhide-at-point' is set to `right-edge', the
> +also include the text property PROP at point-1 unless we are at
> +the beginning of the buffer."
> +  (remove nil
> +  (list (get-text-property (point) prop)
> + (when (and (eq org-auto-emphasis-unhide-at-point 'right-edge)
> +   (not (bobp)))
> +  (get-t

Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region

2020-06-24 Thread Shankar Rao
diff --git a/lisp/org.el b/lisp/org.el
index 4d46b4173..8bab33ec0 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -3644,6 +3644,19 @@ following symbols:
   :type 'boolean
   :safe #'booleanp)

+(defcustom org-auto-emphasis-unhide-at-point nil
+  "If non-nil, unhide the emphasis markers for the text at point.
+If set to the symbol `right-edge', also unhide the emphasis
+markers if point is immediately after the emphasized text.  The
+emphasis markers will be rehidden as soon as point moves away
+from the emphasized text.  If set to nil, the emphasis markers
+always remain hidden."
+  :package-version '(Org . "9.5")
+  :type '(choice (const :tag "Never unhide emphasis markers" nil)
+ (const :tag "Unhide when point is inside" t)
+ (const :tag "Unhide when point is inside or at right
edge" right-edge))
+  :group 'org-appearance)
+
 (defcustom org-hide-macro-markers nil
   "Non-nil mean font-lock should hide the brackets marking macro calls."
   :group 'org-appearance
@@ -5055,12 +5068,78 @@ stacked delimiters is N.  Escaping delimiters is
not possible."
'(font-lock-multiline t org-emphasis t))
   (when (and org-hide-emphasis-markers
  (not (org-at-comment-p)))
- (add-text-properties (match-end 4) (match-beginning 5)
- '(invisible org-link))
- (add-text-properties (match-beginning 3) (match-end 3)
- '(invisible org-link)))
+ (let ((s1 (match-beginning 3))
+  (e1 (match-end 3))
+  (s2 (match-end 4))
+  (e2 (match-beginning 5)))
+  (add-text-properties s2 e2 '(invisible org-link))
+  (add-text-properties s1 e1 '(invisible org-link))
+  (add-text-properties s1 e2
+   `(org-emph-start ,s1 org-emph-end ,e2
   (throw :exit t

+(defvar-local org-auto-emphasis--current-region-bounds nil)
+
+(defun org-auto-emphasis--get-prop-as-list (prop)
+  "Helper function to get org-auto-emphasis properties as a list.
+If `org-auto-emphasis-unhide-at-point' is set to t, then return
+the text property PROP at point in a list. If
+`org-auto-emphasis-unhide-at-point' is set to `right-edge', the
+also include the text property PROP at point-1 unless we are at
+the beginning of the buffer."
+  (remove nil
+  (list (get-text-property (point) prop)
+ (when (and (eq org-auto-emphasis-unhide-at-point 'right-edge)
+   (not (bobp)))
+  (get-text-property (1- (point)) prop)
+
+(defun org-auto-emphasis--post-command-hook ()
+  ;; Rehide emphasis markers for the previous region.
+  (when (and org-auto-emphasis--current-region-bounds
+ (or (< (point) (car org-auto-emphasis--current-region-bounds))
+ (> (point) (cadr org-auto-emphasis--current-region-bounds))
+ (and (not (eq org-auto-emphasis-unhide-at-point 'right-edge))
+  (= (point) (cadr org-auto-emphasis--current-region-bounds)
+ (apply #'font-lock-flush org-auto-emphasis--current-region-bounds)
+ (setq org-auto-emphasis--current-region-bounds nil))
+  ;; Unhide emphasis markers for the current region.
+  (let* ((s (org-auto-emphasis--get-prop-as-list 'org-emph-start))
+ (e (and s (org-auto-emphasis--get-prop-as-list 'org-emph-end)))
+ (s (and e (apply #'min s)))
+ (e (and s (apply #'max e
+(when e
+  (with-silent-modifications
+ (setq org-auto-emphasis--current-region-bounds (list s e))
+ (remove-text-properties s (1+ s) '(invisible org-link))
+ (remove-text-properties (1- e) e '(invisible org-link))
+
+(define-minor-mode org-auto-emphasis-mode
+  "Toggle Org Auto Emphasis mode.
+This mode, when enabled, unhides emphasis markers for the text
+at point, depending on the value of
+`org-auto-emphasis-unhide-at-point'. With a prefix argument ARG,
+enable Org Auto Emphasis mode if ARG is positive, and disable it
+otherwise.  If called from Lisp, enable the mode if ARG is
+omitted or nil.
+
+To enable this in all Org files, add the following line to init.el:
+
+  (add-hook \\='org-mode #\\='org-auto-emphasis-mode)
+"
+  :init-value nil
+  (if org-auto-emphasis-mode
+  ;; Turn on
+  (progn
+(setq-local font-lock-extra-managed-props
+(append font-lock-extra-managed-props
+'(org-emph-start org-emph-end)))
+    (when org-auto-emphasis-unhide-at-point
+  (add-hook 'post-command-hook
+#'org-auto-emphasis--post-command-hook nil t))
+(font-lock-flush))
+;; Turn off
+(remove-hook 'post-command-hook #'org-auto-emphasis--post-command-hook
t)))
+
 (defun org-emphasize (&optional char)
   "Insert or change an emphasis, i.e. a font like bold or italic.
 If there is an active region, change that region to a new emphasis.
-- 
2.17.1
From 0e2a46c01ad412d59b3a67a4ba8292914e700102 Mon Sep 17 00:00:00 2001
From: Shankar Rao 
Date: Wed, 24 

Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region

2020-06-24 Thread Shankar Rao
> Sorry for being late to the party, but, IMO, this doesn't sound like
> a right approach to the problem of invisible emphasis markers. A user
> choosing to hide emphasis markers should not need to—or even be given
> the opportunity to—display them in order to edit them efficiently.
>

I agree that if org-emphasize handled marker visibility states in a DWIM
fashion, then a user should not need to display them, but why do you
believe they shouldn't have the opportunity, especially given that this is
the exact behavior of prettify-symbols-mode?

Could you walk me through, in your proposed DWIM system, how a user should
be able to remove or change emphasis markers after they are rendered and
hidden?

Shankar


Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region

2020-07-03 Thread Shankar Rao
Hi,

I wrote my message in a hurry. Let me clarify it.
>
> I'm only talking about built-in tooling. I don't mind if a user have the
> feature you're proposing, of course, as it is not wrong per se.
>
> However, I believe that's not the best solution for the problem we're
> trying to solve. I think there's an opportunity to provide something
> smarter, and less intrusive, to handle emphasis, which doesn't involve
> messing with `post-command-hook'.
>

I agree with you that my solution is somewhat intrusive. Ideally, I would
have preferred that my solution could leverage advice functions or some Org
hook, so that I wouldn't have to modify org.el, but it doesn't seem like
there is a straightforward way to do that. The modification of
`post-command-hook', similar to one used for `prettify-symbols-mode', only
occurs if `org-auto-emphasis-mode' is active


> Like in a word processor, you don't need to see the markers to operate
> on them. I don't think the usual "toggle" model is appropriate, however.
> I suggest to use two commands: one for deleting the markers around point
> or within active region, and one for inserting markers or extending
> existing ones.
>
So in your system, in order to interact with emphasis markers, the user
would have to learn two different commands? That doesn't seem to be in line
with the dwim philosophy used in modern emacs packages.

In my opinion, one of the strengths of Org is that the interface is
multimodal. One can (in principle) edit documents in much the same way as
word processors and rich text editors. However since everything underneath
is implemented with just text, one can also directly access and manipulate
this text. The ability to switch between these two modalities is extremely
powerful and is what sets Org apart from other document editing systems.


> Allow me to polish up my draft a bit, so we can compare the benefits of
> each system.
>

I look forward to seeing your proposed system more concretely.

Shankar Rao


Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region

2020-07-07 Thread Shankar Rao
Thank you for your hard work on this. It's definitely easier to compare two
concrete blocks of code rather than abstract ideas.

> I agree with you that my solution is somewhat intrusive. Ideally, I would
> > have preferred that my solution could leverage advice functions or some
> Org
> > hook, so that I wouldn't have to modify org.el, but it doesn't seem like
> > there is a straightforward way to do that. The modification of
> > `post-command-hook', similar to one used for `prettify-symbols-mode',
> only
> > occurs if `org-auto-emphasis-mode' is active
>
> The problem is not your implementation, really. It's just that I don't
> think it should be the _built-in_ way to solve emphasis management. IOW,
> we shouldn't need to activate a minor mode to make that management
> tolerable in the first place.
>
> However, I agree that it makes senses as an extension, in the same vein
> as `org-fragtog` for LaTeX fragments.
>

That's a fair point. As I said, I modified `org-do-emphasis-faces' in
org.el only because I couldn't find a less intrusive way of achieving the
functionality I was looking for. Is there a way to make
`org-auto-emphasis-mode' an extension that leaves org.el unmodified?


> > So in your system, in order to interact with emphasis markers, the user
> > would have to learn two different commands? That doesn't seem to be in
> line
> > with the dwim philosophy used in modern emacs packages.
>
> Two different commands? Bah! The change I suggest introduces 7 new
> commands and 12 new bindings! :)
>
> Yet, I claim it is still (somewhat) intuitive.
>

I agree that your change is reasonably intuitive. I find it quite elegant
that you appropriated the M-o binding (which by default runs the
`facemenu-set-*' commands) in orgmode, and that the modifier keys
(*,/,_,~,=,+) map to text emphasis markers. But while I find your change
easy to understand, I find it a bit unwieldy to use. I discuss this further
below.


> > In my opinion, one of the strengths of Org is that the interface is
> > multimodal. One can (in principle) edit documents in much the same way as
> > word processors and rich text editors. However since everything
> underneath
> > is implemented with just text, one can also directly access and
> manipulate
> > this text. The ability to switch between these two modalities is
> extremely
> > powerful and is what sets Org apart from other document editing
> > systems.
>
> You can always toggle `visible-mode' for that.
>
> But, really, I think an option like `org-hide-emphasis-markers' is
> a one-off toggle. Having to, in a way, switch regularly between two
> values is sub-optimal.
>

I completely agree that toggling on and off *all* emphasis markers is
suboptimal. In fact, before I developed this `org-auto-emphasis-mode', my
previous solution was to toggle the emphasis marker at point. Please refer
to this reddit post (
https://www.reddit.com/r/orgmode/comments/grh423/is_it_possible_to_make_orghideemphasismarkers_and/).
Coincidentally, I bound this function to M-o as well.


> Here it is.
>
> The main command is `org-emphasis'. It emphasizes the minimal possible
> area around point, or region. If there's already an emphasis object of
> the desired type around point or region, it extends it forward instead.
> With a prefix argument, it removes the emphasis.
>
> Interactively, the command asks for the type of emphasis to use, but
> I suggest to use dedicated commands instead. Thus, I added a key-binding
> for each of the six emphasis types. For example, for bold, use
>
>   `M-o *'or`M-o M-*'
>
> There are equivalent commands for underline (`M-o _` or `M-o M-_'), and
> so on.
>

I tested out your commands and I find your `org-emphasis' to indeed be an
improvement over `org-emphasize'. Since the two commands are so similar, I
would recommend refining this and having it be a replacement for
`org-emphasize'. Here are my comments.

- I like that, in the absence of a region, `org-emphasis' emphasizes the
area around the point. This improves upon `org-emphasize', which inserts a
pair of emphasis markers at point.
- I find the behavior of repeated invocations to expand the area of
emphasis to be useful, but strange. I don't know of any other commands that
expand the area of some property with repeated invocations (except for
`expand-region', which is designed to do that explicitly). To me, it would
be both more straightforward to expand or contract the region (e.g., using
C-right or C-left) and then apply emphasis using M-o.
- I find it unwieldy that to unemphasize, you must use both the prefix
command and remember which marker you chose (e.g. to unbold you must do C-u
M-o *). Prefix commands are usually reserved for special modifications of
commands, and I think unemphasizing is sufficiently common that it
shouldn't be relegated to this space. In word processors like MS Word,
unemphasizing is implemented by repeatedly invoking the keyboard command
(e.g, C-b on plain text bolds it and C-b on bolded

Insert outline breadcrumbs just before headings text in agenda view

2021-08-31 Thread Shankar Rao
 In Emacs org-mode, I have a set of TODOs in the following format:

* H1
** H2
*** H3
 TODO [#A] File Taxes

If I activate breadcrumbs in org-agenda-prefix-format (i.e., by
doing (setf (alist-get 'agenda org-agenda-prefix-format)
" %i %-12:c%?-12t% s%b")), when I look at the agenda-todo view, it
shows up as:

H1->H2->H3->TODO [#A] File Taxes

However, I would like it to instead be displayed like this:
TODO [#A] H1->H2->H3->File Taxes

I asked about this on Reddit
<https://www.reddit.com/r/orgmode/comments/p828af/rearrange_headline_with_breadcrumbs_in_agenda/>
and Stack Exchange
<https://emacs.stackexchange.com/questions/68225/orgmode-rearrange-headline-with-breadcrumbs-in-agenda-todo-list>,
and since it
appeared that no one had already come up with a solution for
this, I decided to cook up my own using an advice function:
(defvar org-agenda-breadcrumbs-level 1
  "Highest level subtree to include in Org agenda breadcrumb.")

(defun org-agenda-breadcrumbs-string ()
  "Create formatted string with outline of Org subtree at point.

The outline goes up to subtree level
`org-agenda-breadcrumbs-level` and the subtree headings are
separated by `org-agenda-breadcrumbs-separator`."
  (org-format-outline-path (nthcdr (1- org-agenda-breadcrumbs-level)
   (org-get-outline-path))
   (1- (frame-width))
   nil org-agenda-breadcrumbs-separator))

(defun org-agenda-insert-breadcrumbs-before-text (args)
  "In Org agenda, insert outline breadcrumbs just before heading text in ARGS.

This is an advice function for use with `org-agenda-format-item`
by doing:

(advice-add #'org-agenda-format-item :filter-args
#'org-agenda-insert-breadcrumbs-before-text)

Since ARGS is the list of arguments to be passed to
`org-agenda-format-item`, the second list element of ARGS
contains the heading text to be modified."
  (org-with-point-at (org-get-at-bol 'org-marker)
(let* ((txt (org-get-heading t t t t))
   (index (or (cl-search txt (cadr args)) 0))
   (bc (let ((s (org-agenda-breadcrumbs-string)))
 (if (eq "" s)
 ""
   (concat s org-agenda-breadcrumbs-separator)
  (setf (substring (cadr args) index index) bc)
  args)))

(advice-add #'org-agenda-format-item :filter-args
#'org-agenda-insert-breadcrumbs-before-text)

In my init.el, because I don't want the top level headings in the
outline breadcrumbs, I also have the following:

(setq org-agenda-breadcrumbs-level 2)

In my opinion, a feature like this is of sufficiently broad
interest that it should be included in Org so that it can be enabled
without the use of an advice function. However, it's not clear to me
what would be the best interface for configuring it. For example,
it doesn't make sense to add an option for this to
org-agenda-prefix-format, since this modifies the heading text
rather than the prefix.

If people agree that this feature is of broad interest, and have
suggestions on a good configuration interface, I would be happy
to submit this as a patch.

Shankar Rao