Git Product home page Git Product logo

org-super-links's Introduction

org-super-links

Create links with auto backlinks is the general idea.

I’m trying to keep this as flexible as possible. There are a few different ways to use this to support different use cases and workflows. See Usage for a more detailed explanation. There are also a few tips and useful functions on the wiki tips page.

I also want to keep this as close to pure org-mode as possible. No external db, no functions required for reading, etc. It should function as just a regular org-mode file. This makes it much more usable for me on my phone. Using beorg or organice for example. It also allows the links to function as normal for exporting and things like that. It’s just pure org.

Contents

Screenshots

Everybody loves screenshots, right?

org-super-links-link images/sl-link.gif

related drawer images/related-drawer.gif

capture template images/capture-template.gif

Super basic example

View the org source to get a better idea of how this looks.

* TODO Test heading target
  :PROPERTIES:
  :ID:       02a5da87-46e5-4ae0-85c1-ee63a570270a
  :END:
  :BACKLINKS:
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][This has a link]]
  :END:

This has a backlink as you can see from the BACKLINKS drawer above.

* TODO This has a link
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99a
  :END:

This has a link pointing to the heading above

[[id:02a5da87-46e5-4ae0-85c1-ee63a570270a][Test heading target]]

Installation

Maybe someday I’ll put this on melpa, but it is not currently.

I personally use straight and use-package for package management. It’s pretty nice.

Install develop branch using straight.

(use-package org-super-links
  :straight (org-super-links :type git :host github :repo "toshism/org-super-links" :branch "develop")
  :bind (("C-c s s" . org-super-links-link)
         ("C-c s l" . org-super-links-store-link)
         ("C-c s C-l" . org-super-links-insert-link)))

You can also use quelpa with quelpa-use-package. Example basic configuration using quelpa:

(use-package org-super-links
  :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.4")
  :bind (("C-c s s" . org-super-links-link)
       ("C-c s l" . org-super-links-store-link)
       ("C-c s C-l" . org-super-links-insert-link)))

Usage

The idea is to keep this as simple as possible and not enforce any particular system or workflow, but to be flexible enough to support many. It’s a simple concept, when you insert a link, insert a backlink at the target.

There are a few different ways you can use this to integrate into your preferred workflow.

Org link replacement

Use it just like you would use regular org links. Instead of calling org-store-link call org-super-links-store-link. Then to insert the link instead of org-insert-link call org-super-links-insert-link. That will insert a link as normal while also adding a backlink at the target of the link. This should work the same as regular org links, with the benefit of adding the backlink.

org-super-links-link

To create a link at point call org-super-links-link. That will bring up the configured search interface (helm-org-ql by default) and allow you to select the target. Once selected a link will be inserted at point, and a backlink added to target.

helm-org-ql/helm-org-rifle action

There is also a helm-org-ql and helm-org-rifle action. To use this method, with the point at the place you would like the link, call helm-org-ql / helm-org-rifle. Select the target of the link and from the actions menu choose Super Link. A link pointing to the selected candidate will be created at point, and a backlink will be added to the target.

capture template

Whenever org-capture is called a link to the current point is automatically stored. To insert this link simply call org-super-links-insert-link. The backlink will be created automatically as usual.

org-super-links-quick-insert-inline-link

Creates a link ignoring the org-super-links-related-into-drawer and org-super-links-link-prefix settings and inserts a link with no prefix at point.

org-super-links-quick-insert-drawer-link

The inverse of org-super-links-quick-insert-inline-link. Insert a link ignoring the org-super-links-related-into-drawer and org-super-links-link-prefix settings. Inserts a link using org-super-links-link-prefix-timestamp for the prefix and either org-super-links-related-into-drawer or org-super-links-related-drawer-default-name for the drawer name. org-super-links-related-into-drawer has precedence if it’s set to a string.

org-super-links-delete-link

Delete the link at point, and the corresponding reverse link. If no reverse link exists, just delete link at point. This works from either side, and deletes both sides of a link.

org-super-links-convert-link-to-super

