mirror of https://github.com/logseq/logseq
Add tag and url support for follow-link-under-cursor cmd
Plain urls, markdown urls and org mode urls all workpull/3983/head
parent
6e1708b7ba
commit
757ac40fdd
|
@ -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!
|
||||
[]
|
||||
|
|
|
@ -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"))
|
Loading…
Reference in New Issue