Open a link from the keyboard?


#1

Is there a way to open a link the insertion point is within from the keyboard? One of the few times I currently have to move my hand to my mouse is to open links.


#2

That’s a good thought – the keyboard combinations with legible strings attached to them don’t seem to refer to anything, but I may be missing something.

Could certainly be written …

Key Assignment
Backspace deleteBackward
Delete deleteForward
Down moveDown
End scrollToEndOfDocument
Enter insertNewline
Enter smartInsertNewline
Esc cancelOperation
F5 complete
Home scrollToBeginningOfDocument
Left moveLeft
PageDown scrollPageDown
PageUp scrollPageUp
Right moveRight
Space smartInsertSpace
Tab insertTab
Tab smartInsertTab
Up moveUp
^A moveToBeginningOfParagraph
^B moveBackward
^Backspace deleteBackwardByDecomposingPreviousCharacter
^D deleteForward
^Down scrollPageDown
^E moveToEndOfParagraph
^Enter insertLineBreak
^F moveForward
^H deleteBackward
^K deleteToEndOfParagraph
^L centerSelectionInVisibleArea
^Left moveToBeginningOfLine
^N moveDown
^P moveUp
^Right moveToEndOfLine
^T transpose
^Up scrollPageUp
^V pageDown
^Y yank
^⌥Backspace deleteWordBackward
⇧Backspace deleteBackward
⇧Delete deleteForward
⇧Down moveDownAndModifySelection
⇧End moveToEndOfDocumentAndModifySelection
⇧Home moveToBeginningOfDocumentAndModifySelection
⇧Left moveLeftAndModifySelection
⇧PageDown pageDownAndModifySelection
⇧PageUp pageUpAndModifySelection
⇧Right moveRightAndModifySelection
⇧Tab insertBacktab
⇧Up moveUpAndModifySelection
⇧^A moveToBeginningOfParagraphAndModifySelection
⇧^E moveToEndOfParagraphAndModifySelection
⇧^Left moveToBeginningOfLineAndModifySelection
⇧^Right moveToEndOfLineAndModifySelection
⇧^[ shallower heading
⇧^] deeper heading
⇧⌘' show filter panel
⇧⌘9 informal dates and adjustments
⇧⌘Down moveToEndOfDocumentAndModifySelection
⇧⌘Enter insertNewlineAbove
⇧⌘Enter smartInsertNewlineAbove
⇧⌘Left moveToBeginningOfLineAndModifySelection
⇧⌘Right moveToEndOfLineAndModifySelection
⇧⌘T generate Perspective
⇧⌘T generate Perspective
⇧⌘U translate date tags
⇧⌘Up moveToBeginningOfDocumentAndModifySelection
⇧⌘[ fewer heading levels
⇧⌘] more heading levels
⇧⌘^⌥K show map
⇧⌥Down moveParagraphForwardAndModifySelection
⇧⌥Left moveWordLeftAndModifySelection
⇧⌥Right moveWordRightAndModifySelection
⇧⌥Up moveParagraphBackwardAndModifySelection
⌘. cancelOperation
⌘Backspace deleteToBeginningOfLine
⌘Down moveToEndOfDocument
⌘Enter insertNewlineBelow
⌘Enter smartInsertNewlineAfter
⌘Left moveToBeginningOfLine
⌘Right moveToEndOfLine
⌘Up moveToBeginningOfDocument
⌘⌥' informal dates and adjustments
⌘⌥- collapse more
⌘⌥= expand more
⌥Backspace deleteWordBackward
⌥Delete deleteWordForward
⌥Enter insertNewlineIgnoringFieldEditor
⌥Esc complete
⌥Left moveWordLeft
⌥PageDown pageDown
⌥PageUp pageUp
⌥Right moveWordRight
⌥Space insertSpace
⌥Tab insertTabIgnoringFieldEditor

#3

You’d think I would have though of this… but nope… will add to next release.


#4

Any suggested standard keyboard shortcut for this?


#5

Yay! Thanks, Jesse.

Some app I used recently used ⌘⇧O, which I found logical and easy to hit. I can always remap with Keyboard Maestro, though, so I’m not picky.

A related thought: it would be great if this function worked if the insertion point were anywhere inside a Markdown link (for example, right inside the opening bracket—even though it wouldn’t be adjacent to the URL at that point).


#6

If you wanted a primitive stop-gap until Jesse’s next release, you could use something like KeyBoard Maestro to assign ⌘⇧O to a rough script like this. Place your cursor near to a link (or anywhere in the line if there is only one link), and then run the script to open the nearest link.

(Its shelf life will be limited – it uses a function which is not part of the documented and stable API, and which might well change in the next release)

-- Quick sketch of script to open nearest link to cursor
-- Ver 0.2b changes some comments left over from earlier version

property pstrJS : "

	function(editor) {
		var rngSeln = editor.selectedRange(), oNode=rngSeln.startNode,
			lngSelnStart=rngSeln.location()-oNode.lineTextStart(),
			lngSelnEnd= lngSelnStart + rngSeln.length(),
			lngLinkStart, lngLinkEnd,
			lstAttrib=oNode.lineAttributedString()._attributeRuns,
			dctRun, dctAttribs, lngShortest, lngMin, i, strURL;
	
		// Open nearest link to the cursor
		lngMin=Number.POSITIVE_INFINITY; 
		for (i=lstAttrib.length; i--;) {
			dctRun=lstAttrib[i],
			dctAttribs=dctRun.attributes;
			if ('linktarget' in dctAttribs) {
				lngLinkStart = dctRun.location;
				lngLinkEnd = lngLinkStart+dctRun.length;
			
				// distance between link text and cursor ?
				lngShortest = Math.min(
					Math.abs(lngSelnStart- lngLinkEnd),
					Math.abs(lngLinkStart - lngSelnEnd)
				)
				
				// Is this the closest we've seen ?
				if (lngShortest < lngMin) {
					lngMin=lngShortest;
					strURL = dctAttribs.linktarget;
				}
			}
		}
		if (strURL) editor.openLink(strURL);
	}
