     (fn [entry hashtags mentions put-fn toggle-edit]
       (let [latest-entry (dissoc entry :comments)
             md-string (or (:md @local-display-entry) "edit here")
-            ts (:timestamp entry)
             get-content #(aget (.. % -target -parentElement -parentElement -firstChild -firstChild) "innerText")
             update-temp-fn #(reset! local-saved-entry (merge latest-entry (h/parse-entry (get-content %))))
             save-fn #(put-fn [:text-entry/update @local-saved-entry])

                        :on-input         update-temp-fn
                        :on-key-down      on-keydown-fn}
                 md-string]]]
         (let [selection (.getSelection js/window)
               cursor-pos (.-anchorOffset selection)
               anchor-node (aget selection "anchorNode")
               node-value (str (when anchor-node (aget anchor-node "nodeValue")) "")
               md (:md @local-saved-entry)
               before-cursor (subs node-value 0 cursor-pos)
               current-tag (re-find (js/RegExp. (str "(?!^)#" h/tag-char-class "+$") "m") before-cursor)
               current-tag-regex (js/RegExp. current-tag "i")
               tag-substr-filter (fn [tag] (when current-tag (re-find current-tag-regex tag)))
               current-mention (re-find (js/RegExp. (str "@" h/tag-char-class  "+$") "m") before-cursor)
               current-mention-regex (js/RegExp. current-mention "i")
               mention-substr-filter (fn [mention] (when current-mention (re-find current-mention-regex mention)))]
           [:div.suggestions
            (for [tag (filter tag-substr-filter hashtags)]
              ^{:key (str ts tag)}
              [:div
               {:on-click #(let [curr-tag-regex (js/RegExp (str current-tag "(?!" h/tag-char-class ")") "i")
                                 updated (merge entry (h/parse-entry (s/replace md curr-tag-regex tag)))]
                            (reset! local-saved-entry updated)
                            (reset! local-display-entry updated))}
               [:span.hashtag tag]])
            (for [mention (filter mention-substr-filter mentions)]
              ^{:key (str ts mention)}
              [:div
               {:on-click #(let [updated (merge entry (h/parse-entry (s/replace md current-mention mention)))]
                            (reset! local-saved-entry updated)
                            (reset! local-display-entry updated))}
               [:span.mention mention]])])
         (when (not= @last-saved @local-saved-entry)
           [:span.not-saved {:on-click save-fn} [:span.fa.fa-floppy-o] "  click to save"])]))))


                           (u/reducer (:mentions entry) u/mentions-replacer))]
      [:div {:dangerouslySetInnerHTML {:__html (md/md->html formatted-md)}}])))

(defn suggestions
  "Renders suggestions for hashtags or mentions if either occurs before the current caret position.
  It does so by getting the selection from the DOM API, which can be used to determine the position
  and a string before that position, then finding either a hashtag or mention fragment right at the
  and of that substring. For these, auto-suggestions are displayed, which are entities that begin
  with the tag fragment before the caret position. When any of the suggestions are clicked, the
  fragment will be replaced with the clicked item."
  [entry hashtags mentions local-saved-entry local-display-entry]
  (let [ts (:ts entry)
        selection (.getSelection js/window)
        cursor-pos (.-anchorOffset selection)
        anchor-node (aget selection "anchorNode")
        node-value (str (when anchor-node (aget anchor-node "nodeValue")) "")
        md (:md @local-saved-entry)
        before-cursor (subs node-value 0 cursor-pos)
        current-tag (re-find (js/RegExp. (str "(?!^)#" h/tag-char-class "+$") "m") before-cursor)
        current-tag-regex (js/RegExp. current-tag "i")
        tag-substr-filter (fn [tag] (when current-tag (re-find current-tag-regex tag)))
        current-mention (re-find (js/RegExp. (str "@" h/tag-char-class  "+$") "m") before-cursor)
        current-mention-regex (js/RegExp. current-mention "i")
        mention-substr-filter (fn [mention] (when current-mention (re-find current-mention-regex mention)))
        tags-fn (fn [tag-substr-filter curr-tag-regex tags]
                  (for [tag (filter tag-substr-filter tags)]
                    ^{:key (str ts tag)}
                    [:div
                     {:on-click #(let [updated (merge entry (h/parse-entry (s/replace md curr-tag-regex tag)))]
                                  (reset! local-saved-entry updated)
                                  (reset! local-display-entry updated))}
                     [:span.hashtag tag]]))]
    [:div.suggestions
     (tags-fn tag-substr-filter (js/RegExp (str current-tag "(?!" h/tag-char-class ")") "i") hashtags)
     (tags-fn mention-substr-filter current-mention mentions)]))

(defn editable-md-render
  "Renders markdown in a pre>code element, with editable content. Sends update message to store
  component on any change to the component. The save button sends updated entry to the backend."