Convert a normal org-mode link at `point’ to super link. If org-super-links-related-into-drawer is non-nil move the link into drawer.

When called interactively with a C-u prefix argument ignore org-super-links-related-into-drawer configuration and do not modify existing link. Only add the backlink.

Configuration

The variables below allow quite a bit of flexibility to allow you to fit org-super-links into your workflow. None of these are required. My personal config is here

org-super-links-backlink-into-drawer

Controls how/where to insert the backlinks. If non-nil a drawer will be created and backlinks inserted there. The default is BACKLINKS. If this is set to a string a drawer will be created using that string. For example LINKS. If nil backlinks will just be inserted under the heading.

Default: t

org-super-links-backlink-prefix

Prefix to insert before the backlink.

This can be a string, nil, or a function that takes no arguments and returns a string.

Default is the function org-super-links-backlink-prefix-timestamp which returns an inactive timestamp formatted according to the variable org-time-stamp-formats and a separator ` <- `.

org-super-links-backlink-postfix

Postfix to insert after the backlink. This can be a string, nil, or a function that takes no arguments and returns a string

Default nil

org-super-links-related-into-drawer

Controls how/where to insert links. If non-nil a drawer will be created and links inserted there. The default is org-super-links-related-drawer-default-name. If this is set to a string a drawer will be created using that string. For example LINKS. If nil links will just be inserted at point.

Default: nil

org-super-links-related-drawer-default-name

Default name to use for link drawer if org-super-links-related-into-drawer is t. See org-super-links-related-into-drawer for more info. This is also used when calling org-super-links-quick-insert-drawer-link if org-super-links-related-into-drawer is nil.

Default: RELATED

org-super-links-link-prefix

Prefix to insert before the link. This can be a string, nil, or a function that takes no arguments and returns a string

Default nil

org-super-links-link-postfix nil

Postfix to insert after the link. This can be a string, nil, or a function that takes no arguments and returns a string

Default nil

org-super-links-default-description-formatter

What to use if no description is provided. This can be a string, nil or a function that accepts two arguments LINK and DESC and returns a string.

nil will return the default desciption or the link. string will be used only as a default fall back if set. function will be called for every link.

Default is the variable org-make-link-desciption-function.

org-super-links-search-function

The interface to use for finding target links. This can be a string with one of the values ‘helm-org-ql’, ‘helm-org-rifle’, or a function. If you provide a custom function it will be called with the `point` at the location the link should be inserted. The only other requirement is that it should call the function org-super-links--insert-link with the buffer and pos of the target link. AKA the place you want the backlink.

Using helm-org-ql or helm-org-rifle will also add a new action to the respective action menu.

See the functions org-super-links-get-location (in the org-super-links.el file) or org-super-links-org-ql-link-search-interface (in org-super-links-org-ql.el) for examples.

Default is set based on currently installed packages. In order of priority:

  1. “helm-org-ql”
  2. “helm-org-rifle”
  3. org-super-links-get-location

org-super-links-get-location internally uses org-refile-get-location.

Tips

These are just a few tips on things you can do that may be interesting or helpful.

org-id

When creating links it’s generally better to use an id. Add this to your config file so that any headings you link to or from get an id added automatically. I would strongly recommend using this.

(require 'org-id)
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)

quick “related” link

OUTDATED: I’ve added two functions to replace these. org-super-links-quick-insert-drawer-link and org-super-links-quick-insert-inline-link. I’ll leave these here in case someone may still be interested for some reason.

Often when I’m writing I just want to quickly add a link to another heading that may be related. I found it’s convenient to use something like this.

(defun org-super-links-quick-related ()
  (interactive)
  (let ((org-super-links-link-prefix "\nrelated: "))
    (org-super-links-link)))

(global-set-key (kbd "C-c s r") 'org-super-links-quick-related)

Since org-super-links automatically stores the current heading any time you call org-capture. I use this one a lot to just quickly insert a link in the capture template without necessarily wanting to explain the context before I start writing.

(defun org-super-links-quick-insert-related ()
  (interactive)
  (let ((org-super-links-link-prefix "\nrelated: "))
    (org-super-links-insert-link)))

(global-set-key (kbd "C-c s i") 'org-super-links-quick-insert-related)

These quick related links make me think I should possibly add the option to log links into a drawer too. I find myself wanting to do this reasonably often. If anybody else feels the same I’ll probably add that option.

limit length of link description

Sometimes heading titles can get a bit long. You can define a custom function to limit their length and set org-super-links-default-description-formatter. Here’s a very naive way to keep them short. This will blindly truncate all link descriptions to a maximum of 20 characters. You could come up with a more sophisticated function for limiting the length by words or something.

(defun org-super-links-truncate-description (link desc)
  (truncate-string-to-width desc 20))

(setq org-super-links-default-description-formatter 'org-super-links-truncate-description)

The default value of org-super-links-default-description-formatter is set to org-make-link-description so you can also set that to apply the changes to all org-mode links globally.

Index headlines

I’ve found it’s useful to create “index headlines” to make navigating notes convenient. For example I have a hierarchy of locations I use for location specific notes such as restaurant recommendations or vacation planning. These often end up being just a heading with a bunch of backlinks from various notes.

* Locations
** Germany                                                          :germany:
*** Berlin                                                           :berlin:
   :BACKLINKS:
   [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][some restaurant]]
   :END:
*** Wuerzburg                                                     :wuerzburg:
   :BACKLINKS:
   [2020-05-21 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][some other thing]]
   [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99][So and so's house]]
   :END:
** USA
*** Texas                                                             :texas:
**** Amarillo                                                      :amarillo:
   :BACKLINKS:
   [2020-05-21 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][yeah again]]
   [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][rental car place]]
   :END:
**** Austin                                                          :austin:
     etc...

I do a similar thing for any topic I find myself creating a lot of notes for but that I may not want to be under the same heading, or if I want it under multiple headings.

This combination of tags and index headings makes it easy to find things.

My personal setup and configuration

(use-package org-super-links
  :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "develop")
  :bind (("C-c s s" . org-super-links-link)
         ("C-c s l" . org-super-links-store-link)
         ("C-c s C-l" . org-super-links-insert-link)
         ("C-c s d" . org-super-links-quick-insert-drawer-link)
         ("C-c s i" . org-super-links-quick-insert-inline-link)
         ("C-c s C-d" . org-super-links-delete-link))
  :config
  (setq org-super-links-related-into-drawer t
  	org-super-links-link-prefix 'org-super-links-link-prefix-timestamp))

Over time I’ve grown to prefer to just add links and backlinks both into drawers. I map C-c s i to org-super-links-quick-insert-inline-link for the rare occasion where I want a link inline. This ends up functioning sort of zettelkasten style.

drawer size

This is not specific to org-super-links but I like to set the face for drawers to be fairly small and the color close to the background. It helps keep things from looking cluttered when the drawers are collapsed.

I use something like this in my theme.

(org-drawer :foreground "#2F3841" :height 0.8)

That will make the drawer quite small when collapsed but the text inside full size when expanded.

org-export-with-broken-links

If you export subheadings from your org file that have links/backlinks you may want to set org-export-with-broken-links to t. Otherwise you may see an error like

user-error: Unable to resolve link: "*Heading with a backlink"

See issue #22

Related

org-super-links-peek - take a peek at your links

org-linker-edna - link headings as dependencies

org-linker - utility package to serve as a base for linking org headings in various ways

Changelog

  • fixed bug when linking to narrowed buffer
  • fixed bug with converting links to super links when related-into-drawer nil

0.4

  • refactor org-super-links–insert-link
  • change prefix from sl- to org-super-links-

Bugfixes

  • fixed incorrect link when backlink-into-drawer nil

0.3

[2020-09-21]

  • add org-super-links-convert-link-to-super
  • add delete link
  • remove dependency on helm
    • add org-super-links-get-location search function @piater
  • add related into drawer option
  • add quick inserts
    • org-super-links-quick-insert-drawer-link
    • org-super-links-quick-insert-inline-link
  • switch to using markers internally for all positions
  • add hooks
    • org-super-links-pre-link-hook
    • org-super-links-pre-backlink-hook
  • license change to GPLv3
  • support backlinks in org derived modes from @philScholl

Bugfixes

  • fixed bug with org-capture prefix being swallowed (thanks! @piater)
  • respect org-mode link configurations
  • fix possible incorrect link location after buffer modified by hook(s)
  • fix void-variable helm-org-ql-actions bug

0.2

[2020-04-25]

  • Default target heading search changed to helm-org-ql
  • Allow target heading search to be configurable through org-super-links-search-function
  • Add more configuration options for link formatting
  • Support for customizing the default link description org-super-links-default-description-formatter

Bugfixes:

  • fix issue when calling org-capture from a non-org-mode buffer.

0.1

[2020-04-11] First release

Credits

Thanks to:

License

GPLv3

org-super-links's People

Contributors

akirak avatar dasein1998 avatar philscholl avatar piater avatar syohex avatar toshism avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

org-super-links's Issues

prefix args do not reach org-capture

Another follow-up to bugs #1 and #2: Any prefix args given to org-capture do not reach it. The reason is that the (interactive) spec of sl-store-link overrides that of the advised function org-capture. The fix is simple: Duplicate org-capture's (interactive "P") in sl-store-link.

void-variable helm-org-ql-actions

Since (add-to-list 'helm-org-ql-actions '("Super Link" . sl-insert-link-org-ql-action) t) is autoloaded, it should be in a with-eval-after-load to prevent breaking things.

altering buffer structure using hook can result in incorrect link location

when using one of sl-pre-link-hook or sl-pre-backlink-hook it's possible to end up with links pointing to incorrect headings. for example, if the link and backlink headings are in the same buffer, the link heading is above the backlink heading, and sl-pre-link-hook adds multiple lines content to the link side, you could end up with a link to the heading above the intended backlink as it's position is pushed further down in the buffer by the hook.

the same is true if everything is reversed.

The fix is to switch to always using markers instead of buffer/pos internally to track positions.

Problems updating org-super-links package

New features are being added, but it seems updates don't go easy on Windows.
First, I installed GIT on Windows. It seems to be needed to make upgrades.

I had to reinstall QUELPA several times, since I had several errors like this:
Error getting PACKAGE-DESC: (file-error Opening input file No such file or directory c:/.emacs.d/.cache/quelpa/packages/quelpa-20180712.438.tar)
It wrote the readme.txt from org-super-links, but failed when working with the TAR file.

Now this is the debug result I am getting:

Debugger entered--Lisp error: (error "Command ’(git remote show -n origin)’ exited with non-zero status 128: fatal: not a git repository (or any of the parent directories): .git\n")
  signal(error ("Command ’(git remote show -n origin)’ exited with non-zero status 128: fatal: not a git repository (or any of the parent directories): .git\n"))
  error("Command '%s' exited with non-zero status %d: %s" ("git" "remote" "show" "-n" "origin") 128 "fatal: not a git repository (or any of the parent directories): .git\n")
  quelpa-build--run-process("c:/.emacs.d/quelpa/build/org-super-links/" "git" "remote" "show" "-n" "origin")
  apply(quelpa-build--run-process "c:/.emacs.d/quelpa/build/org-super-links/" "git" ("remote" "show" "-n" "origin"))
  quelpa-build--run-process-match("Fetch URL: \\(.*\\)" "c:/.emacs.d/quelpa/build/org-super-links/" "git" "remote" "show" "-n" "origin")
  quelpa-build--git-repo("c:/.emacs.d/quelpa/build/org-super-links/" "origin")
  quelpa-build--checkout-git(org-super-links (:repo "toshism/org-super-links" :fetcher github :commit "0.3" :url "https://github.com/toshism/org-super-links.git") "c:/.emacs.d/quelpa/build/org-super-links/")
  quelpa-build--checkout-github(org-super-links (:repo "toshism/org-super-links" :fetcher github :commit "0.3") "c:/.emacs.d/quelpa/build/org-super-links/")
  quelpa-build-checkout(org-super-links (:repo "toshism/org-super-links" :fetcher github :commit "0.3") "c:/.emacs.d/quelpa/build/org-super-links")
  quelpa-checkout((org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.3") "c:/.emacs.d/quelpa/build/org-super-links")
  quelpa-build((org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.3"))
  quelpa-package-install((org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.3"))
  apply(quelpa-package-install (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.3") nil)
  quelpa((org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.3"))
  apply(quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.3"))
  (if (and quelpa-use-package-inhibit-loading-quelpa (package-installed-p 'org-super-links)) nil (apply 'quelpa '((org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.3"))))
  eval-buffer(#<buffer  *load*> nil "c:/.emacs.d/init.el" nil t)  ; Reading at buffer position 24073
  load-with-code-conversion("c:/.emacs.d/init.el" "c:/.emacs.d/init.el" t t)
  load("c:/.emacs.d/init" noerror nomessage)
  startup--load-user-init-file(#f(compiled-function () #<bytecode 0x10f8411>) #f(compiled-function () #<bytecode 0x10f83c7>) t)
  command-line()
  normal-top-level()

How do you recommend to use bibliographic citations?

It seems to me that it would be nice to have integrated the "cites" with the LINKS.

I am using org-ref time ago, but now it seems necessary some kind of integration.
For example, here there are two Zettels. One has an internal link and the other one a citation:

*** La mayor gloria para la conciencia es
:PROPERTIES:
:ID:       20200818T190646.436481
:END:
LINKS:
- [[id:Vieira.1994.700ExperimentosConscienciologia.C.38]]
:END
el autocontrol.

*** Parece como si para ejercer autocontrol y evitar caer en tentaciones, habría una
barra de energía que se va agotando. Y una vez agotada el comportamiento es guiado por los instintos. 
cite:Dewall.2013.ScientificSecretsSelfcontrol

File mode specification error and post-command-hook error due to missing minor mode declaration

Hi,

I'm running Emacs 27.1.91. I'm running org-super-links version bba93e8.

I have installed org-super-links through straight with:

(use-package org-super-links
  :straight (org-super-links :type git :repo "toshism/org-super-links" :host github :branch "develop")
  :hook org-mode)

and tested it with just use-package:

(use-package org-super-links
  :hook org-mode
  :load-path "~/.emacs.d/straight/repos/org-super-links/")

When entering an org file I see an error:

File mode specification error: (error Autoloading file ~/.emacs.d/straight/repos/org-super-links/org-super-links.el failed to define function org-super-links

and when attempting to run a command on an org file such as org-add-note the command doesn't complete with:

Error in post-command-hook (org-add-log-note): (error "Autoloading file ~/.emacs.d/straight/repos/org-super-links/org-super-links.el failed to define function org-super-links")

I noticed define-minor-mode isn't defined in org-super-links.el. Defining it as:

(define-minor-mode org-super-links
  "org-super-links minor mode")

resolves the above issues. I don't actually know if defining a minor/major mode is required alongside the provide. I wasn't able to find any documentation that told me explicitly. Is there something I'm missing?

Cheers

insert link got error "Wrong type argument: stringp, nil"

the debug info:
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
set-buffer(nil)
(save-current-buffer (set-buffer (marker-buffer marker)) (save-excursion (goto-char (marker-position marker)) (run-hooks hooks) (call-interactively 'org-store-link) (car-safe (prog1 org-stored-links (setq org-stored-links (cdr org-stored-links))))))
org-super-links-links-action(# org-super-links-pre-backlink-hook)
(let* ((source (point-marker)) (source-link (org-super-links-links-action source 'org-super-links-pre-link-hook)) (target-link (org-super-links-links-action target 'org-super-links-pre-backlink-hook)) (source-formatted-link (org-super-links-link-builder source-link)) (target-formatted-link (org-super-links-link-builder target-link))) (save-current-buffer (set-buffer (marker-buffer target)) (save-excursion (goto-char (marker-position target)) (if (derived-mode-p 'org-mode) (progn (org-super-links-insert-backlink (car source-formatted-link) (cdr source-formatted-link)))))) (if no-forward nil (save-current-buffer (set-buffer (marker-buffer source)) (save-excursion (goto-char (marker-position source)) (org-super-links-insert-relatedlink (car target-formatted-link) (cdr target-formatted-link))))))
org-super-links--insert-link(#)
(let ((target (org-refile-get-location "Super Link"))) (org-super-links--insert-link (set-marker (make-marker) (car (cdr (cdr (cdr target)))) (get-file-buffer (car (cdr target))))))
org-super-links-get-location()
funcall(org-super-links-get-location)
(cond ((string= org-super-links-search-function "helm-org-ql") (require 'org-super-links-org-ql) (org-super-links-org-ql-link-search-interface)) ((string= org-super-links-search-function "helm-org-rifle") (require 'org-super-links-org-rifle) (org-super-links-org-rifle-link-search-interface)) (t (funcall org-super-links-search-function)))
org-super-links-search-function()
org-super-links-link()
(let ((org-super-links-related-into-drawer nil) (org-super-links-link-prefix nil)) (org-super-links-link))
org-super-links-quick-insert-inline-link()
funcall-interactively(org-super-links-quick-insert-inline-link)
call-interactively(org-super-links-quick-insert-inline-link record nil)
#f(compiled-function (cmd &optional record-flag keys special) "Execute CMD as an editor command.\nCMD must be a symbol that satisfies the commandp' predicate.\nOptional second arg RECORD-FLAG non-nil\nmeans unconditionally put this command in the variable command-history'.\nOtherwise, that is done only if an arg is read using the minibuffer.\nThe argument KEYS specifies the value to use instead of (this-command-keys)\nwhen reading the arguments; if it is nil, (this-command-keys) is used.\nThe argument SPECIAL, if non-nil, means that this command is executing\na special event, so ignore the prefix argument and don't clear it." #<bytecode 0x404ec17b>)(org-super-links-quick-insert-inline-link record nil nil)
ad-Advice-command-execute(#f(compiled-function (cmd &optional record-flag keys special) "Execute CMD as an editor command.\nCMD must be a symbol that satisfies the commandp' predicate.\nOptional second arg RECORD-FLAG non-nil\nmeans unconditionally put this command in the variable command-history'.\nOtherwise, that is done only if an arg is read using the minibuffer.\nThe argument KEYS specifies the value to use instead of (this-command-keys)\nwhen reading the arguments; if it is nil, (this-command-keys) is used.\nThe argument SPECIAL, if non-nil, means that this command is executing\na special event, so ignore the prefix argument and don't clear it." #<bytecode 0x404ec17b>) org-super-links-quick-insert-inline-link record)
apply(ad-Advice-command-execute #f(compiled-function (cmd &optional record-flag keys special) "Execute CMD as an editor command.\nCMD must be a symbol that satisfies the commandp' predicate.\nOptional second arg RECORD-FLAG non-nil\nmeans unconditionally put this command in the variable command-history'.\nOtherwise, that is done only if an arg is read using the minibuffer.\nThe argument KEYS specifies the value to use instead of (this-command-keys)\nwhen reading the arguments; if it is nil, (this-command-keys) is used.\nThe argument SPECIAL, if non-nil, means that this command is executing\na special event, so ignore the prefix argument and don't clear it." #<bytecode 0x404ec17b>) (org-super-links-quick-insert-inline-link record))
command-execute(org-super-links-quick-insert-inline-link record)
counsel-M-x-action("org-super-links-quick-insert-inline-link")
#f(compiled-function (x) #<bytecode 0xa9365b4b>)("org-super-links-quick-insert-inline-link")
ivy-call()
#f(compiled-function (arg1 arg2 &rest rest) "Read a string in the minibuffer, with completion.\n\nPROMPT is a string, normally ending in a colon and a space.\nivy-count-format' is prepended to PROMPT during completion.\n\nCOLLECTION is either a list of strings, a function, an alist, or\na hash table, supplied for minibuffer-completion-table'.\n\nPREDICATE is applied to filter out the COLLECTION immediately.\nThis argument is for compatibility with completing-read'.\n\nWhen REQUIRE-MATCH is non-nil, only members of COLLECTION can be\nselected.\n\nIf INITIAL-INPUT is non-nil, then insert that input in the\nminibuffer initially.\n\nHISTORY is a name of a variable to hold the completion session\nhistory.\n\nKEYMAP is composed with ivy-minibuffer-map'.\n\nPRESELECT, when non-nil, determines which one of the candidates\nmatching INITIAL-INPUT to select initially. An integer stands\nfor the position of the desired candidate in the collection,\ncounting from zero. Otherwise, use the first occurrence of\nPRESELECT in the collection. Comparison is first done with\nequal'. If that fails, and when applicable, match PRESELECT as\na regular expression.\n\nDEF is for compatibility with completing-read'.\n\nUPDATE-FN is called each time the candidate list is re-displayed.\n\nWhen SORT is non-nil, ivy-sort-functions-alist' determines how\nto sort candidates before displaying them.\n\nACTION is a function to call after selecting a candidate.\nIt takes one argument, the selected candidate. If COLLECTION is\nan alist, the argument is a cons cell, otherwise it's a string.\n\nMULTI-ACTION, when non-nil, is called instead of ACTION when\nthere are marked candidates. It takes the list of candidates as\nits only argument. When it's nil, ACTION is called on each marked\ncandidate.\n\nUNWIND is a function of no arguments to call before exiting.\n\nRE-BUILDER is a function transforming input text into a regex\npattern.\n\nMATCHER is a function which can override how candidates are\nfiltered based on user input. It takes a regex pattern and a\nlist of candidates, and returns the list of matching candidates.\n\nDYNAMIC-COLLECTION is a boolean specifying whether the list of\ncandidates is updated after each input by calling COLLECTION.\n\nEXTRA-PROPS is a plist that can be used to store\ncollection-specific session-specific data.\n\nCALLER is a symbol to uniquely identify the caller to ivy-read'.\nIt is used, along with COLLECTION, to determine which\ncustomizations apply to the current completion session." #<bytecode 0xa8ac640b>)("M-x " ("org-super-links-quick-insert-inline-link" "org-super-links-insert-link" "org-super-links-link" "org-roam-insert" "org-super-links-store-link" "org-super-links-quick-insert-drawer-link" "org-mark-ring-goto" "org-store-link" "balance-windows" "persp-switch" "org-insert-drawer" "org-edit-src-code" "org-archive-subtree" "goto-last-change" "avy-goto-word-1" "avy-goto-word-0" "org-id-goto" "org-cut-subtree" "color-rg-replace-all-matches" "pyim-punctuation-toggle" "org-sidebar-tree" "org-attach" "org-agenda-columns" "org-content" "package-install" "org-toggle-inline-images" "package-refresh-contents" "org-set-property" "xah-open-in-vscode" "org-roam-server-mode" "dired-omit-mode" "multiple-cursors-mode" "list-packages" "mc/mark-next-like-this-word" "org-refile-goto-last-stored" "keyfreq-show" "org-demote-subtree" "org-html-export-to-html" "dired" "magit" "read-only-mode" "org-roam-capture" "cns-mode" "org-copy-subtree" "org-sidebar-toggle" "rg-dwim-current-dir" "org-insert-structure-template" "focus-mode" "org-sidebar" "global-cns-mode" ...) :predicate counsel--M-x-externs-predicate :require-match t :history counsel-M-x-history :action counsel-M-x-action :keymap (keymap (67108908 . counsel--info-lookup-symbol) (67108910 . counsel-find-symbol)) :initial-input nil :caller counsel-M-x :sort t)
apply(#f(compiled-function (arg1 arg2 &rest rest) "Read a string in the minibuffer, with completion.\n\nPROMPT is a string, normally ending in a colon and a space.\nivy-count-format' is prepended to PROMPT during completion.\n\nCOLLECTION is either a list of strings, a function, an alist, or\na hash table, supplied for minibuffer-completion-table'.\n\nPREDICATE is applied to filter out the COLLECTION immediately.\nThis argument is for compatibility with completing-read'.\n\nWhen REQUIRE-MATCH is non-nil, only members of COLLECTION can be\nselected.\n\nIf INITIAL-INPUT is non-nil, then insert that input in the\nminibuffer initially.\n\nHISTORY is a name of a variable to hold the completion session\nhistory.\n\nKEYMAP is composed with ivy-minibuffer-map'.\n\nPRESELECT, when non-nil, determines which one of the candidates\nmatching INITIAL-INPUT to select initially. An integer stands\nfor the position of the desired candidate in the collection,\ncounting from zero. Otherwise, use the first occurrence of\nPRESELECT in the collection. Comparison is first done with\nequal'. If that fails, and when applicable, match PRESELECT as\na regular expression.\n\nDEF is for compatibility with completing-read'.\n\nUPDATE-FN is called each time the candidate list is re-displayed.\n\nWhen SORT is non-nil, ivy-sort-functions-alist' determines how\nto sort candidates before displaying them.\n\nACTION is a function to call after selecting a candidate.\nIt takes one argument, the selected candidate. If COLLECTION is\nan alist, the argument is a cons cell, otherwise it's a string.\n\nMULTI-ACTION, when non-nil, is called instead of ACTION when\nthere are marked candidates. It takes the list of candidates as\nits only argument. When it's nil, ACTION is called on each marked\ncandidate.\n\nUNWIND is a function of no arguments to call before exiting.\n\nRE-BUILDER is a function transforming input text into a regex\npattern.\n\nMATCHER is a function which can override how candidates are\nfiltered based on user input. It takes a regex pattern and a\nlist of candidates, and returns the list of matching candidates.\n\nDYNAMIC-COLLECTION is a boolean specifying whether the list of\ncandidates is updated after each input by calling COLLECTION.\n\nEXTRA-PROPS is a plist that can be used to store\ncollection-specific session-specific data.\n\nCALLER is a symbol to uniquely identify the caller to ivy-read'.\nIt is used, along with COLLECTION, to determine which\ncustomizations apply to the current completion session." #<bytecode 0xa8ac640b>) ("M-x " ("org-super-links-quick-insert-inline-link" "org-super-links-insert-link" "org-super-links-link" "org-roam-insert" "org-super-links-store-link" "org-super-links-quick-insert-drawer-link" "org-mark-ring-goto" "org-store-link" "balance-windows" "persp-switch" "org-insert-drawer" "org-edit-src-code" "org-archive-subtree" "goto-last-change" "avy-goto-word-1" "avy-goto-word-0" "org-id-goto" "org-cut-subtree" "color-rg-replace-all-matches" "pyim-punctuation-toggle" "org-sidebar-tree" "org-attach" "org-agenda-columns" "org-content" "package-install" "org-toggle-inline-images" "package-refresh-contents" "org-set-property" "xah-open-in-vscode" "org-roam-server-mode" "dired-omit-mode" "multiple-cursors-mode" "list-packages" "mc/mark-next-like-this-word" "org-refile-goto-last-stored" "keyfreq-show" "org-demote-subtree" "org-html-export-to-html" "dired" "magit" "read-only-mode" "org-roam-capture" "cns-mode" "org-copy-subtree" "org-sidebar-toggle" "rg-dwim-current-dir" "org-insert-structure-template" "focus-mode" "org-sidebar" "global-cns-mode" ...) :predicate counsel--M-x-externs-predicate :require-match t :history counsel-M-x-history :action counsel-M-x-action :keymap (keymap (67108908 . counsel--info-lookup-symbol) (67108910 . counsel-find-symbol)) :initial-input nil :caller counsel-M-x :sort t))
ivy-read("M-x " ("org-super-links-quick-insert-inline-link" "org-super-links-insert-link" "org-super-links-link" "org-roam-insert" "org-super-links-store-link" "org-super-links-quick-insert-drawer-link" "org-mark-ring-goto" "org-store-link" "balance-windows" "persp-switch" "org-insert-drawer" "org-edit-src-code" "org-archive-subtree" "goto-last-change" "avy-goto-word-1" "avy-goto-word-0" "org-id-goto" "org-cut-subtree" "color-rg-replace-all-matches" "pyim-punctuation-toggle" "org-sidebar-tree" "org-attach" "org-agenda-columns" "org-content" "package-install" "org-toggle-inline-images" "package-refresh-contents" "org-set-property" "xah-open-in-vscode" "org-roam-server-mode" "dired-omit-mode" "multiple-cursors-mode" "list-packages" "mc/mark-next-like-this-word" "org-refile-goto-last-stored" "keyfreq-show" "org-demote-subtree" "org-html-export-to-html" "dired" "magit" "read-only-mode" "org-roam-capture" "cns-mode" "org-copy-subtree" "org-sidebar-toggle" "rg-dwim-current-dir" "org-insert-structure-template" "focus-mode" "org-sidebar" "global-cns-mode" ...) :predicate counsel--M-x-externs-predicate :require-match t :history counsel-M-x-history :action counsel-M-x-action :keymap (keymap (67108908 . counsel--info-lookup-symbol) (67108910 . counsel-find-symbol)) :initial-input nil :caller counsel-M-x)
counsel-M-x()
funcall-interactively(counsel-M-x)
call-interactively(counsel-M-x nil nil)
#f(compiled-function (cmd &optional record-flag keys special) "Execute CMD as an editor command.\nCMD must be a symbol that satisfies the commandp' predicate.\nOptional second arg RECORD-FLAG non-nil\nmeans unconditionally put this command in the variable command-history'.\nOtherwise, that is done only if an arg is read using the minibuffer.\nThe argument KEYS specifies the value to use instead of (this-command-keys)\nwhen reading the arguments; if it is nil, (this-command-keys) is used.\nThe argument SPECIAL, if non-nil, means that this command is executing\na special event, so ignore the prefix argument and don't clear it." #<bytecode 0x404ec17b>)(counsel-M-x nil nil nil)
ad-Advice-command-execute(#f(compiled-function (cmd &optional record-flag keys special) "Execute CMD as an editor command.\nCMD must be a symbol that satisfies the commandp' predicate.\nOptional second arg RECORD-FLAG non-nil\nmeans unconditionally put this command in the variable command-history'.\nOtherwise, that is done only if an arg is read using the minibuffer.\nThe argument KEYS specifies the value to use instead of (this-command-keys)\nwhen reading the arguments; if it is nil, (this-command-keys) is used.\nThe argument SPECIAL, if non-nil, means that this command is executing\na special event, so ignore the prefix argument and don't clear it." #<bytecode 0x404ec17b>) counsel-M-x)
apply(ad-Advice-command-execute #f(compiled-function (cmd &optional record-flag keys special) "Execute CMD as an editor command.\nCMD must be a symbol that satisfies the commandp' predicate.\nOptional second arg RECORD-FLAG non-nil\nmeans unconditionally put this command in the variable command-history'.\nOtherwise, that is done only if an arg is read using the minibuffer.\nThe argument KEYS specifies the value to use instead of (this-command-keys)\nwhen reading the arguments; if it is nil, (this-command-keys) is used.\nThe argument SPECIAL, if non-nil, means that this command is executing\na special event, so ignore the prefix argument and don't clear it." #<bytecode 0x404ec17b>) counsel-M-x)
command-execute(counsel-M-x)

Usage of fragile links instead of IDs like it's shown in the README

Hi,

I tested org-super-links using your example headings from the README. Unfortunately, my result with version 20200611.1550 is different.

My process:

  1. Copy and paste of your headings
  2. Removing BACKLINKS drawer
  3. Place curson or second heading
  4. Invoke C-s s s and search for previous heading
*** TODO Test heading target
  :PROPERTIES:
  :ID:       02a5da87-46e5-4ae0-85c1-ee63a570270a
  :END:
:BACKLINKS:
[2020-07-09 Thu 17:02] <- [[*This has a link][This has a link]]
:END:

This has a backlink as you can see from the BACKLINKS drawer above.

*** TODO This has a link
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99a
  :END:
:RELATED:
[2020-07-09 Thu 17:02] -> [[*Test heading target][Test heading target]]
:END:

This has a link pointing to the heading above

In contrast to my result above, the README shows:

  :BACKLINKS:
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][This has a link]]
  :END:

The second thing that differs is the :RELATED: link which is a good thing to have in my opinion. So I don't mind.

Even though both headings do feature :ID: properties, the link was made using relative links according to the heading title. I can not use those kind of links since they break when heading titles get renamed.

org-super-links-convert-link-to-super fails when org-super-links-related-into-drawer is nil

Just checking out your package because I am working on "updating/modernizing" org-wiki to make it work more like zim (you can find my fork here, but I am just starting, so there is still a lot to be done, for which I will probably take my time). Anyway, I wanted to implement some (enhanced) backlink functionality, and then I found this package which looks very useful.

Anyway, I am just starting checking it out, and I noticed that when trying to org-super-links-convert-link-to-super (without C-u) with org-super-links-related-into-drawer is nil then the formatting of the original link breaks.
Simply the new link format gets inserted, while the original link does not get deleted. To fix it the original link should get deleted before the (org-super-links--insert-link target arg). in the org-super-links-convert-link-to-super function.

Anyway, thanks for your very nice package!

If a heading contains no text, sl-store-link / sl-insert-link fails

Version 0.3:

How to reproduce:

Assume to have to follwoing 2 headings in an org-file:

* TODO Heading A :hgi:
DEADLINE: <2020-10-30 Fr>
:PROPERTIES:
:ID:       23ececef-b9d4-473a-bc02-6a06c4dc8c9a
:END:

* TODO Heading B :hgi:
SCHEDULED: <2020-10-14 Mi>
:PROPERTIES:
:ID:       1778ed38-ee23-4cf4-9ded-5e700913e394
:END:
:LOGBOOK:
- State "TODO"       from "____"       [2020-10-11 So 13:07]
:END:

some text

  1. Place point somewhere under 'Heading A'
  2. M-x sl-store-link
  3. Place point below 'some text' of 'Heading B'
  4. M-x sl-insert-link

Result:
The inserted link refers to 'Heading B' instead to 'Heading A'

Expected result:
The inserted link refers to 'Heading A'

Note:
The backlink however seems to be correct

Error using org-protocol-capture

sl-store-link does not accept the proper arguments. When calling org-capture through org-protocol-capture the sl-store-link function, which is advising org-capture should accept GOTO and KEYS as optional parameters.

Make it a part of org

This package seems useful enough to include into main org distribution. What do you think about contributing to org-mode directly?

Bug after updating emacs?

Hi

It seems that after updating to emacs 27.1 the :LINK: drawer is not generated in the heading where you hit "sl-store-link".

Edit: It seems the drawer is not created in one of my buffers, independently if I hit "sl-store-link" or "sl-insert-link" on it.
Edit 2: Now it works, same buffer, different heading.

:END: Problem: "Anti-bug" discovered

Good night, dear toshism

Time ago a problem goes after us: in the :LINKS: drawer the :END: is like not recognized and we have to go and modify it by hand.
Tonight using your package, as usual, I discovered an "anti-bug" that makes the :END: in the drawer to appear correctly and I thought that maybe it could help you to understand how to solve the problem:

If the body of a note starts with an /italic/ word, the :END: is added correctly when creating the link.

* Note
/here/ the :END: in the drawer works as intended

Is it possible to store a link from the agenda view?

I'm not able to use org-super-links from the agenda view. I mean storing links with the point on an entry on the agenda view or using it with org-capture.

Is this feature not available or am I missing something?

Feature request: autocomplete of link title

Is it possible to quick inset links in a way similar to roam research's method:

as you type words between the brackets, the system would list all the org headline titles which contain the words you typed,
then you can quickly insert the headline link as you choose the target headline from the list.

Is it possible to assign "C-c C-l" to sl-insert-link?

Is it possible to use normal links keybinds (C-c l and C-c C-l) with org-super-links commands? Changing the org-super-links :bind settings in the init file doesn't seem to work.

I would like to try org-super-links as my default link creation tool.

Best regards

Could it be possible to copy a property when inserting a link?

Some times the notes I create are linked to a highlight of a book that has an image attached.

If I want to attach the image to the note too, I have to copy the attahcment's DIR manually.

Is it possible that, when inserting a link, the DIR to be detected and copy to the PROPERTIES drawer?
Example where in both entries I want to show the same image, so it would be helpful to copy the :DIR: property:

HIGHTLIGHT WITH IMAGE:

* Lowenfels, 2010, p. 14                                         :ATTACH:
:PROPERTIES:
:DIR:      ~/NOTAS/data/Lowenfels.2010.TeamingMicrobesOrganic/
:ID:       20201027T051213.039128
:END:
:LINKS:
- [[id:20201027T051213.165136][Las hifas protegen a las raíces, dificultando el acceso a los nematodos que se alimentan de raíces, incluso]]
:END:
[[attachment:Lowenfels.2010.TeamingMicrobesOrganic.p.14.jpg]]
"A foraging, root-eating nematode, trapped by a fungal hypha."

NOTE:

**** Las hifas protegen a las raíces, dificultando el acceso a los nematodos que se alimentan de raíces, incluso
:PROPERTIES:
:ID:       20201027T051213.165136
:DIR:      ~/NOTAS/data/Lowenfels.2010.TeamingMicrobesOrganic/
:END:
:LINKS:
- [[id:20201027T051213.039128][Lowenfels, 2010, p. 14]]
:END:
atrapándolos.
[[attachment:Lowenfels.2010.TeamingMicrobesOrganic.p.14.jpg]]

A thought: maybe it could be customizable to chose what PROPERTIES we want to be copied, so it is not limited just to my needs with attachments, but the user could choose them. Even, maybe the user could choose the DRAWER too.

Spread backlinks to all related headings

Instead of creating just 1 link, could backlinks spread links more widely between related Heads?

For example:

* TODO Test heading target
  :PROPERTIES:
  :ID:       02a5da87-46e5-4ae0-85c1-ee63a570270a
  :END:
  :BACKLINKS:
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][This has a link]]
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99b][This has a link too]]
  :END:

This has 2 backlinks as you can see from the BACKLINKS drawer above.

* TODO This has a link
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99a
  :END:
  :BACKLINKS:
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99b][This has a link too]]
  :END:

This has a link pointing to the heading above.
**And a backlink, which is a Head related to this one, because both point to the same Test heading target**

[[id:02a5da87-46e5-4ae0-85c1-ee63a570270a][Test heading target]]

* TODO This has a link too
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99b
  :END:
  :BACKLINKS:
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][This has a link]]
  :END:

This has a link pointing to the heading above
**And a backlink, which is a Head related to this one, because both point to the same Test heading target**
[[id:02a5da87-46e5-4ae0-85c1-ee63a570270a][Test heading target]]

Could backlinks be created too between second and third Heads, as they are pointing to the same Heading target and so they are related?
This seems a trivial example, but if you have like 20 Headings related with each other, it can be a mess to create a mesh of links and this could be quite elegant solution if is achieved by org-super-links

How to choose the link description everytime?

For some links I prefer to not use description, because my :ID: is self explanatory.

I know org-super-links allows to customize the function that creates the description, but I am too inexpert to configure it. Could you teach how to configure org-super-links to wait for the description, instead of using just the heading?

With backlinks description I am ok ;-)

Add link predicates

There are simple links that do not require a description of the relationship, but it would be very useful to have the option to define the predicate of a (back)link: "instance of", "related to", "member of", or anything else.

For example:

* Emacs
:BACKLINKS:
[2020-08-25 Tue 11:23] <- mode of <- [[id:6c54d566-8e54-47a7-9033-16d9220b08ed][Org-Mode]]
:END:

One way is to be prompted for the type when adding a link. Another is to define a few valid types and then select the right type when prompted.

Inserting a link with org-rifle breaks the target file

So assume you have two files, FS and FT, and I'm trying to reference the header T (in FT) from header S (in FS) using org-rifle (the issue is the same with org-ql). That is, I expect that while standing inside S I call sl-link, select T and together with a forward link to T there is a backlink in T created that points to S. Now, the issue is the following:

Whenever my (inactive) pointer in FT is, say, position F, the call described will:

  1. Insert a backlink in T to S, but without a newline at the end
  2. Return back to the place in FT, insert a newline there, and forward link S to this place (header at F).

I managed to trace down the issue to the org-insert-link call in sl-insert-backlink. What happens, somehow, is that after this function inserts the link, it jumps to the previous position in FT and inserts a newline there (at F), instead of just inserting it after the link. I don't know a way to prevent org-insert-link from doing so, and I don't understand why this happens, since org-insert-link is a huge function. Wrapping sl-insert-backlink in save-excursion also doesn't really help.

I also thought it could be somehow related to org-make-link-description-function, which was deprecated?

I'm really bad at elisp, and I would be really helpful to hear any feedback on this, (I like the library idea a lot!).

PS: in org-super-links-org-rifle.el there's a typo (helm-org-ql when it should be helm-org-rifle) which prevents the rifle action from being turned on.

(with-eval-after-load "helm-org-ql"
  (add-to-list 'helm-org-rifle-actions '("Super Link" . sl-insert-link-rifle-action) t)

sl-link doesn't work for me

I have added this to my configuration, still sl-link gives an error:
(setq sl-search-function 'helm-org-rifle)

sl-link error:
require: Symbol’s value as variable is void: helm-org-rifle-actions

Issue that might relate to dependencies

When inserting a link with sl-link, I'm greeted with this message:

Symbol's value as variable is void: helm-org-ql-actions

I suspect this has something to do with org-ql and helm-org, but both are installed and working. Do you have an idea on why this is happening and how to solve it?

Could every link be in a :BACKLINKS: or :LINKS: drawer?

Hi
I keep enjoying your package. Just a thought:

Usually when I interlink 2 ideas, none of them is more important than the other. So some times it seems kind of "assymetric" to have a link and a :BACKLINK:, like if they were different, while they are doing the same function: add a reference to an idea.

Have you thought about the possibility of having all of the links in a drawer called :LINKS: or something like that?

* TODO Test heading target
  :PROPERTIES:
  :ID:       02a5da87-46e5-4ae0-85c1-ee63a570270a
  :END:
  :LINKS:
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a][This has a link]]
  :END:

This has a link as you can see from the LINKS drawer above.

* TODO This has a link
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99a
  :END:

This has a link pointing to the heading above
 :LINKS:
  [2020-04-11 Sat 00:26] <- [[id:02a5da87-46e5-4ae0-85c1-ee63a570270a][Test heading target]]
  :END:

Assigning dependencies between tasks using org-edna

Hi,

Feature request

I'd like to wish for an extension of org-super-links to be a valuable tool for assigning dependencies between tasks using org-edna. This would improve project management to a great extend since it now requires manual effort and is improving an error prone situation.

I do think that this is also a valid approach for org-super-links since it relates to its very basic goal: linking headings. With this feature, it just adds different kind of links using the same query mechanism and also extending data within drawers.

  • How the process should work from my perspective:
    1. manual step: Cursor is placed within a "source heading".
    2. manual step: Trigger function keyboard binding for this new function such as C-c s t (for "trigger")
      • OPTIONAL: with a given universal argument, this function is only operating/querying the current buffer for performance optimization and a high probable locality of reference.
    3. manual step: Function is querying for a "target heading" and user confirms (using helm, …)
      • Very similar to the current functionality of C-c s s (sl-link).
    4. automatically: Target heading gets a property set: :BLOCKER: ids($ID_OF_SOURCE_HEADING)
      • if existing :BLOCKER: property, the ids($ID_OF_SOURCE_HEADING) gets appended since there can be multiple ids()
      • OPTIONAL: create normal org-super-links-backlink that links back to the source heading as long as this feature request of org-edna is not implemented.
    5. automatically: Source heading gets a property set: :TRIGGER: ids($ID_OF_TARGET_HEADING) todo!(TODO) scheduled!(".")
      • if existing :TRIGGER: property, the new values get appended since there can be multiple sets of values, initiated by ids() or similar.
      • OPTIONAL: ask for the content of scheduled!("") which can be arbitrary date expressions such as "+2d", "mon", …
      • OPTIONAL: ask for the todo keyword which can be TODO, WAITING, STARTED and so forth using tab completion.
      • OPTIONAL: define default todo keyword in a defvar variable (I personally prefer "NEXT" in this context).

(FYI: I'd use all features marked as optional in my daily workflows.)

This way, the user is able to define a dependency between two tasks as easy and as quickly as possible. Depending tasks do feature a backlink via :BLOCKER: properties. Those backlinks do have a different format than existing org-super-links backlinks. This is due to the format definition of org-edna. Maybe an org-super-links backlink can be automatically added as well via preferences. I'd use both links (org-edna-dependency-link + org-super-links-backlinks) as long as this feature request of org-edna is not implemented.

Example for org-edna syntax

A minimal example for plain org-edna syntax is shown to understand its syntax, not demonstrating all the properties mentioned in the algorithm above.

** NEXT my first task
SCHEDULED: <2020-07-11 Sat>
:PROPERTIES:
:ID:       2020-07-09-my-first-task
:TRIGGER: ids(2020-07-09-my-next-task) todo!(NEXT) scheduled!(".")   ids(2020-07-09-another-task) todo!(NEXT) scheduled!("++2d")
:END:

** my next task
:PROPERTIES:
:ID:       2020-07-09-my-next-task
:BLOCKER: ids(2020-07-09-my-first-task) ids(a-totally-different-task-not-shown-here)
:END:

** the task after the next task
:PROPERTIES:
:ID:       2020-07-09-another-task
:BLOCKER: ids(2020-07-09-my-first-task)
:END:

In that example, when the user is setting the first task to DONE, the "next task" gets the todo keyword "NEXT" and a SCHEDULED for the very same day. The task after the next task gets the todo keyword "NEXT" and is scheduled for two days after today.

The :BLOCKER: properties are not necessary for org-edna in this example. They are redundant. However, I'd prefer to have them because this way, any task has clearly defined back-references that work with this org-edna syntax.

Please note that in contrast to org-depend, tasks get their todo keyword only when they are "active". My guess is that this is also speeding up performance of large agenda setups.

You can find another org-edna example project at this issue.

Benefits

Using the proposed feature, all :TRIGGER: and :BLOCKER: properties can be set in this example. It only requires two invocations, both when being at the first heading. It is clearly visible that this helps a lot for optimizing manual effort and providing a full set of meta-data (back-references) while eliminating potential errors.

Using org-edna for defining dependencies like that has further benefits. The user does not need to hide blocked tasks via org-agenda-dim-blocked-tasks which I presume offers better performance. Blocked tasks simply do not necessarily feature a todo keyword at all, thus they aren't taken into account for agenda generation which is a plus.

Having the optional possibility to define arbitrary relative scheduled dates offer maximum flexibility when managing projects.

From my personal point of view, this is the way to do project management with dependencies.

command sl-create-new-target insert the original link

The command meant to create a new heading and link to the original headline.

But it always insert the original headline itself link

but sometimes it works, do not know how to solve the issue, it seems the function " sl-related-to-last-capture" has some problems
My working environment: windows 10 operation system, spacemacs

MY config:

(use-package org-super-links
:bind (("C-c s s" . sl-link)
("C-c s l" . sl-store-link)
("C-c s C-l" . sl-insert-link)))

(require 'org-id)
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)

(defun sl-create-new-target ()
(interactive)
(add-hook 'org-capture-after-finalize-hook 'sl-related-to-last-capture)
(org-capture))

(defun sl-related-to-last-capture ()
(interactive)
(sl--insert-link org-capture-last-stored-marker)
(remove-hook 'org-capture-after-finalize-hook 'sl-related-to-last-capture))

(spacemacs/set-leader-keys-for-major-mode 'org-mode "gi" 'sl-create-new-target)

setup issues: use-package, helm-org-ql-actions

Hi,
Yes, I know that this might be totally off-topic since it's an error that use-package throws, not org-super-links. However, since I used the README of this project to start with quelpa, I think that others following these direction probably can face the very same issue. If not, I'm happy to move this to use-package as well.

What I did:
I set up quelpa for the first time by evaluating the following snippet:

(use-package quelpa
  :ensure t
)

Then I evaluated this:

(use-package org-super-links
  :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2")
  :ensure t
  :bind (("C-c s s" . sl-link)
	   ("C-c s l" . sl-store-link)
	   ("C-c s C-l" . sl-insert-link)))

which resulted in:

Debugger entered--Lisp error: (error "use-package: Unrecognized keyword: :quelpa")
  signal(error ("use-package: Unrecognized keyword: :quelpa"))
  error("use-package: %s" "Unrecognized keyword: :quelpa")
  use-package-normalize-plist(org-super-links (:quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link))) nil use-package-merge-keys)
  use-package-normalize-keywords(org-super-links (:quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link))))
  #f(compiled-function (name &rest args) "Declare an Emacs package by specifying a group of configuration options.\n\nFor full documentation, please see the README file that came with\nthis file.  Usage:\n\n  (use-package package-name\n     [:keyword [option]]...)\n\n:init            Code to run before PACKAGE-NAME has been loaded.\n:config          Code to run after PACKAGE-NAME has been loaded.  Note that\n                 if loading is deferred for any reason, this code does not\n                 execute until the lazy load has occurred.\n:preface         Code to be run before everything except `:disabled'; this\n                 can be used to define functions for use in `:if', or that\n                 should be seen by the byte-compiler.\n\n:mode            Form to be added to `auto-mode-alist'.\n:magic           Form to be added to `magic-mode-alist'.\n:magic-fallback  Form to be added to `magic-fallback-mode-alist'.\n:interpreter     Form to be added to `interpreter-mode-alist'.\n\n:commands        Define autoloads for commands that will be defined by the\n                 package.  This is useful if the package is being lazily\n                 loaded, and you wish to conditionally call functions in your\n                 `:init' block that are defined in the package.\n:hook            Specify hook(s) to attach this package to.\n\n:bind            Bind keys, and define autoloads for the bound commands.\n:bind*           Bind keys, and define autoloads for the bound commands,\n                 *overriding all minor mode bindings*.\n:bind-keymap     Bind a key prefix to an auto-loaded keymap defined in the\n                 package.  This is like `:bind', but for keymaps.\n:bind-keymap*    Like `:bind-keymap', but overrides all minor mode bindings\n\n:defer           Defer loading of a package -- this is implied when using\n                 `:commands', `:bind', `:bind*', `:mode', `:magic', `:hook',\n                 `:magic-fallback', or `:interpreter'.  This can be an integer,\n                 to force loading after N seconds of idle time, if the package\n                 has not already been loaded.\n:after           Delay the use-package declaration until after the named modules\n                 have loaded. Once load, it will be as though the use-package\n                 declaration (without `:after') had been seen at that moment.\n:demand          Prevent the automatic deferred loading introduced by constructs\n                 such as `:bind' (see `:defer' for the complete list).\n\n:if EXPR         Initialize and load only if EXPR evaluates to a non-nil value.\n:disabled        The package is ignored completely if this keyword is present.\n:defines         Declare certain variables to silence the byte-compiler.\n:functions       Declare certain functions to silence the byte-compiler.\n:load-path       Add to the `load-path' before attempting to load the package.\n:diminish        Support for diminish.el (if installed).\n:delight         Support for delight.el (if installed).\n:custom          Call `customize-set-variable' with each variable definition.\n:custom-face     Call `customize-set-faces' with each face definition.\n:ensure          Loads the package using package.el if necessary.\n:pin             Pin the package to an archive." #<bytecode 0x16da3b9>)(org-super-links :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link)))
  macroexpand((use-package org-super-links :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link))) nil)
  macroexp-macroexpand((use-package org-super-links :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link))) nil)
  macroexp--expand-all((use-package org-super-links :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link))))
  macroexpand-all((use-package org-super-links :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link))))
  eval-sexp-add-defvars((use-package org-super-links :quelpa (org-super-links :repo "toshism/org-super-links" :fetcher github :commit "0.2") :ensure t :bind (("C-c s s" . sl-link) ("C-c s l" . sl-store-link) ("C-c s C-l" . sl-insert-link))))
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

I also evaluated quelpa-self-upgrade which did not change the situation. It's quelpa version 20200618.5 which is listed as installed in my list-packages. So the use-package for quelpa must have worked fine.
The issue is the same on Emacs 26.3 on Xubuntu 20.04 as well as 27.0.50 on Debian stable.

Can you give me advice here? Thanks!

Could make "org-super-links sidebar" the using of link descriptions unnecessary? :enhancement:

When adding a description to links, if the linked heading is changed, the link will keep working, but the link description will be "obsolete" as it is already different from the heading from which it was created.

If we used just the ID, with no link description, there would be, usually, a lack of information, as the ID commonly is not auto-descriptive.

Could the coming sidebar detect the links in the drawer and show the headings towards they are directed to? In that way we could use the link without description, and watch the information that the heading brings up, always updated. Example:

Notes:

* TODO Test heading target
  :PROPERTIES:
  :ID:       02a5da87-46e5-4ae0-85c1-ee63a570270a
  :END:
  :BACKLINKS:
  [2020-04-11 Sat 00:26] <- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99a]]
  :END:

This has a backlink as you can see from the BACKLINKS drawer above.

* TODO This has a link
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99a
  :END:
 :LINKS:
[[id:02a5da87-46e5-4ae0-85c1-ee63a570270a]]
:END:
This has a link pointing to the heading above

SIDEBAR 1 for * TODO Test heading target:

 :BACKLINKS:
TODO This has a link
  :END:

SIDEBAR 2 for * TODO This has a link:

 :LINKS:
TODO Test heading target
:END:

Deletion of backlinks

Hi, love the package, thank you for your work!

A suggestion for future enhancement: I feel like it is easy to lose track of the backlinks, since I'd usually just delete a (forward) link by deleting the text directly, but now I'd have a back link with no corresponding forward link.

I am not sure what would be the best behaviour on this case, but if there was at least a function for checking if any link under that heading still exists, I think it would be useful.

Thanks!

Will BACKLINKS drawers be important?

I was able to install org-super-links yesterday, now I must do the settings and use it.
Just a question:
Till now I have been doing backlinks manually, but I used no drawer. Do drawers have a function or will have a function in the future? For example, in the coming sidebar, maybe it is important because :BACKLINKS: drawers will be parsed to show the backlinks?

better options for link formatting

currently you can only change a format string for the backlinks and it has to be time/link/description, or add a prefix. it would be nice to have more control over that.

I would like the forward side links to have some control as well. if it were more configurable it would be easier to fit into different workflows.

Purge time- and date-stamps from generated link descriptions

For similar reasons as #23 I'd like to have org-super-headings remove time- and datestamps as well as their ranges from any generated link description within backlink drawers or outside.