"

on run
	tell application "FoldingText"
		set lstDocs to documents
		if lstDocs ≠ {} then tell item 1 of lstDocs to (evaluate script pstrJS)
	end tell
end run

#7

This is great! I hope some other users wander in here and grab themselves a copy as well…


#8

Adjusted to Ver 2 (above)

If you place your cursor close to (or on) a link, the script should now open the closest link

(Rather than simply opening the first link it finds, ignoring cursor position, as Ver 1 did)


#9

Is it possible to open a link to a PDF saved on my mac as well?

i could upload the PDF to a webspace but would rather not.

Thanks.


#10

You can select a PDF, or any other file, in the finder, and copy an MD link to it of the form:

[Gurre-Lieder, Dutch National Opera.pdf](file:///Users/houthakker/Desktop/Gurre-Lieder%2C%20Dutch%20National%20Opera.pdf)

by running a script like this, which I have assigned to a keystroke on my system.

FoldingText responds to the opening of local file links like this by displaying the file in the Finder window, so they are a useful way of bookmarking external files from your project text files.


#11

I wanted the link to open automatically (in Preview say) and not jut show in the Finder, else I can just drag the icon to the FT Document window for the same effect. Is that what you would expect?

I tested it on the website and it opened within the web page but ideally I want to open it in Preview on the Mac.


#12

I can just drag the icon to the FT Document window for the same effect

Well, not quite the same effect …

drag the icon to the FT Document window

/Users/houthakker/Desktop/Gurre-Lieder, Dutch National Opera.pdf

(not clickable - apart from the lack of [](), the spaces in the path are unescaped)

whereas,

copy with the script

[Gurre-Lieder, Dutch National Opera.pdf](file:///Users/houthakker/Desktop/Gurre-Lieder%2C%20Dutch%20National%20Opera.pdf)

(clickable)

I can personally quite understand the local file link behaviour which Jesse has chosen - there could be some risks in automatically ‘opening’ any locally linked file, and Javascript is more or less specifically designed to make that hard, but you could ask him what his thinking is there for future versions.


#13

As an alternative, you could try this (at your own risk : -) )

(it gets the shell to pass the url to bash ‘open’)



-- Copyright (C) 2014 Robin Trew
--
-- Permission is hereby granted, free of charge, 
-- to any person obtaining a copy of this software 
-- and associated documentation files (the "Software"), 
-- to deal in the Software without restriction, 
-- including without limitation the rights to use, copy, 
-- modify, merge, publish, distribute, sublicense, 
-- and/or sell copies of the Software, and to permit persons 
-- to whom the Software is furnished to do so, 
-- subject to the following conditions:

-- *******
-- The above copyright notice and this permission notice 
-- shall be included in ALL copies 
-- or substantial portions of the Software.
-- *******

-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
-- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
-- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

property pstrJS : "

	function(editor) {
		var rngSeln = editor.selectedRange(), oNode=rngSeln.startNode,
			lngSelnStart=rngSeln.location()-oNode.lineTextStart(),
			lngSelnEnd= lngSelnStart + rngSeln.length(),
			lngLinkStart, lngLinkEnd,
			lstAttrib=oNode.lineAttributedString()._attributeRuns,
			dctRun, dctAttribs, lngShortest, lngMin, i, strURL;
	
		// Open nearest link to the cursor
		lngMin=Number.POSITIVE_INFINITY; 
		for (i=lstAttrib.length; i--;) {
			dctRun=lstAttrib[i],
			dctAttribs=dctRun.attributes;
			if ('linktarget' in dctAttribs) {
				lngLinkStart = dctRun.location;
				lngLinkEnd = lngLinkStart+dctRun.length;
			
				// distance between link text and cursor ?
				lngShortest = Math.min(
					Math.abs(lngSelnStart- lngLinkEnd),
					Math.abs(lngLinkStart - lngSelnEnd)
				)
				
				// Is this the closest we've seen ?
				if (lngShortest < lngMin) {
					lngMin=lngShortest;
					strURL = dctAttribs.linktarget;
				}
			}
		}
		return strURL;
	}
"

on run
	tell application "FoldingText"
		set lstDocs to documents
		if lstDocs ≠ {} then
			tell item 1 of lstDocs
				set strURL to (evaluate script pstrJS)
				if strURL is not null then do shell script "open " & strURL
			end tell
		end if
	end tell
end run

(still depends on the properly escaped and properly formed links of the kind assembled by the copy script)


#14

Thanks and your points taken, probably better to leave as a link, then a quick cmd-O to open, or I may use my webspace.


#15

@complexpoint You’re a treasure trove. This script will be useful when I need to reference locally stored documents in my FT files.

Sidenote, fwiw: I’m leaning towards storing supporting project files in Evernote, and linking to them via “classic note links” (i.e. links that open in the Evernote client, rather than the web version). This is primarily for portability, so I can open the same links regardless of whether I’m working on OS X or iOS. I use a TextExpander snippet to paste the link that’s generated by Evernote into an FT document as a Markdown link.

Editorial is quite happy to auto-link raw urls in Taskpaper mode, but Markdown links keep things tidy in FoldingText (Editorial doesn’t yet hide the url), and at very least add context.