org: Como classificar os títulos por TODO e depois por prioridade?

24

Costumo ter uma lista como esta:

* Main heading
** TODO [#A] Make world better
** TODO [#B] Make Emacs better 
** TODO [#B] Customize emacs 
** DONE [#C] some task
** TODO [#A] Launch rocket to mars

Gostaria de classificá-lo de acordo com a palavra-chave 'TODO' primeiro. Em seguida, os itens dentro do TODO classificado que eu gostaria de classificar por prioridade. (seria bom classificar ainda mais por "Esforço").

No momento, posso clicar no cabeçalho principal e classificar os filhos já por prioridade ou por palavra-chave todo, mas não por ambos.

A classificação por ambos é possível como estratégia de classificação?


Atualmente eu tenho dois títulos

* Tasks
** TODO [#A] meh
** TODO [#B] meh2
* Completed.
** DONE [#B] meh3.

Mas o problema com essa abordagem é que tenho que embaralhar constantemente as tarefas quando concluí-las.

[EDIT]
Isso é meio parecido com isso, exceto que eu não conseguia entender a resposta dele para transferi-la para minhas necessidades?

Leo Ufimtsev
fonte
1
A função org-sort-entriesatuará no cabeçalho principal de todos os subtítulos ou pode classificar o que está em uma região selecionada. Existem opções interativas para você escolher. Você também pode usá-lo programaticamente, e várias classificações são possíveis - eu geralmente uso a, o, p, t (uma após a outra para atingir 4 níveis de critérios de classificação). Por exemplo, você pode classificar tudo primeiro por ordem alfabética, depois por palavras-chave de tarefas, depois por prioridade e depois por tempo.
lawlist
Olá, estou ciente da opção org-sort-inputs para classificar tarefas filho. Atualizei a questão para refletir melhor isso. Obrigado pelo seu comentário.
Leo Ufimtsev 25/02
Aqui está um link para uma abordagem detalhada para classificar um buffer de modo organizacional de forma programática: stackoverflow.com/a/22232709/2112489
lawlist
Eu já tenho esse link na minha pergunta. O exposto acima é meio adaptado às necessidades específicas de alguém. Existe uma abordagem mais geral / mais fácil?
Leo Ufimtsev 25/02
1
@LeoUfimtsev Tente definir org-refile-targetsalgo parecido (setq org-refile-targets '((nil . (:maxlevel . 6)))). Isso fará com que os org-modetítulos do programa atinjam uma profundidade de 6 ao refil. Você pode verificar a documentação para org-refile-targetsobter mais informações.
itsjeyd

Respostas:

19

Seria ótimo se houvesse algo assim org-agenda-sorting-stratagytrabalhado org-sort-entries, mas não parece haver. Podemos fingir, pois org-sort-entriespodemos usar um argumento especificando uma função que atribui uma tecla (string ou número) a cada cabeçalho, que será usada para classificar as entradas quando o ?ftipo de classificação for fornecido. Tudo o que precisamos fazer é obter uma string para as propriedades TODO e PRIORITY. O truque é que queremos classificar a propriedade TODO por sua posição org-todo-keywords, e não por ordem alfabética.

(require 'cl)
(require 'dash)

(defun todo-to-int (todo)
    (first (-non-nil
            (mapcar (lambda (keywords)
                      (let ((todo-seq
                             (-map (lambda (x) (first (split-string  x "(")))
                                   (rest keywords)))) 
                        (cl-position-if (lambda (x) (string= x todo)) todo-seq)))
                    org-todo-keywords))))

(defun my/org-sort-key ()
  (let* ((todo-max (apply #'max (mapcar #'length org-todo-keywords)))
         (todo (org-entry-get (point) "TODO"))
         (todo-int (if todo (todo-to-int todo) todo-max))
         (priority (org-entry-get (point) "PRIORITY"))
         (priority-int (if priority (string-to-char priority) org-default-priority)))
    (format "%03d %03d" todo-int priority-int)
    ))

(defun my/org-sort-entries ()
  (interactive)
  (org-sort-entries nil ?f #'my/org-sort-key))

M-x my/org-sort-entriesclassificará pela palavra-chave TODO e romperá os vínculos com PRIORITY (usando org-default-priorityquando nenhuma prioridade for dada). Isso será interrompido se você tiver mais de 1000 palavras-chave TODO, o que é um bom motivo para não fazer isso.

erikstokes
fonte
Omg, obrigado pelo script. Um problema: instalei o traço. Tentei o script, mas estou recebendo um erro: A definição do símbolo é nula: todo-to-int. Eu acho que você tem essa função em algum lugar do seu arquivo .emacs, mas esqueceu de incluir o item acima? ou talvez algum erro de digitação?
Leo Ufimtsev 26/02
Alterei a função que converte uma palavra-chave em int todo-to-intdepois de colar em minha resposta. Está consertado agora.
Erikstokes
1
Agora tudo funciona. Cara, obrigado por todo o seu esforço, muito apreciado :-D.
Leo Ufimtsev 26/02
1
Nota: não é mais recomendado usar cl de acordo com a documentação .
Cammil
1

Adicione o seguinte ao seu arquivo:

#+ARCHIVE: :: * Completed.

E embaralhar se torna arquivamento

Em vez de classificar as entradas, que tal uma exibição classificada?

(setq org-agenda-custom-commands
      '(("cx" "TODOs sorted by state, priority, effort"
         todo "*"
         ((org-agenda-overriding-header "\nTODOs sorted by state, priority, effort")
          (org-agenda-sorting-strategy '(todo-state-down priority-down effort-up))))))

Restrinja-o ao arquivo atual com <. Você pode marcar Concluído e arquivar a partir da exibição classificada.

Filho de um gnu
fonte
1

Você também pode definir uma org-agenda-cmp-user-definedfunção e adicioná-la org-agenda-sorting-strategy. Este é o que eu criei como exemplo.

(setq org-todo-sort-order '("WAIT" "TODO" "DOING" "CANCELED" "DONE"))

(defun my:user-todo-sort (a b)
  "Sort todo based on which I want to see first"
  (when-let ((state-a (get-text-property 14 'todo-state a))
             (state-b (get-text-property 14 'todo-state b))
             (cmp (--map (cl-position-if (lambda (x)
                                           (equal x it))
                                         org-todo-sort-order)
                         (list state-a state-b))))
    (cond ((apply '> cmp) 1)
          ((apply '< cmp) -1)
          (t nil))))
(setq org-agenda-cmp-user-defined 'my:user-todo-sort)
Prgrm.celeritas
fonte
1

Você pode usar esta biblioteca criada por mim: https://github.com/felipelalli/org-sort-tasks

Ele usa o Merge Sort algo perguntando ao usuário se uma tarefa A é mais importante que B e, em seguida, cria uma lista classificada.

Felipe
fonte
Você pode adicionar uma descrição do que isso faz e, em particular, como ele difere das outras respostas.
Andrew Swann
Ele usa o Merge Sort algo perguntando ao usuário se uma tarefa A é mais importante que B e, em seguida, cria uma lista classificada.
Felipe