Skip to content

Conversation

@shiftkey
Copy link
Member

@shiftkey shiftkey commented Aug 6, 2017

This is my proposed implementation of #2009, and should be simpler than #2039.

First Pass: Make It Work

  • lookup to see if the user has each program installed
    • Atom
    • VSCode
    • Sublime Text
  • Preferences dialog listing available editors and
  • Persist this setting somewhere when it changes (localStorage?)
  • Top-level menu item for "Open in External Editor"
    • ensure this actually launches the selected editor

This should be enough to confirm we're on the right track.

Second Pass - polishing things

  • top-level menu should show the editor name here as well
  • Repository menu item for "Open in External Editor"
  • performance - this lookup could be expensive - cache it for the session
  • macOS should invoke shims instead of launching app
  • docs about how this integration works
  • on first launch, set a default editor - awaiting to lookup of all editors adds +1s on Windows to AppStore.loadInitialState when it fails - maybe i shouldn't do this
  • when the editor doesn't exist, you need to go in to Preferences and manually switch to a different editor (the first one looks like it's selected but lol no) for it to actually update. that's bananas.
  • merge in open Preferences/Options to a given tab #2413 and get "Open Preferences/Options" action to focus on Advanced tab
  • find a faster registry implementation for Windows

Screens and Visuals

With editors found:

  • Preferences view

With no editors found:

  • defaults to Open in Atom - should this be 'Open in External Editor' instead?
  • Preferences view should show "Go install Atom" link instead of select

  • error dialog when you don't have any editors suggests you install Atom

  • error dialog when the editor can't be found, and you have to go to preferences and try again

Assorted other notes:

  • app-path [repo] uses a precompiled binary. I'd rather that use node-gyp from a purist perspective, but we can PR that later unless we have strong feels.

@shiftkey shiftkey force-pushed the open-in-external-editor branch from d4f680a to bd5c93c Compare August 6, 2017 23:06
@j-f1
Copy link
Contributor

j-f1 commented Aug 6, 2017

It might be good to use something like electron-settings to save the preferences to a file that users could potentially edit.

@shiftkey
Copy link
Member Author

shiftkey commented Aug 7, 2017

It might be good to use something like electron-settings to save the preferences to a file that users could potentially edit.

We don't do this for any of our current preferences, so I'm going to defer this to another discussion.

createWindow()

const menu = buildDefaultMenu()
let menu = buildDefaultMenu()

This comment was marked as spam.

{
label: `Open in ${editorLabel}`,
id: 'open-external-editor',
accelerator: 'CmdOrCtrl+Shift+A',

This comment was marked as spam.

This comment was marked as spam.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CmdOrCtrl+Shift+A? Is that really the conventional keystroke shortcut for that command? I seem to remember that command using an E in other apps where I've seen it (though I don't recall the modifier keys).


try {
// invoked without assigning the result so we verify the app is installed
await appPath('com.github.atom')

This comment was marked as spam.

This comment was marked as spam.

'Contents',
'SharedSupport',
'bin',
'subl'

This comment was marked as spam.

const regKey = new Registry({
hive: Registry.HKLM,
key:
'\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1',

This comment was marked as spam.

@shiftkey
Copy link
Member Author

shiftkey commented Aug 7, 2017

While I go through and tidy up the UX corner cases, this is likely ready for some early 👀

*/
export function pathExists(path: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
Fs.exists(path, exists => {

This comment was marked as spam.

This comment was marked as spam.

@shiftkey shiftkey mentioned this pull request Aug 8, 2017
@joshaber joshaber self-assigned this Aug 8, 2017
async function findCodeApplication(): Promise<LookupResult> {
const name = VisualStudioCodeLabel
try {
const installPath = await appPath('com.github.atom')

This comment was marked as spam.

This comment was marked as spam.

@joshaber
Copy link
Contributor

joshaber commented Aug 8, 2017

This seems reasonable so far 👍 I was a little unsure of using the apps' command line launchers, vs. launching the app itself, but after thinking about it I suppose that's probably the better supported launching method anyways.

@shiftkey
Copy link
Member Author

shiftkey commented Aug 8, 2017

I was a little unsure of using the apps' command line launchers, vs. launching the app itself

As in "launching the .app or .exe directly"?

but after thinking about it I suppose that's probably the better supported launching method anyways.

Yeah, these are full-fledged interfaces that are copied over to /usr/local/bin on macOS. My initial testing around this lazily would just invoke the .exe - it took me a couple of attempts to remember that this wasn't right.

$ atom --help
Atom Editor v1.18.0

Usage: atom [options] [path ...]

One or more paths to files or folders may be specified. If there is an
existing Atom window that contains all of the given folders, the paths
will be opened in that window. Otherwise, they will be opened in a new
window.

... 

$ code --help
Visual Studio Code 1.14.2

Usage: code [options] [paths...]

Options:
...

And as Atom points out, the handling of "open a new window" versus "focus existing window" should be handled by the app through these interfaces.

@shiftkey
Copy link
Member Author

shiftkey commented Aug 9, 2017

Some notes after profiling this PR:

Windows

No longer using winreg as I can extract the magic and make this code fast:

  • when an application cannot be found in the registry, failure is reported quickly (~30ms)
  • when an application is found, the registry information is returned to the caller in ~40ms

macOS

  • the result reported from either success or failure is about the same (~25ms)
  • the overall time to resolve all editors is approx ~37ms

@shiftkey shiftkey force-pushed the open-in-external-editor branch from bfec7aa to c8cad9b Compare August 9, 2017 22:55
@donokuda
Copy link
Contributor

Done in cf4514a

@shiftkey
Copy link
Member Author

I might have missed it, but I think we also need to disable the menu item if the repository is missing on disk.

This should be covered by the repository menu being disabled, but 4b8407e makes this more explicit.

@shiftkey
Copy link
Member Author

🌔

Copy link
Contributor

@joshaber joshaber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just needs a merge now and this'll be good to go 🔜

Really nice work on this 💖

case ExternalEditor.SublimeText:
return 'com.sublimetext.3'
default:
return assertNever(editor, `Unknown external editor: ${editor}`)

This comment was marked as spam.

@shiftkey
Copy link
Member Author

🍎

@joshaber
Copy link
Contributor

🕺

'app',
'atom.sh'
)
const exists = await pathExists(path)

This comment was marked as spam.

This comment was marked as spam.

value: string
}

const regPath = 'C:\\Windows\\System32\\reg.exe'

This comment was marked as spam.

This comment was marked as spam.

@zeke
Copy link
Contributor

zeke commented Aug 15, 2017

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review Pull Requests that are ready to be reviewed by the maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants