Add tag and url support for follow-link-under-cursor cmd

Plain urls, markdown urls and org mode urls all work
pull/3983/head
Gabriel Horner 2022-01-19 14:11:13 -05:00 committed by Andelf
parent 6e1708b7ba
commit 757ac40fdd
2 changed files with 102 additions and 29 deletions

View File

@ -1304,46 +1304,76 @@
(let [repo (state/get-current-repo)]
(delete-blocks! repo blocks))))))
(defn- get-nearest-page
"Return the nearset page-name (not dereferenced, may be an alias)"
(def url-regex
"Didn't use link/plain-link as it is incorrectly detects words as urls."
#"[^\s\(\[]+://[^\s\)\]]+")
(defn extract-nearest-link-from-text
[text pos & additional-patterns]
(let [page-pattern #"\[\[([^\]]+)]]"
block-pattern #"\(\(([^\)]+)\)\)"
tag-pattern #"#\S+"
page-matches (util/re-pos page-pattern text)
block-matches (util/re-pos block-pattern text)
tag-matches (util/re-pos tag-pattern text)
additional-matches (mapcat #(util/re-pos % text) additional-patterns)
matches (->> (concat page-matches block-matches tag-matches additional-matches)
(remove nil?))
[_ match] (first (sort-by
(fn [[start-pos content]]
(let [end-pos (+ start-pos (count content))]
(cond
(< pos start-pos)
(- pos start-pos)
(> pos end-pos)
(- end-pos pos)
:else
0)))
>
matches))]
(when match
(cond
(some #(re-find % match) additional-patterns)
match
(string/starts-with? match "#")
(subs match 1 (count match))
:else
(subs match 2 (- (count match) 2))))))
(defn- get-nearest-page-or-link
"Return the nearest page-name (not dereferenced, may be an alias), block, tag or link"
[]
(when-let [block (state/get-edit-block)]
(when (:block/uuid block)
(when-let [edit-id (state/get-edit-input-id)]
(when-let [input (gdom/getElement edit-id)]
(when-let [pos (cursor/pos input)]
(let [value (gobj/get input "value")
page-pattern #"\[\[([^\]]+)]]"
block-pattern #"\(\(([^\)]+)\)\)"
page-matches (util/re-pos page-pattern value)
block-matches (util/re-pos block-pattern value)
matches (->> (concat page-matches block-matches)
(remove nil?))
[_ page] (first (sort-by
(fn [[start-pos content]]
(let [end-pos (+ start-pos (count content))]
(cond
(< pos start-pos)
(- pos start-pos)
(let [value (gobj/get input "value")]
(extract-nearest-link-from-text value pos url-regex))))))))
(> pos end-pos)
(- end-pos pos)
:else
0)))
>
matches))]
(when page
(subs page 2 (- (count page) 2))))))))))
(defn- get-nearest-page
"Return the nearest page-name (not dereferenced, may be an alias), block or tag"
[]
(when-let [block (state/get-edit-block)]
(when (:block/uuid block)
(when-let [edit-id (state/get-edit-input-id)]
(when-let [input (gdom/getElement edit-id)]
(when-let [pos (cursor/pos input)]
(let [value (gobj/get input "value")]
(extract-nearest-link-from-text value pos))))))))
(defn follow-link-under-cursor!
[]
(when-let [page (get-nearest-page)]
(when-let [page (get-nearest-page-or-link)]
(when-not (string/blank? page)
(let [page-name (db-model/get-redirect-page-name page)]
(state/clear-edit!)
(insert-first-page-block-if-not-exists! page-name)
(route-handler/redirect-to-page! page-name)))))
(if (re-find url-regex page)
(js/window.open page)
(let [page-name (db-model/get-redirect-page-name page)]
(state/clear-edit!)
(insert-first-page-block-if-not-exists! page-name)
(route-handler/redirect-to-page! page-name))))))
(defn open-link-in-sidebar!
[]

View File

@ -0,0 +1,43 @@
(ns frontend.handler.editor-test
(:require [frontend.handler.editor :as editor]
[clojure.test :refer [deftest is testing]]))
(deftest extract-nearest-link-from-text-test
(testing "Page, block and tag links"
(is (= "page1"
(editor/extract-nearest-link-from-text "[[page1]] [[page2]]" 0))
"Finds first page link correctly based on cursor position")
(is (= "page2"
(editor/extract-nearest-link-from-text "[[page1]] [[page2]]" 10))
"Finds second page link correctly based on cursor position")
(is (= "tag"
(editor/extract-nearest-link-from-text "#tag [[page1]]" 3))
"Finds tag correctly")
(is (= "61e057b9-f799-4532-9258-cfef6ce58370"
(editor/extract-nearest-link-from-text
"((61e057b9-f799-4532-9258-cfef6ce58370)) #todo" 5))
"Finds block correctly"))
(testing "Url links"
(is (= "https://github.com/logseq/logseq"
(editor/extract-nearest-link-from-text
"https://github.com/logseq/logseq is #awesome :)" 0 editor/url-regex))
"Finds url correctly")
(is (not= "https://github.com/logseq/logseq"
(editor/extract-nearest-link-from-text
"https://github.com/logseq/logseq is #awesome :)" 0))
"Doesn't find url if regex not passed")
(is (= "https://github.com/logseq/logseq"
(editor/extract-nearest-link-from-text
"[logseq](https://github.com/logseq/logseq) is #awesome :)" 0 editor/url-regex))
"Finds url in markdown link correctly"))
(is (= "https://github.com/logseq/logseq"
(editor/extract-nearest-link-from-text
"[[https://github.com/logseq/logseq][logseq]] is #awesome :)" 0 editor/url-regex))
"Finds url in org link correctly"))