Reasons

Time- and date-stamps within heading titles are meant to be put on the agenda in order to link to this very same heading. When org-super-links is copying those time- and date-stamps to the linked headings as well, they get put on the agenda. I claim that this is not the intention of the majority of the users.

Therefore, the generated link descriptions should not cause the linked heading to be part of the agenda just because of the time- and date-stamps within the copied link titles.

Examples

This is how it look like currently:

- missing examples:
  - inactive date-stamp range
  - inactive time-stamp range
  - time- or datestamp not at the beginning of the heading title
  - recurring time- or date-stamps
  - examples where the time- or date-stamp is the only thing in the heading, resulting in an empty description (omitted in the alternative proposal below)
  - examples with a different locale for weekdays
  - time- or datestamps using sexp syntax
  - examples with different date- and time-stamp formats (I'd ignore these and add this to the package documentation)

******* <2020-08-01 Sat> target active date-stamp
:PROPERTIES:
:ID:       target-active-date-stamp
:END:
:BACKLINKS:
[2020-08-01 Sat 14:40] <- [[id:Example-heading-with-links][Example heading with links]]
:END:

******* [2020-08-01 Sat] target inactive date-stamp
:PROPERTIES:
:ID:       target-inactive-date-stamp
:END:
:BACKLINKS:
[2020-08-01 Sat 14:40] <- [[id:Example-heading-with-links][Example heading with links]]
:END:

******* <2020-08-01 Sat 14:36> target active time-stamp
:PROPERTIES:
:ID:       target-active-time-stamp
:END:
:BACKLINKS:
[2020-08-01 Sat 14:40] <- [[id:Example-heading-with-links][Example heading with links]]
:END:

******* <2020-08-01 Sat 14:00-15:00> target active time-stamp range
:PROPERTIES:
:ID:       target-active-time-stamp-range
:END:
:BACKLINKS:
[2020-08-01 Sat 14:41] <- [[id:Example-heading-with-links][Example heading with links]]
:END:

******* [2020-08-01 Sat 14:36] target inactive time-stamp
:PROPERTIES:
:ID:       target-inactive-time-stamp
:END:
:BACKLINKS:
[2020-08-01 Sat 14:41] <- [[id:Example-heading-with-links][Example heading with links]]
:END:

******* <2020-08-01 Sat>-<2020-08-04 Tue> target active date-stamp range
:PROPERTIES:
:ID:       target-active-date-stamp-range
:END:
:BACKLINKS:
[2020-08-01 Sat 14:41] <- [[id:Example-heading-with-links][Example heading with links]]
:END:

******* Example heading with links (current behavior)
:PROPERTIES:
:ID:       Example-heading-with-links
:END:
[2020-08-01 Sat 14:40] -> [[id:target-active-date-stamp][<2020-08-01 Sat> target active date-stamp]]
[2020-08-01 Sat 14:40] -> [[id:target-inactive-date-stamp][[2020-08-01 Sat] target inactive date-stamp]]
[2020-08-01 Sat 14:40] -> [[id:target-active-time-stamp][<2020-08-01 Sat 14:36> target active time-stamp]]
[2020-08-01 Sat 14:41] -> [[id:target-active-time-stamp-range][<2020-08-01 Sat 14:00-15:00> target active time-stamp range]]
[2020-08-01 Sat 14:41] -> [[id:target-inactive-time-stamp][[2020-08-01 Sat 14:36] target inactive time-stamp]]
[2020-08-01 Sat 14:41] -> [[id:target-active-date-stamp-range][<2020-08-01 Sat>-<2020-08-04 Tue> target active date-stamp range]]

Here is my proposed result:

******* Example heading with links (proposed behavior; purged time- and datestamps)
:PROPERTIES:
:ID:       Example-heading-with-links
:END:
[2020-08-01 Sat 14:40] -> [[id:target-active-date-stamp][target active date-stamp]]
[2020-08-01 Sat 14:40] -> [[id:target-inactive-date-stamp][target inactive date-stamp]]
[2020-08-01 Sat 14:40] -> [[id:target-active-time-stamp][target active time-stamp]]
[2020-08-01 Sat 14:41] -> [[id:target-active-time-stamp-range][target active time-stamp range]]
[2020-08-01 Sat 14:41] -> [[id:target-inactive-time-stamp][[target inactive time-stamp]]
[2020-08-01 Sat 14:41] -> [[id:target-active-date-stamp-range][target active date-stamp range]]

If removing time- and date-stamps does seem to be too harsh, I can think of this alternative result:

******* Example heading with links (proposed behavior; alternative result with ISO time- and datestamps)
:PROPERTIES:
:ID:       Example-heading-with-links
:END:
[2020-08-01 Sat 14:40] -> [[id:target-active-date-stamp][2020-08-01 target active date-stamp]]
[2020-08-01 Sat 14:40] -> [[id:target-inactive-date-stamp][2020-08-01 target inactive date-stamp]]
[2020-08-01 Sat 14:40] -> [[id:target-active-time-stamp][2020-08-01T14:36 target active time-stamp]]
[2020-08-01 Sat 14:41] -> [[id:target-active-time-stamp-range][2020-08-01T14:00-15:00 target active time-stamp range]]
[2020-08-01 Sat 14:41] -> [[id:target-inactive-time-stamp][2020-08-01T14:36 target inactive time-stamp]]
[2020-08-01 Sat 14:41] -> [[id:target-active-date-stamp-range][2020-08-01--2020-08-04 target active date-stamp range]]

Another alternative approach would be to just convert any active time- or date-stamps to inactive ones which still might be error prone with non thoroughly tested modules (additional square brackets within links+description).

Convert existing org-links

I have no idea how difficult it would be, but would be great to be able to convert existing links into super-links alternatively to let regular org-links be treated as super-links (but this might perhaps be into realm of org-roam or similar solutions).

Purge statistics cookies from generated link descriptions

Disclaimer: This is not a bug per se, more a personal strong guess that this might cause issues in various situations which can be easily avoided.

I suggest to remove statistic cookies like [2/5] or [25%] from the generated link descriptions such as:

** [3/5] target heading text
:PROPERTIES:
:ID: the-id
:END:

[...]

** an example heading
:RELATED:
[2020-07-11 Sat 15:24] -> [[id:the-id][[2/5] target heading text]]
:END:

The potential issue here are the nested square brackets. Some less-tested Org packages might stumble over it according my experience.

In my opinion, this can be easily prevented by removing them from the link description. They offer no benefit since they don't get updated when the original heading cookies change as shown in the example above.

When org-super-links creates links, it strips todo keywords such as TODO or WAITING from the link description. The same rationale should be in place with removing statistics cookies as well.

Please note that the position of statistic cookies are not limited to the begin of the heading title.

Can't export related drawers containing non-ID-links

Hi,

I just noticed that there seems to be an issue with exporting to TeX/PDF or Markdown and pretty sure for any format. It seems to be the case that only RELATED drawers containing fragile links (not ID-links):

*** A linked heading for testing
:PROPERTIES:
:CREATED:  [2020-07-09 Thu 23:07]
:END:
:RELATED:
[2020-07-09 Thu 23:08] -> [[*Heading with a backlink using fragile links][Heading with a backlink using fragile links]]
:END:

Results in:
user-error: Unable to resolve link: "*Heading with a backlink using fragile links"

The linked heading exists within the very same buffer. Somehow, the export method does not like that.

I haven't observed this behavior when using ID links.

org-super-links has 2 types of LINKS. Could we choose which one to use each time?

As in the default package behavior, sometimes Related LINKS and BACKLINKS are necessary when interconnecting 2 ideas.
But other times, when interconnecting 2 ideas, 2 Related LINKS can be necessary, making BACKLINKS drawer unsuitable. For example, when one idea helps to understand the other idea and vice versa. In this case both links would be in the same "jerarquichal" level, one shouldn't be a BACKLINK of the other one.

Could it be possible to be prompted what kind of link must be used each time?

For example, here, 2 related links seem to be proper interconection, without BACKLINKS drawer:

* Our sun is 4,500,000,000 years old
  :PROPERTIES:
  :ID:       02a5da87-46e5-4ae0-85c1-ee63a570270aa
  :END:
  :LINKS:
- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99aa][Our sun has about 5,000,000,000 years to go]]
  :END:
