Fix wrong position after heading edit

pull/645/head
Tienson Qin 2020-05-07 14:25:44 +08:00
parent 52ae2169b6
commit 9e05f0f4a9
4 changed files with 113 additions and 93 deletions

View File

@ -203,22 +203,25 @@
(defn get-matched-commands
[input]
(let [edit-content (gobj/get input "value")
pos (:pos (util/get-caret-pos input))
last-command (subs edit-content
(:pos @*slash-caret-pos)
pos)]
(when (> pos 0)
(or
(and (= \/ (nth edit-content (dec pos)))
;; (or
;; (and
;; (>= (count edit-content) 2)
;; (contains? #{" " "\r" "\n" "\t"} (nth edit-content (- (count edit-content) 2))))
;; (= edit-content "/"))
(commands/commands-map))
(and last-command
(commands/get-matched-commands last-command))))))
(try
(let [edit-content (gobj/get input "value")
pos (:pos (util/get-caret-pos input))
last-command (subs edit-content
(:pos @*slash-caret-pos)
pos)]
(when (> pos 0)
(or
(and (= \/ (nth edit-content (dec pos)))
;; (or
;; (and
;; (>= (count edit-content) 2)
;; (contains? #{" " "\r" "\n" "\t"} (nth edit-content (- (count edit-content) 2))))
;; (= edit-content "/"))
(commands/commands-map))
(and last-command
(commands/get-matched-commands last-command)))))
(catch js/Error e
nil)))
(defn in-auto-complete?
[input]
@ -273,7 +276,6 @@
40 (fn [state e]
(when-not (in-auto-complete? input)
(on-up-down state e false)))
;; backspace
8 (fn [state e]
(let [node (gdom/getElement input-id)
@ -282,18 +284,21 @@
(when (and (> current-pos 1)
(= (nth value (dec current-pos)) "/"))
(reset! *slash-caret-pos nil)
(reset! *show-commands false))
(on-backspace state e)))}
(reset! *show-commands false))))
}
(fn [e key-code]
(swap! state/state assoc
:editor/last-saved-cursor nil)))
(mixins/on-key-up
state
;; /
{191 (fn [state e]
{
;; /
191 (fn [state e]
(when-let [matched-commands (seq (get-matched-commands input))]
(reset! *show-commands true)
(reset! *slash-caret-pos (util/get-caret-pos input))))}
(reset! *slash-caret-pos (util/get-caret-pos input))))
;; backspace
8 on-backspace}
(fn [e key-code]
(when (not= key-code 191) ; not /
(let [matched-commands (get-matched-commands input)]

View File

@ -150,40 +150,41 @@
(defn parse-heading
[{:heading/keys [uuid content meta file page] :as heading} format]
(let [ast (format/to-edn content format nil)
start-pos (:pos meta)
encoded-content (utf8/encode content)
content-length (utf8/length encoded-content)
headings (extract-headings ast content-length)
headings (safe-headings headings)
ref-pages-atom (atom [])
headings (doall
(map-indexed
(fn [idx {:heading/keys [ref-pages meta] :as heading}]
(let [heading (merge
heading
{:heading/file file
:heading/page page
:heading/content (utf8/substring encoded-content
(:pos meta)
(:end-pos meta))}
(when (zero? idx)
{:heading/uuid uuid})
(when (seq ref-pages)
{:heading/ref-pages
(mapv
(fn [page]
(let [page-name (string/capitalize page)
page {:page/name page-name}]
(swap! ref-pages-atom conj page)
page))
ref-pages)}))]
(-> heading
(assoc-in [:heading/meta :pos] (+ (:pos meta) start-pos))
(assoc-in [:heading/meta :end-pos] (+ (:end-pos meta) start-pos)))))
headings))
pages (vec (distinct @ref-pages-atom))]
{:headings headings
:pages pages
:start-pos start-pos
:end-pos (+ start-pos content-length)}))
(when-not (string/blank? content)
(let [ast (format/to-edn content format nil)
start-pos (:pos meta)
encoded-content (utf8/encode content)
content-length (utf8/length encoded-content)
headings (extract-headings ast content-length)
headings (safe-headings headings)
ref-pages-atom (atom [])
headings (doall
(map-indexed
(fn [idx {:heading/keys [ref-pages meta] :as heading}]
(let [heading (merge
heading
{:heading/file file
:heading/page page
:heading/content (utf8/substring encoded-content
(:pos meta)
(:end-pos meta))}
(when (zero? idx)
{:heading/uuid uuid})
(when (seq ref-pages)
{:heading/ref-pages
(mapv
(fn [page]
(let [page-name (string/capitalize page)
page {:page/name page-name}]
(swap! ref-pages-atom conj page)
page))
ref-pages)}))]
(-> heading
(assoc-in [:heading/meta :pos] (+ (:pos meta) start-pos))
(assoc-in [:heading/meta :end-pos] (+ (:end-pos meta) start-pos)))))
headings))
pages (vec (distinct @ref-pages-atom))]
{:headings headings
:pages pages
:start-pos start-pos
:end-pos (+ start-pos content-length)})))

View File

@ -497,9 +497,12 @@
(defn periodically-pull-and-push
[repo-url {:keys [pull-now?]
:or {pull-now? true}}]
;; (periodically-pull repo-url pull-now?)
;; (periodically-push-tasks repo-url)
(when-not config/dev?
(periodically-pull repo-url pull-now?)
(periodically-push-tasks repo-url)))
(periodically-push-tasks repo-url))
)
(defn render-local-images!
[]
@ -649,32 +652,25 @@
(show-notification! "Email already exists!"
:error)))))
(defn get-new-content
[{:heading/keys [uuid content meta dummy?] :as heading} file-content value]
(let [new-content (str value "\n")
new-content (if dummy?
(str "\n" new-content)
new-content)
new-file-content (utf8/insert! file-content
(:pos meta)
(if (or dummy? (string/blank? content))
(:pos meta)
(+ (:pos meta) (utf8/length (utf8/encode content))))
new-content)]
(string/trim new-file-content)))
;; (defn save-heading-if-changed!
;; [{:heading/keys [uuid content meta file dummy?] :as heading} value {:keys [new-content] :as opts}]
;; (let [repo-url (state/get-current-repo)
;; value (string/trim value)]
;; (when (not= (string/trim content) value)
;; (let [file (db/entity (:db/id file))
;; file-content (:file/content file)
;; new-content (or
;; new-content
;; (get-new-content heading file-content value))
;; file-path (:file/path file)]
;; (alter-file repo-url file-path new-content opts)))))
(defn new-file-content
[{:heading/keys [content meta dummy?] :as heading} file-content value]
(let [utf8-content (utf8/encode file-content)
prefix (utf8/substring utf8-content 0 (:pos meta))
postfix (let [end-pos (if dummy?
(:pos meta)
(:end-pos meta))]
(utf8/substring utf8-content end-pos))
value (str
(if (= "\n" (last prefix))
""
"\n")
value
(if (= "\n" (first postfix))
""
"\n"))]
[(str prefix value postfix)
value]))
(defn save-heading-if-changed!
[{:heading/keys [uuid content meta file dummy?] :as heading} value]
@ -686,7 +682,7 @@
file-content (:file/content file)
file-path (:file/path file)
format (format/get-format file-path)
new-content (get-new-content heading file-content value)
[new-content value] (new-file-content heading file-content value)
{:keys [headings pages start-pos end-pos]} (block/parse-heading (assoc heading :heading/content value) format)
after-headings (db/get-file-after-headings repo file-id end-pos)
last-start-pos (atom end-pos)
@ -734,8 +730,7 @@
{:heading/uuid uuid
:heading/meta new-meta}))
after-headings)
new-content (utf8/insert! file-content (:pos meta) (:end-pos meta) "")]
;; update all headings meta after this deleted heading in the same file
new-content (utf8/delete! file-content (:pos meta) (:end-pos meta))]
(db/transact!
(concat
[[:db.fn/retractEntity [:heading/uuid uuid]]]
@ -745,7 +740,8 @@
(alter-file repo
file-path
new-content
{:reset? false}))))
{:reset? false})
)))
(defn clone-and-pull
[repo-url]
@ -841,4 +837,14 @@
[]
(p/let [changes (git/get-status-matrix (state/get-current-repo))]
(prn changes)))
(defn debug-file-and-headings
[path]
(p/let [content (load-file (state/get-current-repo)
path)]
(let [db-content (db/get-file path)
headings (db/get-file-by-concat-headings path)]
(prn {:content content
:utf8-length (utf8/length (utf8/encode content))
:headings headings}))))
)

View File

@ -11,18 +11,22 @@
[s]
(.encode encoder s))
(defn decode
[arr]
(.decode decoder arr))
(defn substring
([arr start]
(->> (.subarray arr start)
(.decode decoder)))
(decode (.subarray arr start)))
([arr start end]
(->> (.subarray arr start end)
(.decode decoder))))
(decode (.subarray arr start end))))
(defn length
[arr]
(gobj/get arr "length"))
;; start-pos inclusive
;; end-pos exclusive
(defn insert!
[s start-pos end-pos content]
(let [arr (encode s)
@ -30,3 +34,7 @@
(str (substring arr 0 start-pos)
content
(substring arr end-pos))))
(defn delete!
[s start-pos end-pos]
(insert! s start-pos end-pos ""))