commit b07ca177d449e58e6e5c14e21e140e63354e335c (HEAD, refs/remotes/origin/master) Author: Dmitry Gutov Date: Fri Jul 31 05:52:53 2015 +0300 Fix default-directory in changeset diffs after vc-print-log * lisp/vc/log-view.el (log-view-diff-common): Move the revision-granularity check back into log-view-diff-changeset. (log-view-diff-changeset): Bind default-directory to the current VC root. diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el index 19bbc45..f1b5710 100644 --- a/lisp/vc/log-view.el +++ b/lisp/vc/log-view.el @@ -607,13 +607,12 @@ considered file(s)." (interactive (list (if (use-region-p) (region-beginning) (point)) (if (use-region-p) (region-end) (point)))) - (log-view-diff-common beg end t)) + (when (eq (vc-call-backend log-view-vc-backend 'revision-granularity) 'file) + (error "The %s backend does not support changeset diffs" log-view-vc-backend)) + (let ((default-directory (vc-root-dir))) + (log-view-diff-common beg end t))) (defun log-view-diff-common (beg end &optional whole-changeset) - (when (and whole-changeset - (eq (vc-call-backend log-view-vc-backend 'revision-granularity) - 'file)) - (error "The %s backend does not support changeset diffs" log-view-vc-backend)) (let ((to (log-view-current-tag beg)) (fr (log-view-current-tag end))) (when (string-equal fr to) commit 6a79a169e7418a82e570936737f67b7f21603b59 Author: Dmitry Gutov Date: Fri Jul 31 05:37:28 2015 +0300 Rename project-directories to project-roots * lisp/progmodes/project.el (project-search-path-function) (project-search-path): Update the docstring. (project-directories): Rename to `project-roots', update all callers and implementations accordingly. (project-root): Remove. * lisp/progmodes/xref.el (xref-find-regexp): Use * instead of *.* as the default file mask. diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el index 9e92fc7..3b06cf7 100644 --- a/lisp/cedet/ede.el +++ b/lisp/cedet/ede.el @@ -1528,8 +1528,8 @@ It does not apply the value to buffers." (when project-dir (ede-directory-get-open-project project-dir 'ROOT)))) -(cl-defmethod project-root ((project ede-project)) - (ede-project-root-directory project)) +(cl-defmethod project-roots ((project ede-project)) + (list (ede-project-root-directory project))) (add-hook 'project-find-functions #'project-try-ede) diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index b7ae3c7..cf34e1a 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -655,6 +655,7 @@ It can be quoted, or be inside a quoted form." (declare-function project-search-path "project") (declare-function project-current "project") +(declare-function project-prune-directories "project") (defun elisp--xref-find-references (symbol) (cl-mapcan diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 44a15dc..2735459 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -37,16 +37,16 @@ that it is not applicable, or a project instance.") (declare-function etags-search-path "etags" ()) (defvar project-search-path-function #'etags-search-path - "Function that returns a list of source directories. + "Function that returns a list of source root directories. -The directories in which we can look for the declarations or -other references to the symbols used in the current buffer. -Depending on the language, it should include the headers search -path, load path, class path, and so on. +The directories in which we can recursively look for the +declarations or other references to the symbols used in the +current buffer. Depending on the language, it should include the +headers search path, load path, class path, or so on. -The directory names should be absolute. Normally set by the -major mode. Used in the default implementation of -`project-search-path'.") +The directory names should be absolute. This variable is +normally set by the major mode. Used in the default +implementation of `project-search-path'.") ;;;###autoload (defun project-current (&optional dir) @@ -54,35 +54,29 @@ major mode. Used in the default implementation of (unless dir (setq dir default-directory)) (run-hook-with-args-until-success 'project-find-functions dir)) -(cl-defgeneric project-root (project) - "Return the root directory of the current project. -The directory name should be absolute.") - +;; FIXME: Add MODE argument, like in `ede-source-paths'? (cl-defgeneric project-search-path (project) - "Return the list of source directories. -Including any where source (or header, etc) files used by the -current project may be found, inside or outside of the project -tree. The directory names should be absolute. - -A specialized implementation should use the value -`project-search-path-function', or, better yet, call and combine -the results from the functions that this value is set to by all -major modes used in the project. Alternatively, it can return a -user-configurable value." - (project--prune-directories - (nconc (funcall project-search-path-function) - ;; Include these, because we don't know any better. - ;; But a specialized implementation may include only some of - ;; the project's subdirectories, if there are no source - ;; files at the top level. - (project-directories project)))) - -(cl-defgeneric project-directories (project) - "Return the list of directories related to the current project. + "Return the list of source root directories. +Any directory roots where source (or header, etc) files used by +the current project may be found, inside or outside of the +current project tree(s). The directory names should be absolute. + +Unless it really knows better, a specialized implementation +should take into account the value returned by +`project-search-path-function' and call +`project-prune-directories' on the result." + (project-prune-directories + (append + ;; We don't know the project layout, like where the sources are, + ;; so we simply include the roots. + (project-roots project) + (funcall project-search-path-function)))) + +(cl-defgeneric project-roots (project) + "Return the list of directory roots related to the current project. It should include the current project root, as well as the roots -of any currently open related projects, if they're meant to be -edited together. The directory names should be absolute." - (list (project-root project))) +of any other currently open projects, if they're meant to be +edited together. The directory names should be absolute.") (cl-defgeneric project-ignores (_project) "Return the list of glob patterns that match ignored files. @@ -103,8 +97,8 @@ end it with `/'." (vc-call-backend backend 'root dir))))) (and root (cons 'vc root)))) -(cl-defmethod project-root ((project (head vc))) - (cdr project)) +(cl-defmethod project-roots ((project (head vc))) + (list (cdr project))) (cl-defmethod project-ignores ((project (head vc))) (nconc @@ -121,10 +115,10 @@ end it with `/'." (defun project-ask-user (dir) (cons 'user (read-directory-name "Project root: " dir nil t))) -(cl-defmethod project-root ((project (head user))) - (cdr project)) +(cl-defmethod project-roots ((project (head user))) + (list (cdr project))) -(defun project--prune-directories (dirs) +(defun project-prune-directories (dirs) "Returns a copy of DIRS sorted, without subdirectories or non-existing ones." (let* ((dirs (sort (mapcar diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 9d0dd77..9764bc7 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -767,6 +767,8 @@ With prefix argument, prompt for the identifier." (interactive (list (xref--read-identifier "Find references of: "))) (xref--show-xrefs identifier 'references identifier nil)) +;; TODO: Rename and move to project-find-regexp, as soon as idiomatic +;; usage of xref from other packages has stabilized. ;;;###autoload (defun xref-find-regexp (regexp) "Find all matches for REGEXP. @@ -777,13 +779,13 @@ to search in, and the file name pattern to search for." (let* ((proj (project-current)) (files (if current-prefix-arg (grep-read-files regexp) - "*.*")) + "*")) (dirs (if current-prefix-arg (list (read-directory-name "Base directory: " nil default-directory t)) - (project--prune-directories - (nconc - (project-directories proj) + (project-prune-directories + (append + (project-roots proj) (project-search-path proj))))) (xref-find-function (lambda (_kind regexp) commit f3f15aef9a2d79252ec061093c25160f29809976 Author: Eli Zaretskii Date: Thu Jul 30 19:50:51 2015 +0300 Support long URLs in w32-shell-execute * src/w32fns.c (Fw32_shell_execute): Don't use filename_to_utf16 and filename_to_ansi to convert the DOCUMENT argument, as it could be a URL that is not limited to MAX_PATH characters. Instead, use MultiByteToWideChar directly, and allocate heap storage as required to accommodate the converted string. Likewise with non-Unicode operation. Ensure OPERATION is null-terminated, even if it is longer than 32K bytes. (Bug#21158) diff --git a/src/w32.c b/src/w32.c index 8721ed9..296729a 100644 --- a/src/w32.c +++ b/src/w32.c @@ -1490,7 +1490,7 @@ static int file_name_codepage; /* Produce a Windows ANSI codepage suitable for encoding file names. Return the information about that codepage in CP_INFO. */ -static int +int codepage_for_filenames (CPINFO *cp_info) { /* A simple cache to avoid calling GetCPInfo every time we need to diff --git a/src/w32.h b/src/w32.h index e62b93c..338cb06 100644 --- a/src/w32.h +++ b/src/w32.h @@ -192,6 +192,7 @@ extern int filename_from_ansi (const char *, char *); extern int filename_to_ansi (const char *, char *); extern int filename_from_utf16 (const wchar_t *, char *); extern int filename_to_utf16 (const char *, wchar_t *); +extern int codepage_for_filenames (CPINFO *); extern Lisp_Object ansi_encode_filename (Lisp_Object); extern int w32_copy_file (const char *, const char *, int, int, int); diff --git a/src/w32fns.c b/src/w32fns.c index 499450f..c742ca8 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7090,6 +7090,8 @@ a ShowWindow flag: const char file_url_str[] = "file:///"; const int file_url_len = sizeof (file_url_str) - 1; + int doclen; + if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0) { /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to @@ -7144,16 +7146,21 @@ a ShowWindow flag: UNGCPRO; current_dir = ENCODE_FILE (current_dir); + /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could + be a URL that is not limited to MAX_PATH chararcters. */ + doclen = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, + SSDATA (document), -1, NULL, 0); + doc_w = xmalloc (doclen * sizeof (wchar_t)); + pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, + SSDATA (document), -1, doc_w, doclen); if (use_unicode) { - wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH]; + wchar_t current_dir_w[MAX_PATH]; SHELLEXECUTEINFOW shexinfo_w; - /* Encode filename, current directory and parameters, and - convert operation to UTF-16. */ + /* Encode the current directory and parameters, and convert + operation to UTF-16. */ filename_to_utf16 (SSDATA (current_dir), current_dir_w); - filename_to_utf16 (SSDATA (document), document_w); - doc_w = document_w; if (STRINGP (parameters)) { int len; @@ -7166,6 +7173,7 @@ a ShowWindow flag: params_w = alloca (len * sizeof (wchar_t)); pMultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, SSDATA (parameters), -1, params_w, len); + params_w[len - 1] = 0; } if (STRINGP (operation)) { @@ -7198,15 +7206,19 @@ a ShowWindow flag: shexinfo_w.nShow = (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); success = ShellExecuteExW (&shexinfo_w); + xfree (doc_w); } else { char document_a[MAX_PATH], current_dir_a[MAX_PATH]; SHELLEXECUTEINFOA shexinfo_a; + int codepage = codepage_for_filenames (NULL); + int ldoc_a = pWideCharToMultiByte (codepage, 0, doc_w, -1, NULL, 0, + NULL, NULL); + doc_a = xmalloc (ldoc_a); + pWideCharToMultiByte (codepage, 0, doc_w, -1, doc_a, ldoc_a, NULL, NULL); filename_to_ansi (SSDATA (current_dir), current_dir_a); - filename_to_ansi (SSDATA (document), document_a); - doc_a = document_a; if (STRINGP (parameters)) { parameters = ENCODE_SYSTEM (parameters); @@ -7229,6 +7241,8 @@ a ShowWindow flag: shexinfo_a.nShow = (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); success = ShellExecuteExA (&shexinfo_a); + xfree (doc_w); + xfree (doc_a); } if (success)