[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#58626: Proposed changes to implement opening URLs on macOS
From: |
Perry Smith |
Subject: |
bug#58626: Proposed changes to implement opening URLs on macOS |
Date: |
Sat, 12 Nov 2022 17:36:07 -0600 |
> On Nov 12, 2022, at 14:57, Stefan Kangas <stefankangas@gmail.com> wrote:
>
> Perry Smith <pedzsan@icloud.com> writes:
>
>> Attached is my patch file based upon the emacs-28.2 tar ball. With
>> these changes, I can do:
>>
>> open emacs:///some/path/to/file.txt#25,40
>
> Could you send the patch in uncompressed instead? That will simplify
> reviewing it.
Please let me know if this doesn’t work...
Only in emacs-28.2-new: .DS_Store
Only in emacs-28.2-new: What-I-Did.txt
Only in emacs-28.2/admin/unidata: unidata-gen.elc
Only in emacs-28.2/admin/unidata: unidata.txt
Only in emacs-28.2/admin/unidata: uvs.elc
Only in emacs-28.2-new/lib: sys
Only in emacs-28.2-new/lib-src: ctags.dSYM
Only in emacs-28.2-new/lib-src: ebrowse.dSYM
Only in emacs-28.2-new/lib-src: emacsclient.dSYM
Only in emacs-28.2-new/lib-src: etags.dSYM
Only in emacs-28.2-new/lib-src: hexl.dSYM
Only in emacs-28.2-new/lib-src: make-docfile.dSYM
Only in emacs-28.2-new/lib-src: make-fingerprint.dSYM
Only in emacs-28.2-new/lib-src: movemail.dSYM
Only in emacs-28.2/lisp: loaddefs.el
Only in emacs-28.2-new/lisp: loaddefs.el~
diff -rc emacs-28.2/lisp/term/common-win.el
emacs-28.2-new/lisp/term/common-win.el
*** emacs-28.2/lisp/term/common-win.el 2022-09-06 16:31:54.000000000 -0500
--- emacs-28.2-new/lisp/term/common-win.el 2022-10-16 07:53:34.000000000 -0500
***************
*** 73,78 ****
--- 73,79 ----
(cons 12 'ns-new-frame)
(cons 13 'ns-toggle-toolbar)
(cons 14 'ns-show-prefs)
+ (cons 15 'ns-open-url)
))))
(set-terminal-parameter frame 'x-setup-function-keys t)))
Binary files emacs-28.2/lisp/term/common-win.elc and
emacs-28.2-new/lisp/term/common-win.elc differ
diff -rc emacs-28.2/lisp/term/ns-win.el emacs-28.2-new/lisp/term/ns-win.el
*** emacs-28.2/lisp/term/ns-win.el 2022-09-06 16:31:54.000000000 -0500
--- emacs-28.2-new/lisp/term/ns-win.el 2022-10-18 11:36:44.000000000 -0500
***************
*** 182,187 ****
--- 182,188 ----
(define-key global-map [ns-new-frame] 'make-frame)
(define-key global-map [ns-toggle-toolbar] 'ns-toggle-toolbar)
(define-key global-map [ns-show-prefs] 'customize)
+ (define-key global-map [ns-open-url] 'ns-open-url)
;; Set up a number of aliases and other layers to pretend we're using
***************
*** 530,535 ****
--- 531,578 ----
(global-set-key [drag-n-drop] 'ns-drag-n-drop)
+ (defvar ns-input-url-scheme) ; nsterm.m
+ (defvar ns-input-url-user) ; nsterm.m
+ (defvar ns-input-url-password) ; nsterm.m
+ (defvar ns-input-url-host) ; nsterm.m
+ (defvar ns-input-url-port) ; nsterm.m
+ (defvar ns-input-url-path) ; nsterm.m
+ (defvar ns-input-url-query) ; nsterm.m
+ (defvar ns-input-url-fragment) ; nsterm.m
+
+ (defun ns-open-url ()
+ "Open a buffer as directed by the URL which has been broken down
+ into components:
+ `ns-input-url-scheme' - the URL's scheme (string)
+ `ns-input-url-user' - the URL's user (string)
+ `ns-input-url-password' - the URL's password (string)
+ `ns-input-url-host' - the URL's host (string)
+ `ns-input-url-port' - the URL's port (integer)
+ `ns-input-url-path' - the URL's path (string)
+ `ns-input-url-query' - the URL's query (string)
+ `ns-input-url-fragment' - the URL's fragment (string)
+ "
+ (interactive)
+ (cond
+ ((equal ns-input-url-scheme "file")
+ (progn (setq ns-input-file (append (list ns-input-url-path)))
+ (setq ns-input-line nil) ; My testing on macOS 12.6 shows the
fragment is never passed
+ (ns-open-file-select-line)))
+ ((equal ns-input-url-scheme "emacs")
+ (progn (setq ns-input-file (append (list ns-input-url-path)))
+ (setq ns-input-line
+ (and ns-input-url-fragment
+ (let ((seq (mapcar #'string-to-number (split-string
ns-input-url-fragment "[-,:]" t))))
+ (cond
+ ((= (length seq) 1) (car seq))
+ ((= (length seq) 2) (cons (car seq) (car (cdr
seq))))))))
+ (ns-open-file-select-line)))
+ (t (message (format "scheme: %s; user: %s; password: %s; host: %s; port:
%d; path: %s; query: %s; fragment: %s"
+ ns-input-url-scheme ns-input-url-user
+ ns-input-url-password ns-input-url-host
+ ns-input-url-port ns-input-url-path
+ ns-input-url-query ns-input-url-fragment)))))
+
;;;; Frame-related functions.
;; nsterm.m
Binary files emacs-28.2/lisp/term/ns-win.elc and
emacs-28.2-new/lisp/term/ns-win.elc differ
Only in emacs-28.2-new/nextstep: .DS_Store
Only in emacs-28.2-new/nextstep/Cocoa/Emacs.base/Contents/Resources:
English.lproj
diff -rc emacs-28.2/nextstep/templates/Info.plist.in
emacs-28.2-new/nextstep/templates/Info.plist.in
*** emacs-28.2/nextstep/templates/Info.plist.in 2022-09-06 16:31:54.000000000
-0500
--- emacs-28.2-new/nextstep/templates/Info.plist.in 2022-10-15
11:31:41.000000000 -0500
***************
*** 672,677 ****
--- 672,687 ----
<string>mailto</string>
</array>
</dict>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLName</key>
+ <string>Emacs Local Address URL</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>emacs</string>
+ </array>
+ </dict>
</array>
<key>NSAppleScriptEnabled</key>
<string>YES</string>
Only in emacs-28.2-new/nextstep/templates: Info.plist.in-orig
diff -rc emacs-28.2/src/nsterm.m emacs-28.2-new/src/nsterm.m
*** emacs-28.2/src/nsterm.m 2022-09-06 16:31:54.000000000 -0500
--- emacs-28.2-new/src/nsterm.m 2022-10-16 12:13:33.000000000 -0500
***************
*** 292,298 ****
static struct input_event *q_event_ptr = NULL;
static int n_emacs_events_pending = 0;
static NSMutableArray *ns_pending_files, *ns_pending_service_names,
! *ns_pending_service_args;
static BOOL ns_do_open_file = NO;
static BOOL ns_last_use_native_fullscreen;
--- 292,298 ----
static struct input_event *q_event_ptr = NULL;
static int n_emacs_events_pending = 0;
static NSMutableArray *ns_pending_files, *ns_pending_service_names,
! *ns_pending_service_args, *ns_pending_urls;
static BOOL ns_do_open_file = NO;
static BOOL ns_last_use_native_fullscreen;
***************
*** 4361,4366 ****
--- 4361,4372 ----
[ns_pending_service_names removeObjectAtIndex: 0];
[ns_pending_service_args removeObjectAtIndex: 0];
}
+ /* Process the open URL requests */
+ else if (ns_pending_urls && [ns_pending_urls count] != 0
+ && [(EmacsApp *) NSApp openURL: [ns_pending_urls
objectAtIndex: 0]])
+ {
+ [ns_pending_urls removeObjectAtIndex: 0];
+ }
else
{
/* Run and wait for events. We must always send one NX_APPDEFINED
event
***************
*** 5123,5128 ****
--- 5129,5135 ----
ns_pending_files = [[NSMutableArray alloc] init];
ns_pending_service_names = [[NSMutableArray alloc] init];
ns_pending_service_args = [[NSMutableArray alloc] init];
+ ns_pending_urls = [[NSMutableArray alloc] init];
/* Start app and create the main menu, window, view.
Needs to be here because ns_initialize_display_info () uses AppKit
classes.
***************
*** 5938,5943 ****
--- 5945,6004 ----
/*
==========================================================================
+ Open URL
+
+ ==========================================================================
*/
+
+ /* Open a URL after going into queue read by ns_read_socket. */
+ - (BOOL) openURL: (NSURL *)url
+ {
+ NSTRACE ("[EmacsApp openURL:]");
+
+ struct frame *emacsframe = SELECTED_FRAME ();
+ NSEvent *theEvent = [NSApp currentEvent];
+
+ if (!emacs_event)
+ return NO;
+
+ emacs_event->kind = NS_NONKEY_EVENT;
+ emacs_event->code = KEY_NS_OPEN_URL;
+ ns_input_url_scheme = [[url scheme] lispString];
+ ns_input_url_user = [[url user] lispString];
+ ns_input_url_password = [[url password] lispString];
+ ns_input_url_host = [[url host] lispString];
+ ns_input_url_port = make_int([[url port] intValue]);
+ ns_input_url_path = [[url path] lispString];
+ ns_input_url_query = [[url query] lispString];
+ ns_input_url_fragment = [[url fragment] lispString];
+ EV_TRAILER (theEvent);
+
+ return YES;
+ }
+
+ /* Notification from the Workspace to open a URL. */
+ - (void)application: sender openURLs: (NSArray<NSURL *> *)urlList
+ {
+ NSEnumerator *urls = [urlList objectEnumerator];
+ NSURL *url;
+
+ NSTRACE ("[EmacsApp openURLs:]");
+ while ((url = [urls nextObject]) != nil)
+ if (ns_do_open_file || not_in_argv ([url path])) {
+ [ns_pending_urls addObject: url];
+ }
+
+ /* The documentation says to do this for openFiles but it is not
+ * mentioned in the openURLs doc so I'm going to leave it out for
+ * now.
+
+ [self replyToOpenOrPrint: NSApplicationDelegateReplySuccess];
+ */
+
+ }
+
+
+ /* ==========================================================================
+
Service provision
========================================================================== */
***************
*** 7004,7010 ****
height = (int)NSHeight (frame);
NSTRACE_SIZE ("New size", NSMakeSize (width, height));
! NSTRACE_SIZE ("Original size", size);
/* Reset the frame size to match the bounds of the superview (the
NSWindow's contentView). We need to do this as sometimes the
--- 7065,7071 ----
height = (int)NSHeight (frame);
NSTRACE_SIZE ("New size", NSMakeSize (width, height));
! NSTRACE_SIZE ("Original size", oldSize);
/* Reset the frame size to match the bounds of the superview (the
NSWindow's contentView). We need to do this as sometimes the
***************
*** 9845,9850 ****
--- 9906,9947 ----
"The file specified in the last NS event.");
ns_input_file =Qnil;
+ /* -- URL components */
+
+ DEFVAR_LISP ("ns-input-url-scheme", ns_input_url_scheme,
+ "The scheme component of the URL specified in the last NS
event.");
+ ns_input_url_scheme =Qnil;
+
+ DEFVAR_LISP ("ns-input-url-user", ns_input_url_user,
+ "The user component of the URL specified in the last NS
event.");
+ ns_input_url_user =Qnil;
+
+ DEFVAR_LISP ("ns-input-url-password", ns_input_url_password,
+ "The password component of the URL specified in the last NS
event.");
+ ns_input_url_password =Qnil;
+
+ DEFVAR_LISP ("ns-input-url-host", ns_input_url_host,
+ "The host component of the URL specified in the last NS
event.");
+ ns_input_url_host =Qnil;
+
+ DEFVAR_LISP ("ns-input-url-port", ns_input_url_port,
+ "The port component of the URL specified in the last NS
event.");
+ ns_input_url_port =Qnil;
+
+ DEFVAR_LISP ("ns-input-url-path", ns_input_url_path,
+ "The path component of the URL specified in the last NS
event.");
+ ns_input_url_path =Qnil;
+
+ DEFVAR_LISP ("ns-input-url-query", ns_input_url_query,
+ "The query component of the URL specified in the last NS
event.");
+ ns_input_url_query =Qnil;
+
+ DEFVAR_LISP ("ns-input-url-fragment", ns_input_url_fragment,
+ "The fragment component of the URL specified in the last NS
event.");
+ ns_input_url_fragment =Qnil;
+
+ /* -- */
+
DEFVAR_LISP ("ns-working-text", ns_working_text,
"String for visualizing working composition sequence.");
ns_working_text =Qnil;
Only in emacs-28.2-new: trace