Skip to content

Commit

Permalink
Make insertion commands more smart
Browse files Browse the repository at this point in the history
  • Loading branch information
louie committed Jan 28, 2018
1 parent 763c036 commit 9ef7759
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 29 deletions.
16 changes: 8 additions & 8 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ anki-editor -- an Emacs package that helps you create Anki cards in Org-mode

** Command Cheatsheet

| Command | Brief Description |
|-----------------------------------------------+---------------------------------------------------------------|
| =anki-editor-submit= | Send notes in current buffer to Anki. |
| =anki-editor-insert-deck= | Insert a deck heading with the same level as current heading. |
| =anki-editor-insert-note= | Insert the skeleton of a note. |
| =anki-editor-insert-tags= | Insert a tag at point with autocompletion. |
| =anki-editor-export-heading-contents-to-html= | Export the contents of the heading at point to HTML. |
| =anki-editor-convert-region-to-html= | Convert and replace region to HTML. |
| Command | Brief Description |
|-----------------------------------------------+------------------------------------------------------|
| =anki-editor-submit= | Send notes in current buffer to Anki. |
| =anki-editor-insert-deck= | Insert a deck heading. |
| =anki-editor-insert-note= | Insert the skeleton of a note. |
| =anki-editor-insert-tags= | Insert a tag at point with autocompletion. |
| =anki-editor-export-heading-contents-to-html= | Export the contents of the heading at point to HTML. |
| =anki-editor-convert-region-to-html= | Convert and replace region to HTML. |


*Since I'm not a native English speaker, let me know if there's any ambiguity or grammatical mistakes.*
Expand Down
128 changes: 107 additions & 21 deletions anki-editor.el
Original file line number Diff line number Diff line change
Expand Up @@ -170,23 +170,46 @@ of that heading."

;;;###autoload
(defun anki-editor-insert-deck (&optional prefix)
"Insert a deck heading with the same level as current heading.
With PREFIX, only insert the deck name."
"Insert a deck heading.
With PREFIX, only insert the deck name at point."
(interactive "P")
(message "Fetching decks...")
(let ((decks (sort (anki-editor--anki-connect-invoke-result "deckNames" 5) #'string-lessp))
deckname)
(setq deckname (completing-read "Choose a deck: " decks))
(unless prefix (org-insert-heading-respect-content))
(insert deckname)
(unless prefix (anki-editor--set-tags-fix anki-editor-deck-tag))))
(if prefix
(insert deckname)
(let (inserted)
(anki-editor--visit-superior-headings
(lambda ()
(when (member anki-editor-deck-tag (org-get-tags))
(anki-editor--insert-deck-heading deckname)
(setq inserted t))))

(unless inserted
(anki-editor--insert-deck-heading deckname))))))

;;;###autoload
(defun anki-editor-insert-note ()
"Insert the skeleton of a note.
The contents to be insrted are structured with a note heading
that's one level lower to the current one as well as subheadings
that correspond to fields."
along with subheadings that correspond to fields.
Where the note is inserted depends on where the point is.
When the point is somewhere inside a note heading, the new note
is inserted below this note with same heading level.
Or when the point is outside any note heading but inside a
heading that isn't tagged with 'deck' but under a deck heading,
the new note is one level lower to and is inserted at the bottom
of this heading.
Or when the point is inside a deck heading, the behavior is the
same as above.
Otherwise, it's inserted at point."
(interactive)
(message "Fetching note types...")
(let ((note-types (sort (anki-editor--anki-connect-invoke-result "modelNames" 5) #'string-lessp))
Expand All @@ -195,19 +218,39 @@ that correspond to fields."
(message "Fetching note fields...")
(setq fields (anki-editor--anki-connect-invoke-result "modelFieldNames" 5 `((modelName . ,note-type)))
note-heading (read-from-minibuffer "Enter the heading: " "Item"))
(org-insert-heading-respect-content)
(org-do-demote)
(insert note-heading)
(anki-editor--set-tags-fix anki-editor-note-tag)
(org-set-property (substring (symbol-name anki-editor-prop-note-type) 1) note-type)
(dolist (field fields)
(save-excursion
(org-insert-heading-respect-content)
(org-do-demote)
(insert field)))
(org-next-visible-heading 1)
(end-of-line)
(newline-and-indent)))

;; find and go to the best position, then insert the note
(let ((cur-point (point))
pt-of-grp
inserted)
(anki-editor--visit-superior-headings
(lambda ()
(let ((tags (org-get-tags)))
(cond
;; if runs into a note heading, inserts the note heading with
;; the same level
((member anki-editor-note-tag tags)
(progn
(anki-editor--insert-note-skeleton note-heading note-type fields)
(setq inserted t)
t))
;; if runs into a deck heading, inserts the note heading one
;; level lower to current deck heading or to the group
;; heading that was visited before
((member anki-editor-deck-tag tags)
(progn
(when pt-of-grp (goto-char pt-of-grp))
(anki-editor--insert-note-skeleton note-heading note-type fields t)
(setq inserted t)
t))
;; otherwise, consider it as a group heading and save its
;; point for further consideration, then continue
(t (progn
(unless pt-of-grp (setq pt-of-grp (point)))
nil))))))
(unless inserted
(goto-char cur-point)
(anki-editor--insert-note-skeleton note-heading note-type fields)))))

;;;###autoload
(defun anki-editor-insert-tags ()
Expand Down Expand Up @@ -246,7 +289,7 @@ that correspond to fields."
"Upgrade anki-connect to the latest version.
This will display a confirmation dialog box in Anki asking if you
want to continue. The upgrading is done by downloading the latest
want to continue. The upgrading is done by downloading the latest
code in the master branch of its Github repo.
This is useful when new version of this package depends on the
Expand All @@ -259,6 +302,12 @@ bugfixes or new features of anki-connect."

;;; Core Functions

(defun anki-editor--insert-deck-heading (deckname)
"Insert a deck heading with DECKNAME."
(org-insert-heading-respect-content)
(insert deckname)
(anki-editor--set-tags-fix anki-editor-deck-tag))

(defun anki-editor--process-note-heading (deck)
"Process note heading at point.
DECK is used when the action is note creation."
Expand All @@ -276,6 +325,28 @@ DECK is used when the action is note creation."
(push `(deck . ,deck) note)
(anki-editor--save-note note)))

(defun anki-editor--insert-note-skeleton (heading note-type fields &optional demote)
"Insert a note skeleton with HEADING, NOTE-TYPE and FIELDS.
If DEMOTE is t, demote the inserted note heading."
(org-insert-heading-respect-content)
(when demote (org-do-demote))
(insert heading)
(anki-editor--set-tags-fix anki-editor-note-tag)
(org-set-property (substring (symbol-name anki-editor-prop-note-type) 1) note-type)
(dolist (field fields)
(save-excursion
(org-insert-heading-respect-content)
(org-do-demote)
(insert field)))

;; TODO: Is it a good idea to automatically move to the first field
;; heading and open a new line ?

;; (org-next-visible-heading 1)
;; (end-of-line)
;; (newline-and-indent)
)

(defun anki-editor--save-note (note)
"Request anki-connect for updating or creating NOTE."
(if (= (alist-get 'note-id note) -1)
Expand Down Expand Up @@ -446,6 +517,21 @@ DECK is used when the action is note creation."
(insert replacement)
(cons original replacement)))

(defun anki-editor--visit-superior-headings (visitor &optional level)
"Move point to and call VISITOR at each superior heading from point.
Don't pass LEVEL, it's only used in recursion.
Stops when VISITOR returns t or point reaches the beginning of buffer."
(let (stop)
(when (org-at-heading-p)
(let ((cur-level (car (org-heading-components))))
(when (or (null level) (< cur-level level))
(setq level cur-level
stop (funcall visitor)))))
(when (and (not stop) (/= (point) (point-min)))
(org-previous-visible-heading 1)
(anki-editor--visit-superior-headings visitor level))))


(provide 'anki-editor)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down

0 comments on commit 9ef7759

Please sign in to comment.