This has a related link to a data that can be complementary, and "jerarquically" at the same level.

* Our sun has about 5,000,000,000 years to go
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99aa
  :END:
  :LINKS:
- [[id:02a5da87-46e5-4ae0-85c1-ee63a570270aa][Our sun is 4,500,000,000 years old]]
  :END:
This has a related link to a data that can be complementary, and "jerarquically" at the same level.

Note: I am using :LINKS: drawers for related links in the example, because I think they could be useful, maybe allowing us to let them out when doing searches, or with other functions that the org-super-links package could bring up.

In this other example, on the contrary, the default super-links package behavior seems to be the best approaching. I add this one just with the aim of showing the difference of these 2 types of links (or interconnections):

* An article about our sun
  :PROPERTIES:
  :ID:       02a5da87-46e5-4ae0-85c1-ee63a570270aB
  :END:
  :BACKLINKS:
- [[id:3835d3d0-931a-4a45-a015-a3d6a0baa99aB][Our sun has about 5,000,000,000 years to go]]
  :END:
This article has a lot of information, many ideas and data will be taken from it. 
BACKLINKS help us to have a reference to them.

* Our sun has about 5,000,000,000 years to go
  :PROPERTIES:
  :ID:       3835d3d0-931a-4a45-a015-a3d6a0baa99aB
  :END:
  :LINKS:
- [[id:02a5da87-46e5-4ae0-85c1-ee63a570270aB][Our sun is 4,500,000,000 years old]]
  :END:
This data has a link pointing to the article from which it was taken.

Message when installing using QUELPA

I receive this message. Is it important?

In end of data:
org-super-links.el:442:1:Warning: the function `org-refile-get-location' is
    not known to be defined.

Command:
(quelpa '(org-super-links :repo "toshism/org-super-links" :fetcher github))

org-super-links-insert-link does not behave like org-insert-link

The README indicates that org-super-links-insert-link is a simple replacement for org-insert-link but it isn't.

Specifically, I use org-insert-link to create new links, sometimes using the marked text as the default description. But when run org-super-links-insert-link, it just gives the message No link to insert!. From reading the source, they don't even seem similar.

The org-super-links-link command is closer but doesn't prompt to set the description, which would be helpful

Support org-ql

Currently the search for the target link only supports helm-org-rifle. I think it would be better to use helm-org-ql or maybe support both.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.