commit 6430c4c44f3cbfdaa702302017afbc5d442960f3 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Wed Oct 5 08:31:44 2022 +0800 Fix bug in "macintization" of x_draw_glyph_string * src/nsterm.m (ns_draw_stretch_glyph_string): Restore text decoration drawing code ommitted during "macintization" to convert the X function into NS code. Reported by Qiantan Hong . diff --git a/src/nsterm.m b/src/nsterm.m index b68a6f8ec1..82fe58e90e 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3995,6 +3995,7 @@ Function modeled after x_draw_glyph_string_box (). ns_draw_stretch_glyph_string (struct glyph_string *s) { struct face *face; + NSColor *fg_color; if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p) @@ -4091,8 +4092,20 @@ Function modeled after x_draw_glyph_string_box (). NSRectFill (NSMakeRect (x, s->y, background_width, s->height)); } } -} + /* Draw overlining, etc. on the stretch glyph (or the part of the + stretch glyph after the cursor). If the glyph has a box, then + decorations will be drawn after drawing the box in + ns_draw_glyph_string, in order to prevent them from being + overwritten by the box. */ + if (s->face->box == FACE_NO_BOX) + { + fg_color = [NSColor colorWithUnsignedLong: + NS_FACE_FOREGROUND (s->face)]; + ns_draw_text_decoration (s, s->face, fg_color, + s->background_width, s->x); + } +} static void ns_draw_glyph_string_foreground (struct glyph_string *s) @@ -4410,7 +4423,8 @@ Function modeled after x_draw_glyph_string_box (). { NSColor *fg_color; - fg_color = [NSColor colorWithUnsignedLong:NS_FACE_FOREGROUND (s->face)]; + fg_color = [NSColor colorWithUnsignedLong: NS_FACE_FOREGROUND (s->face)]; + ns_draw_text_decoration (s, s->face, fg_color, s->background_width, s->x); } commit a259d0dda3878a64373b808627c4b4cab3971194 Author: Filipp Gunbin Date: Wed Oct 5 02:46:40 2022 +0300 Add tramp-kubernetes integration * doc/misc/tramp.texi (Inline methods): Add kubernetes. (Customizing Methods): Remove kubernetes-tramp. * etc/NEWS: Mention new Tramp method "kubernetes". * lisp/net/tramp-compat.el (kubernetes-tramp): Warn if that package is used. * lisp/net/tramp-container.el (tramp-kubernetes-program): New defcustom. (tramp-kubernetes-method): New defconst. (tramp-kubernetes--completion-function): New function. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 064a2cb602..395df00bf7 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -917,6 +917,14 @@ running container's name or ID, as returned by @samp{docker ps}. Podman is an alternative to @option{docker} which may be run rootless, if desired. +@item @option{kubernetes} +@cindex method @option{kubernetes} +@cindex @option{kubernetes} method + +Integration for containers in Kubernetes pods. The host name is a pod +name returned by @samp{kubectl get pods}. The first container in a +pod is used. + @end table @@ -1777,15 +1785,6 @@ They can be installed with Emacs's Package Manager. This includes @c @item ibuffer-tramp.el @c Contact Svend Sorensen -@item kubernetes-tramp -@cindex method @option{kubectl} -@cindex @option{kubectl} method -Integration for Docker containers deployed in a Kubernetes cluster. A -container is accessed via -@file{@trampfn{kubectl,user@@container,/path/to/file}}, @samp{user} -and @samp{container} have the same meaning as with the @option{docker} -method. - @item lxc-tramp @cindex method @option{lxc} @cindex @option{lxc} method diff --git a/etc/NEWS b/etc/NEWS index d475c28e45..916abbc436 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2450,8 +2450,9 @@ and friends. ** Tramp +++ -*** New connection methods "docker" and "podman". -It allows accessing environments provided by Docker and similar programs. +*** New connection methods "docker", "podman" and "kubernetes". +They allow accessing environments provided by Docker and similar +programs. --- *** Tramp supports abbreviating remote home directories now. diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index f6cc1034ca..a1d1d284ed 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -52,7 +52,10 @@ (with-eval-after-load 'docker-tramp (warn (concat "Package `docker-tramp' has been obsoleted, " - "please use integrated package `tramp-docker'"))) + "please use integrated package `tramp-container'"))) +(with-eval-after-load 'kubernetes-tramp + (warn (concat "Package `kubernetes-tramp' has been obsoleted, " + "please use integrated package `tramp-container'"))) ;; For not existing functions, obsolete functions, or functions with a ;; changed argument list, there are compiler warnings. We want to diff --git a/lisp/net/tramp-container.el b/lisp/net/tramp-container.el index d1c8f2bb4c..e104babed2 100644 --- a/lisp/net/tramp-container.el +++ b/lisp/net/tramp-container.el @@ -39,6 +39,21 @@ ;; Where: ;; USER is the user on the container to connect as (optional) ;; CONTAINER is the container to connect to +;; +;; +;; Open file in a Kubernetes container: +;; +;; C-x C-f /kubernetes:POD:/path/to/file +;; +;; Where: +;; POD is the pod to connect to. +;; By default, the first container in that pod will be +;; used. +;; +;; Completion for POD and accessing it operate in the current +;; namespace, use this command to change it: +;; +;; "kubectl config set-context --current --namespace=" ;;; Code: @@ -60,6 +75,14 @@ :type '(choice (const "podman") (string))) +;;;###tramp-autoload +(defcustom tramp-kubernetes-program "kubectl" + "Name of the Kubernetes client program." + :group 'tramp + :version "29.1" + :type '(choice (const "kubectl") + (string))) + ;;;###tramp-autoload (defconst tramp-docker-method "docker" "Tramp method name to use to connect to Docker containers.") @@ -68,6 +91,10 @@ (defconst tramp-podman-method "podman" "Tramp method name to use to connect to Podman containers.") +;;;###tramp-autoload +(defconst tramp-kubernetes-method "kubernetes" + "Tramp method name to use to connect to Kubernetes containers.") + ;;;###tramp-autoload (defun tramp-docker--completion-function (&rest _args) "List Docker-like containers available for connection. @@ -88,34 +115,59 @@ see its function help for a description of the format." lines))) (mapcar (lambda (m) (list nil m)) (delq nil names)))) +;;;###tramp-autoload +(defun tramp-kubernetes--completion-function (&rest _args) + "List Kubernetes pods available for connection. + +This function is used by `tramp-set-completion-function', please +see its function help for a description of the format." + (when-let ((raw-list (shell-command-to-string + (concat tramp-kubernetes-program + " get pods --no-headers " + "-o custom-columns=NAME:.metadata.name"))) + (names (split-string raw-list "\n" 'omit))) + (mapcar (lambda (name) + (list nil name)) + names))) + ;;;###tramp-autoload (defvar tramp-default-remote-shell) ;; Silence byte compiler. ;;;###tramp-autoload (tramp--with-startup - (push `(,tramp-docker-method - (tramp-login-program ,tramp-docker-program) - (tramp-login-args (("exec") - ("-it") - ("-u" "%u") - ("%h") - ("%l"))) - (tramp-remote-shell ,tramp-default-remote-shell) - (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-i" "-c"))) - tramp-methods) - - (push `(,tramp-podman-method - (tramp-login-program ,tramp-podman-program) - (tramp-login-args (("exec") - ("-it") - ("-u" "%u") - ("%h") - ("%l"))) - (tramp-remote-shell ,tramp-default-remote-shell) - (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-i" "-c"))) - tramp-methods) + (add-to-list 'tramp-methods + `(,tramp-docker-method + (tramp-login-program ,tramp-docker-program) + (tramp-login-args (("exec") + ("-it") + ("-u" "%u") + ("%h") + ("%l"))) + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-i" "-c")))) + (add-to-list 'tramp-methods + `(,tramp-podman-method + (tramp-login-program ,tramp-podman-program) + (tramp-login-args (("exec") + ("-it") + ("-u" "%u") + ("%h") + ("%l"))) + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-i" "-c")))) + (add-to-list 'tramp-methods + `(,tramp-kubernetes-method + (tramp-login-program ,tramp-kubernetes-program) + (tramp-login-args (("exec") + ("%h") + ("-it") + ("--") + ("%l"))) + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-i" "-c")))) (tramp-set-completion-function tramp-docker-method @@ -123,7 +175,11 @@ see its function help for a description of the format." (tramp-set-completion-function tramp-podman-method - '((tramp-docker--completion-function "")))) + '((tramp-docker--completion-function ""))) + + (tramp-set-completion-function + tramp-kubernetes-method + '((tramp-kubernetes--completion-function "")))) (add-hook 'tramp-unload-hook (lambda () commit e4e9cb265c61850b70f3bec595a179663b2a5837 Author: Filipp Gunbin Date: Wed Oct 5 02:16:36 2022 +0300 Rename lisp/net/tramp-docker.el to lisp/net/tramp-container.el diff --git a/lisp/net/tramp-docker.el b/lisp/net/tramp-container.el similarity index 92% rename from lisp/net/tramp-docker.el rename to lisp/net/tramp-container.el index b74bdddddd..d1c8f2bb4c 100644 --- a/lisp/net/tramp-docker.el +++ b/lisp/net/tramp-container.el @@ -1,4 +1,4 @@ -;;; tramp-docker.el --- Tramp integration for Docker-like containers -*- lexical-binding: t; -*- +;;; tramp-container.el --- Tramp integration for Docker-like containers -*- lexical-binding: t; -*- ;; Copyright © 2022 Free Software Foundation, Inc. @@ -23,8 +23,8 @@ ;;; Commentary: -;; ‘tramp-docker’ allows Tramp access to environments provided by -;; Docker and similar programs. +;; Allows Tramp access to environments provided by Docker and similar +;; programs. ;; ;; ## Usage ;; @@ -127,8 +127,8 @@ see its function help for a description of the format." (add-hook 'tramp-unload-hook (lambda () - (unload-feature 'tramp-docker 'force))) + (unload-feature 'tramp-container 'force))) -(provide 'tramp-docker) +(provide 'tramp-container) -;;; tramp-docker.el ends here +;;; tramp-container.el ends here commit 219cbccb9ac1d25df5534b60c0c6a6071b2303ed Author: Vibhav Pant Date: Wed Oct 5 01:01:50 2022 +0530 Add comment explaining gcc_jit_context_new_bitcast usage. diff --git a/src/comp.c b/src/comp.c index 794501f11b..b7541c5d9f 100644 --- a/src/comp.c +++ b/src/comp.c @@ -1179,6 +1179,11 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) gcc_jit_rvalue *tmp = obj; + /* `gcc_jit_context_new_bitcast` requires that the types being converted + between have the same layout and as such, doesn't allow converting + between an arbitrarily sized integer/boolean and a pointer. Casting it + to a uintptr/void* is still necessary, to ensure that it can be bitcast + into a (void *)/uintptr respectively. */ if (old_is_ptr != new_is_ptr) { if (old_is_ptr) commit df5cb9b2a35f33f02a00bcba8e6e044cb7fe737d Author: Vibhav Pant Date: Sun Oct 2 22:15:33 2022 +0530 Address styling comments. diff --git a/src/comp.c b/src/comp.c index 36fdff890d..794501f11b 100644 --- a/src/comp.c +++ b/src/comp.c @@ -385,7 +385,7 @@ init_gccjit_functions (void) #define gcc_jit_context_new_array_access fn_gcc_jit_context_new_array_access #define gcc_jit_context_new_array_type fn_gcc_jit_context_new_array_type #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast - #define gcc_jit_context_new_bitcast fn_gcc_jit_context_new_bitcast +# define gcc_jit_context_new_bitcast fn_gcc_jit_context_new_bitcast #endif #define gcc_jit_context_new_binary_op fn_gcc_jit_context_new_binary_op #define gcc_jit_context_new_call fn_gcc_jit_context_new_call @@ -430,7 +430,7 @@ init_gccjit_functions (void) #define gcc_jit_struct_as_type fn_gcc_jit_struct_as_type #define gcc_jit_struct_set_fields fn_gcc_jit_struct_set_fields #ifdef LIBGCCJIT_HAVE_REFLECTION -#define gcc_jit_type_is_pointer fn_gcc_jit_type_is_pointer +# define gcc_jit_type_is_pointer fn_gcc_jit_type_is_pointer #endif #define gcc_jit_type_get_const fn_gcc_jit_type_get_const #define gcc_jit_type_get_pointer fn_gcc_jit_type_get_pointer @@ -541,7 +541,7 @@ typedef struct { static f_reloc_t freloc; #ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast -#define NUM_CAST_TYPES 15 +# define NUM_CAST_TYPES 15 #endif typedef struct { @@ -1197,7 +1197,9 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) } } return gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, new_type); -#else /* !defined(LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast) */ + +#else /* !LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast */ + int old_index = type_to_cast_index (old_type); int new_index = type_to_cast_index (new_type); @@ -3392,7 +3394,6 @@ define_type_punning (const char *name, DECL_BLOCK (entry_block, result); - gcc_jit_lvalue *tmp_union = gcc_jit_function_new_local (result, NULL, @@ -3479,7 +3480,6 @@ define_cast_functions (void) { comp.unsigned_long_type, "unsigned_long", false }, { comp.unsigned_type, "unsigned", false }, { comp.void_ptr_type, "void_ptr", true } }; - gcc_jit_field *cast_union_fields[2]; /* Define the union used for type punning. */ @@ -3519,7 +3519,7 @@ define_cast_functions (void) comp.cast_functions_from_to[i][j] = define_cast_from_to (cast_types[i], cast_types[j]); } -#endif /* !defined(LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast) */ +#endif /* !LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast */ static void define_CHECK_TYPE (void) commit c7048b84069c2f88e94cd524a30f973e6bbde21b Author: Vibhav Pant Date: Tue Sep 27 23:31:06 2022 +0530 comp.c: Add declaration for gcc_jit_type_is_pointer. diff --git a/src/comp.c b/src/comp.c index 27e914028d..36fdff890d 100644 --- a/src/comp.c +++ b/src/comp.c @@ -109,6 +109,7 @@ along with GNU Emacs. If not, see . */ #undef gcc_jit_struct_set_fields #undef gcc_jit_type_get_const #undef gcc_jit_type_get_pointer +#undef gcc_jit_type_is_pointer #undef gcc_jit_version_major #undef gcc_jit_version_minor #undef gcc_jit_version_patchlevel @@ -230,6 +231,9 @@ DEF_DLL_FN (gcc_jit_type *, gcc_jit_struct_as_type, (gcc_jit_struct *struct_type)); DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_get_const, (gcc_jit_type *type)); DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_get_pointer, (gcc_jit_type *type)); +#ifdef LIBGCCJIT_HAVE_REFLECTION +DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_is_pointer, (gcc_jit_type *type)); +#endif DEF_DLL_FN (void, gcc_jit_block_add_assignment, (gcc_jit_block *block, gcc_jit_location *loc, gcc_jit_lvalue *lvalue, gcc_jit_rvalue *rvalue)); @@ -343,6 +347,9 @@ init_gccjit_functions (void) LOAD_DLL_FN (library, gcc_jit_struct_set_fields); LOAD_DLL_FN (library, gcc_jit_type_get_const); LOAD_DLL_FN (library, gcc_jit_type_get_pointer); +#ifdef LIBGCCJIT_HAVE_REFLECTION + LOAD_DLL_FN (library, gcc_jit_type_is_pointer); +#endif LOAD_DLL_FN_OPT (library, gcc_jit_context_add_command_line_option); LOAD_DLL_FN_OPT (library, gcc_jit_context_add_driver_option); #if defined (LIBGCCJIT_HAVE_gcc_jit_global_set_initializer) @@ -422,6 +429,9 @@ init_gccjit_functions (void) #define gcc_jit_rvalue_get_type fn_gcc_jit_rvalue_get_type #define gcc_jit_struct_as_type fn_gcc_jit_struct_as_type #define gcc_jit_struct_set_fields fn_gcc_jit_struct_set_fields +#ifdef LIBGCCJIT_HAVE_REFLECTION +#define gcc_jit_type_is_pointer fn_gcc_jit_type_is_pointer +#endif #define gcc_jit_type_get_const fn_gcc_jit_type_get_const #define gcc_jit_type_get_pointer fn_gcc_jit_type_get_pointer #if defined (LIBGCCJIT_HAVE_gcc_jit_version) @@ -1164,8 +1174,8 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) #endif #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast - bool old_is_ptr = gcc_jit_type_is_pointer (old_type); - bool new_is_ptr = gcc_jit_type_is_pointer (new_type); + bool old_is_ptr = gcc_jit_type_is_pointer (old_type) != NULL; + bool new_is_ptr = gcc_jit_type_is_pointer (new_type) != NULL; gcc_jit_rvalue *tmp = obj; commit 92d75e5c53241ac76e8fdcb6fc66ade68354687c Author: Vibhav Pant Date: Tue Sep 27 22:38:45 2022 +0530 src/comp.c: Use libgccjit's bitcast API for type coercion, when available. * (type_to_cast_index, define_type_punning, define_cast_from_to, define_cast_functions): Define functions when gcc_jit_context_new_bitcast is not available. * (emit_coerce): Use gcc_jit_context_new_bitcast to coerce types, when available. diff --git a/src/comp.c b/src/comp.c index 1b767ba0dd..27e914028d 100644 --- a/src/comp.c +++ b/src/comp.c @@ -68,6 +68,7 @@ along with GNU Emacs. If not, see . */ #undef gcc_jit_context_get_type #undef gcc_jit_context_new_array_access #undef gcc_jit_context_new_array_type +#undef gcc_jit_context_new_bitcast #undef gcc_jit_context_new_binary_op #undef gcc_jit_context_new_call #undef gcc_jit_context_new_call_through_ptr @@ -180,8 +181,13 @@ DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_call_through_ptr, (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *fn_ptr, int numargs, gcc_jit_rvalue **args)); DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_cast, + (gcc_jit_context * ctxt, gcc_jit_location *loc, + gcc_jit_rvalue *rvalue, gcc_jit_type *type)); +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast +DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_bitcast, (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *rvalue, gcc_jit_type *type)); +#endif DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_comparison, (gcc_jit_context *ctxt, gcc_jit_location *loc, enum gcc_jit_comparison op, gcc_jit_rvalue *a, gcc_jit_rvalue *b)); @@ -293,6 +299,9 @@ init_gccjit_functions (void) LOAD_DLL_FN (library, gcc_jit_context_get_type); LOAD_DLL_FN (library, gcc_jit_context_new_array_access); LOAD_DLL_FN (library, gcc_jit_context_new_array_type); +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + LOAD_DLL_FN (library, gcc_jit_context_new_bitcast); +#endif LOAD_DLL_FN (library, gcc_jit_context_new_binary_op); LOAD_DLL_FN (library, gcc_jit_context_new_call); LOAD_DLL_FN (library, gcc_jit_context_new_call_through_ptr); @@ -368,6 +377,9 @@ init_gccjit_functions (void) #define gcc_jit_context_get_type fn_gcc_jit_context_get_type #define gcc_jit_context_new_array_access fn_gcc_jit_context_new_array_access #define gcc_jit_context_new_array_type fn_gcc_jit_context_new_array_type +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + #define gcc_jit_context_new_bitcast fn_gcc_jit_context_new_bitcast +#endif #define gcc_jit_context_new_binary_op fn_gcc_jit_context_new_binary_op #define gcc_jit_context_new_call fn_gcc_jit_context_new_call #define gcc_jit_context_new_call_through_ptr fn_gcc_jit_context_new_call_through_ptr @@ -518,7 +530,9 @@ typedef struct { static f_reloc_t freloc; +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast #define NUM_CAST_TYPES 15 +#endif typedef struct { EMACS_INT len; @@ -593,13 +607,15 @@ typedef struct { gcc_jit_rvalue *current_thread_ref; /* Other globals. */ gcc_jit_rvalue *pure_ptr; - /* libgccjit has really limited support for casting therefore this union will - be used for the scope. */ +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + /* This version of libgccjit has really limited support for casting + therefore this union will be used for the scope. */ gcc_jit_type *cast_union_type; gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES]; gcc_jit_function *cast_ptr_to_int; gcc_jit_function *cast_int_to_ptr; gcc_jit_type *cast_types[NUM_CAST_TYPES]; +#endif gcc_jit_function *func; /* Current function being compiled. */ bool func_has_non_local; /* From comp-func has-non-local slot. */ EMACS_INT func_speed; /* From comp-func speed slot. */ @@ -1100,6 +1116,7 @@ emit_cond_jump (gcc_jit_rvalue *test, } +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast static int type_to_cast_index (gcc_jit_type * type) { @@ -1109,6 +1126,7 @@ type_to_cast_index (gcc_jit_type * type) xsignal1 (Qnative_ice, build_string ("unsupported cast")); } +#endif static gcc_jit_rvalue * emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) @@ -1145,14 +1163,41 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj) } #endif +#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast + bool old_is_ptr = gcc_jit_type_is_pointer (old_type); + bool new_is_ptr = gcc_jit_type_is_pointer (new_type); + + gcc_jit_rvalue *tmp = obj; + + if (old_is_ptr != new_is_ptr) + { + if (old_is_ptr) + { + tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, + comp.void_ptr_type); + tmp = gcc_jit_context_new_bitcast (comp.ctxt, NULL, tmp, + comp.uintptr_type); + } + else + { + tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, + comp.uintptr_type); + tmp = gcc_jit_context_new_bitcast (comp.ctxt, NULL, tmp, + comp.void_ptr_type); + } + } + return gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, new_type); +#else /* !defined(LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast) */ int old_index = type_to_cast_index (old_type); int new_index = type_to_cast_index (new_type); /* Lookup the appropriate cast function in the cast matrix. */ return gcc_jit_context_new_call (comp.ctxt, - NULL, - comp.cast_functions_from_to[old_index][new_index], - 1, &obj); + NULL, + comp.cast_functions_from_to + [old_index][new_index], + 1, &obj); +#endif } static gcc_jit_rvalue * @@ -3318,6 +3363,7 @@ define_thread_state_struct (void) gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s)); } +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast static gcc_jit_function * define_type_punning (const char *name, gcc_jit_type *from, gcc_jit_field *from_field, @@ -3336,6 +3382,7 @@ define_type_punning (const char *name, DECL_BLOCK (entry_block, result); + gcc_jit_lvalue *tmp_union = gcc_jit_function_new_local (result, NULL, @@ -3422,6 +3469,7 @@ define_cast_functions (void) { comp.unsigned_long_type, "unsigned_long", false }, { comp.unsigned_type, "unsigned", false }, { comp.void_ptr_type, "void_ptr", true } }; + gcc_jit_field *cast_union_fields[2]; /* Define the union used for type punning. */ @@ -3451,6 +3499,7 @@ define_cast_functions (void) comp.void_ptr_type, cast_union_fields[0]); + for (int i = 0; i < NUM_CAST_TYPES; ++i) comp.cast_types[i] = cast_types[i].type; @@ -3460,6 +3509,7 @@ define_cast_functions (void) comp.cast_functions_from_to[i][j] = define_cast_from_to (cast_types[i], cast_types[j]); } +#endif /* !defined(LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast) */ static void define_CHECK_TYPE (void) @@ -4660,7 +4710,9 @@ Return t on success. */) define_jmp_buf (); define_handler_struct (); define_thread_state_struct (); +#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast define_cast_functions (); +#endif return Qt; } commit b86f711e3de7c95e7957477b888154ace575c96f Author: Lars Ingebrigtsen Date: Tue Oct 4 21:46:09 2022 +0200 Put all seq.el news into one section diff --git a/etc/NEWS b/etc/NEWS index 06e91f5d71..d475c28e45 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3145,16 +3145,6 @@ compiler now emits a warning about this deprecated usage. These can be used for buttons in buffers and the like. See the "(elisp) Icons" and "(emacs) Icons" nodes in the manuals for details. -+++ -** New function 'seq-positions'. -This returns a list of the (zero-based) indices of elements matching a -given predicate in the specified sequence. - -+++ -** New function 'seq-keep'. -This is like 'seq-map', but removes all non-nil results from the -returned list. - +++ ** New arguments MESSAGE and TIMEOUT of 'set-transient-map'. MESSAGE specifies a message to display after activating the transient @@ -3163,15 +3153,6 @@ TIMEOUT is the idle time after which to deactivate the transient map. The default timeout value can be defined by the new variable 'set-transient-map-timeout'. -+++ -** New function 'seq-split'. -This returns a list of sub-sequences of the specified sequence. - -+++ -** New function 'seq-remove-at-position'. -This function returns a copy of the specified sequence where the -element at a given (zero-based) index got removed. - +++ ** 'plist-get', 'plist-put' and 'plist-member' are no longer limited to 'eq'. These function now take an optional comparison predicate argument. @@ -3233,6 +3214,27 @@ When called with a new optional argument UNICODE non-nil, 'max-char' will now report the maximum valid codepoint defined by the Unicode Standard. +** seq + ++++ +** New function 'seq-split'. +This returns a list of sub-sequences of the specified sequence. + ++++ +** New function 'seq-remove-at-position'. +This function returns a copy of the specified sequence where the +element at a given (zero-based) index got removed. + ++++ +** New function 'seq-positions'. +This returns a list of the (zero-based) indices of elements matching a +given predicate in the specified sequence. + ++++ +** New function 'seq-keep'. +This is like 'seq-map', but removes all non-nil results from the +returned list. + ** Themes --- commit 92df7cd923d0e870f08484cec06c2726be30882b Author: Lars Ingebrigtsen Date: Tue Oct 4 21:44:52 2022 +0200 Add 'seq-keep' * doc/lispref/sequences.texi (Sequence Functions): Document it. * lisp/emacs-lisp/seq.el (seq-keep): New function (bug#58278). diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 12c15e6f9a..bc5a4cf24a 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -698,6 +698,19 @@ the same type as @var{sequence}. @end example @end defun +@defun seq-keep function sequence + This function returns a list of all non-@code{nil} results from +calling @var{function} on the elements in @var{sequence}. + +@example +@group +(seq-keep #'cl-digit-char-p '(?6 ?a ?7)) +@result{} (6 7) +@end group +@end example + +@end defun + @defun seq-reduce function sequence initial-value @cindex reducing sequences This function returns the result of calling @var{function} with diff --git a/etc/NEWS b/etc/NEWS index eb5d3afbd8..06e91f5d71 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3150,6 +3150,11 @@ These can be used for buttons in buffers and the like. See the This returns a list of the (zero-based) indices of elements matching a given predicate in the specified sequence. ++++ +** New function 'seq-keep'. +This is like 'seq-map', but removes all non-nil results from the +returned list. + +++ ** New arguments MESSAGE and TIMEOUT of 'set-transient-map'. MESSAGE specifies a message to display after activating the transient diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 31dcfa98b4..82ade0ac0c 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -695,5 +695,9 @@ which may be shorter." result)) (nreverse result))) +(defun seq-keep (function sequence) + "Apply FUNCTION to SEQUENCE and return all non-nil results." + (delq nil (seq-map function sequence))) + (provide 'seq) ;;; seq.el ends here diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index d95b35c45e..e22f86f044 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -592,5 +592,11 @@ Evaluate BODY for each created sequence. (should (= (length list) 10000)) (should (= (length (seq-uniq (append list list))) 10000)))) +(ert-deftest test-seq-keep () + (should (equal (seq-keep #'cl-digit-char-p '(?6 ?a ?7)) + '(6 7))) + (should (equal (seq-keep #'cl-digit-char-p [?6 ?a ?7]) + '(6 7)))) + (provide 'seq-tests) ;;; seq-tests.el ends here commit 1d3d87cd678371b067887950acc640361d0ab87c Author: Eli Zaretskii Date: Tue Oct 4 22:25:20 2022 +0300 ; * lisp/simple.el (cursor-face-highlight-mode): Doc fix. diff --git a/lisp/simple.el b/lisp/simple.el index 10a610e0c6..6b73ccb516 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -7028,7 +7028,7 @@ which is the window that will be redisplayed. When run, the `current-buffer' is set to the buffer displayed in that window.") (define-minor-mode cursor-face-highlight-mode - "When enabled, respect the cursor-face property." + "When enabled, highlight text that has `cursor-face' property near point." :global nil (if cursor-face-highlight-mode (add-hook 'pre-redisplay-functions commit 9705dd2e026bd923b4ce6b3f3051c19507c335a7 Author: Brian Cully Date: Tue Oct 4 21:19:05 2022 +0200 Add method description for podman in Tramp * doc/misc/tramp.texi (Inline methods): Adapt docker method. Describe podman method. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index a182c0510d..064a2cb602 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -907,10 +907,15 @@ session. @cindex method @option{docker} @cindex @option{docker} method -Integration for Docker containers. A container is accessed via -@file{@trampfn{docker,user@@container,/path/to/file}}, where -@samp{user} is the (optional) user that you want to use, and -@samp{container} is the id or name of the container. +Integration for Docker containers. The host name may be either a +running container's name or ID, as returned by @samp{docker ps}. + +@item @option{podman} +@cindex method @option{podman} +@cindex @option{podman} method + +Podman is an alternative to @option{docker} which may be run rootless, +if desired. @end table commit c4641130493f0920de0f0c4543ac80504fd5d5f7 Merge: 56210bfc7a a78af3018e Author: Stefan Kangas Date: Tue Oct 4 20:04:19 2022 +0200 Merge from origin/emacs-28 a78af3018e * src/emacs.c (load_pdump): Propery handle case when execu... # Conflicts: # src/emacs.c commit 56210bfc7a0d7648651d7d6219b2b2348acf8ed3 Merge: 9eda89da55 b560ce3560 Author: Stefan Kangas Date: Tue Oct 4 19:23:24 2022 +0200 ; Merge from origin/emacs-28 The following commit was skipped: b560ce3560 Avoid assertion violations in STRING_CHAR commit 9eda89da55d9b635209ec78f88b519e989d20718 Merge: 9107176511 78c262e1c2 Author: Stefan Kangas Date: Tue Oct 4 19:23:24 2022 +0200 Merge from origin/emacs-28 78c262e1c2 ; * lisp/progmodes/glasses.el (glasses-face): Expand the d... commit 91071765115d3458a1deba56be5b247622eddf73 Author: Alan Mackenzie Date: Tue Oct 4 17:13:56 2022 +0000 CC Mode: A new operator and some new keywords for C++20 * lisp/progmodes/cc-langs.el (c-operators, c-overloadable-operators) (c-arithmetic-operators): Add the "spaceship" operator for C++. (c-primitive-type-kwds): Add char8_t for C++. (c-decl-hangon-kwds, c-paren-nontype-kwds): Add alignas for C++. diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 3b008fd6dc..cd23483a58 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -1330,6 +1330,10 @@ since CC Mode treats every identifier as an expression." ,@(when (c-major-mode-is 'java-mode) '(">>>"))) + ;; The C++ "spaceship" operator. + ,@(when (c-major-mode-is 'c++-mode) + `((left-assoc "<=>"))) + ;; Relational. (left-assoc "<" ">" "<=" ">=" ,@(when (c-major-mode-is 'java-mode) @@ -1443,7 +1447,7 @@ form\". See also `c-op-identifier-prefix'." "^" "??'" "xor" "&" "bitand" "|" "??!" "bitor" "~" "??-" "compl" "!" "=" "<" ">" "+=" "-=" "*=" "/=" "%=" "^=" "??'=" "xor_eq" "&=" "and_eq" "|=" "??!=" "or_eq" - "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=" ">=" + "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=>" "<=" ">=" "&&" "and" "||" "??!??!" "or" "++" "--" "," "->*" "->" "()" "[]" "<::>" "??(??)") ;; These work like identifiers in Pike. @@ -1565,8 +1569,10 @@ operators." "List of all arithmetic operators, including \"+=\", etc." ;; Note: in the following, there are too many operators for AWK and IDL. t (append (c-lang-const c-assignment-operators) - '("+" "-" "*" "/" "%" + `("+" "-" "*" "/" "%" "<<" ">>" + ,@(if (c-major-mode-is 'c++-mode) + '("<=>")) "<" ">" "<=" ">=" "==" "!=" "&" "^" "|" @@ -2216,7 +2222,7 @@ the appropriate place for that." '("_Bool" "_Complex" "_Imaginary") ; Conditionally defined in C99. (c-lang-const c-primitive-type-kwds)) c++ (append - '("bool" "wchar_t" "char16_t" "char32_t") + '("bool" "wchar_t" "char8_t" "char16_t" "char32_t") (c-lang-const c-primitive-type-kwds)) ;; Objective-C extends C, but probably not the new stuff in C99. objc (append @@ -2713,7 +2719,8 @@ one of `c-type-list-kwds', `c-ref-list-kwds', (c c++) '(;; GCC extension. "__attribute__" ;; MSVC extension. - "__declspec")) + "__declspec") + c++ (append (c-lang-const c-decl-hangon-kwds) '("alignas"))) (c-lang-defconst c-decl-hangon-key ;; Adorned regexp matching `c-decl-hangon-kwds'. @@ -2937,7 +2944,7 @@ contain type identifiers." "__attribute__" ;; MSVC extension. "__declspec") - c++ (append (c-lang-const c-paren-nontype-kwds) '("noexcept"))) + c++ (append (c-lang-const c-paren-nontype-kwds) '("noexcept" "alignas"))) (c-lang-defconst c-paren-nontype-key t (c-make-keywords-re t (c-lang-const c-paren-nontype-kwds))) commit bf9d3ddac07e961d0a35414d0f64399966537d80 Author: Michael Albinus Date: Tue Oct 4 18:56:34 2022 +0200 * etc/NEWS: Mention new Tramp method "podman". Fix typos. diff --git a/etc/NEWS b/etc/NEWS index 208e83a132..eb5d3afbd8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -26,7 +26,7 @@ applies, and please also update docstrings as needed. --- ** Ahead-of-time native compilation can now be specified via configure. -Use --with-native-compilation=aot to specify that all the Lisp files +Use '--with-native-compilation=aot' to specify that all the Lisp files in the Emacs tree should be natively compiled ahead of time. (This is slow on most machines.) @@ -174,27 +174,27 @@ time. *** New variable 'inhibit-automatic-native-compilation'. If set, Emacs will inhibit native compilation (and won't write anything to the eln cache automatically). The variable is initialised -from the EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION environment +from the 'EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION' environment variable on Emacs startup. - ---- *** New command 'native-compile-prune-cache'. This command -deletes older ".eln" cache entries (but not the ones for the current -Emacs version). +--- +*** New command 'native-compile-prune-cache'. +This command deletes older eln cache entries (but not the ones for +the current Emacs version). --- *** New function 'startup-redirect-eln-cache'. This function can be called in your init files to change the user-specific directory where Emacs stores the "*.eln" files produced by native compilation of Lisp packages Emacs loads. The default -eln-cache directory is unchanged: it is the "eln-cache" subdirectory +eln cache directory is unchanged: it is the "eln-cache" subdirectory of 'user-emacs-directory'. * Incompatible changes in Emacs 29.1 +++ -*** The image commands have changed key bindings. +** The image commands have changed key bindings. In previous Emacs versions, images have had the '+', '-' and 'r' keys bound when point is over an image. In Emacs 29.1, additional commands were added, and this made it more likely that users would trigger the @@ -204,7 +204,7 @@ moved to the 'i' keymap, so '+' is now 'i +', '-' is now 'i -', and you can rotate an image twice by saying 'i r r', for instance. +++ -*** Emacs now picks the correct coding system for X input methods. +** Emacs now picks the correct coding system for X input methods. Previously, Emacs would use the locale coding system for input methods, which could in some circumstances be incorrect, especially when the input method chose to fall back to some other coding system. @@ -217,7 +217,7 @@ their customizations to 'locale-coding-system' to the variable 'x-input-coding-system' instead. +++ -*** Bookmarks no longer include context for encrypted files. +** Bookmarks no longer include context for encrypted files. If you're visiting an encrypted file, setting a bookmark no longer includes excerpts from that buffer in the bookmarks file. This is implemented by the new hook 'bookmark-inhibit-context-functions', @@ -225,7 +225,7 @@ where packages can register a function which returns non-nil for file names to be excluded from adding such excerpts. --- -*** 'show-paren-mode' is now disabled in 'special-mode' buffers. +** 'show-paren-mode' is now disabled in 'special-mode' buffers. In Emacs versions previous to Emacs 28.1, 'show-paren-mode' defaulted off. In Emacs 28.1, the mode was switched on in all buffers. In Emacs 29.1, this was changed to be switched on in all editing-related @@ -236,7 +236,7 @@ init file: (setopt show-paren-predicate t) +++ -*** Explicitly-set read-only state is preserved when reverting a buffer. +** Explicitly-set read-only state is preserved when reverting a buffer. If you use the 'C-x C-q' command to change the read-only state of the buffer and then revert it, Emacs would previously use the file permission bits to determine whether the buffer should be read-only @@ -244,7 +244,7 @@ after reverting the buffer. Emacs now remembers the decision made in 'C-x C-q'. --- -*** The Gtk selection face is no longer used for the region. +** The Gtk selection face is no longer used for the region. The combination of a Gtk-controlled background and a foreground color controlled by the internal Emacs machinery led to low-contrast faces in common default setups. Emacs now uses the same 'region' face on @@ -488,8 +488,8 @@ option) and can be set to nil to disable Just-in-time Lock mode. * Changes in Emacs 29.1 +++ -** New variable 'major-mode-remap-alist' to specify your favorite major modes. -This variable lets you remap the default modes (e.g. 'perl-mode' or +** New user option 'major-mode-remap-alist' to specify favorite major modes. +This user option lets you remap the default modes (e.g. 'perl-mode' or 'latex-mode') to your favorite ones (e.g. 'cperl-mode' or 'LaTeX-mode') without having to use 'defalias', which can have undesirable side effects. @@ -1145,7 +1145,6 @@ added to insert these automatically. For example, if a region is active and 'C-c C-f C-b' is invoked, markup is inserted for the region to be highlighted bold. - ** Imenu +++ @@ -1788,7 +1787,7 @@ info node. This command only works for the Emacs and Emacs Lisp manuals. It copies the name of the function near point into the kill ring. --- -*** 'N' and 'P' are now bound to 'shortdoc-(next|previous)-section'. +*** 'N' and 'P' are now bound to 'shortdoc-{next,previous}-section'. This is in addition to the old keybindings 'C-c C-n' and 'C-c C-p'. ** VC @@ -1811,7 +1810,7 @@ This command marks files based on a regexp. If given a prefix argument, unmark instead. +++ -*** New command 'C-x v !' ('vc-edit-next-command') +*** New command 'C-x v !' ('vc-edit-next-command'). This prefix command requests editing of the next VC shell command before execution. For example, in a Git repository, you can produce a log of more than one branch by typing 'C-x v ! C-x v b l' and then @@ -1843,7 +1842,7 @@ Git commands display summary lines. See the two new user options 'vc-git-log-edit-summary-target-len' and 'vc-git-log-edit-summary-max-len'. --- -*** New 'log-edit-headers-separator' face +*** New 'log-edit-headers-separator' face. It is used to style the line that separates the 'log-edit' headers from the 'log-edit' summary. @@ -2199,7 +2198,7 @@ now an obsolete alias. --- *** New command 'image-dired-copy-filename-as-kill'. It copies the name of the marked or current image to the kill ring, -and is bound to "w" in the thumbnail buffer. +and is bound to 'w' in the thumbnail buffer. --- *** New command 'image-dired-wallpaper-set'. @@ -2244,8 +2243,8 @@ old format, add this to your Init file: *** New faces for the header line of the thumbnail buffer. These faces correspond to different parts of the header line, as specified in 'image-dired-display-properties-format': -- 'image-dired-thumb-header-file-name' - 'image-dired-thumb-header-directory-name' +- 'image-dired-thumb-header-file-name' - 'image-dired-thumb-header-file-size' - 'image-dired-thumb-header-image-count' @@ -2306,7 +2305,7 @@ nil to disable this confirmation completely. The corresponding keymap is now named 'image-dired-image-mode-map'. +++ -*** Some commands have been renamed to be shorter to be shorter. +*** Some commands have been renamed to be shorter. - 'image-dired-display-thumbnail-original-image' has been renamed to 'image-dired-display-this'. - 'image-dired-display-next-thumbnail-original' has been renamed to @@ -2451,8 +2450,8 @@ and friends. ** Tramp +++ -*** New connection method "docker". -It allows accessing environments provided by Docker. +*** New connection methods "docker" and "podman". +It allows accessing environments provided by Docker and similar programs. --- *** Tramp supports abbreviating remote home directories now. @@ -2591,7 +2590,7 @@ Enabling this will automatically kill a "*shell*" buffer as soon as the shell session terminates. --- -*** New minor mode 'shell-highlight-undef-mode' +*** New minor mode 'shell-highlight-undef-mode'. Customize 'shell-highlight-undef-enable' to t if you want to enable this minor mode in "*shell*" buffers. It will highlight undefined commands with a warning face as you type. @@ -3093,7 +3092,7 @@ The following generalized variables have been made obsolete: 'buffer-name', 'buffer-string', 'buffer-substring', 'current-buffer', 'current-column', 'current-global-map', 'current-input-mode', 'current-local-map', 'current-window-configuration', -'default-file-modes', 'documentation-property', `eq', 'frame-height', +'default-file-modes', 'documentation-property', 'eq', 'frame-height', 'frame-width', 'frame-visible-p', 'global-key-binding', 'local-key-binding', 'mark', 'mark-marker', 'marker-position', 'mouse-position', 'point', 'point-marker', 'point-max', 'point-min', commit 4998d5bdf3a3b61769db3020db642465f5d59e70 Author: Brian Cully Date: Tue Oct 4 18:56:23 2022 +0200 Provide Podman containers on their own method in Tramp * lisp/net/tramp-docker.el (tramp-podman-program): New defcustom. (tramp-podman-method): New defconst. (tramp-docker-program): Remove "podman" from option list. (top): Update comments to refer to Docker-alike where necessary. Add description for how to use the podman method. diff --git a/lisp/net/tramp-docker.el b/lisp/net/tramp-docker.el index 12fabfe7ba..b74bdddddd 100644 --- a/lisp/net/tramp-docker.el +++ b/lisp/net/tramp-docker.el @@ -1,4 +1,4 @@ -;;; tramp-docker.el --- Tramp integration for Docker containers -*- lexical-binding: t; -*- +;;; tramp-docker.el --- Tramp integration for Docker-like containers -*- lexical-binding: t; -*- ;; Copyright © 2022 Free Software Foundation, Inc. @@ -24,14 +24,18 @@ ;;; Commentary: ;; ‘tramp-docker’ allows Tramp access to environments provided by -;; Docker. +;; Docker and similar programs. ;; ;; ## Usage ;; -;; Open a file on a running systemd-docker container: +;; Open a file on a running Docker container: ;; ;; C-x C-f /docker:USER@CONTAINER:/path/to/file ;; +;; or Podman: +;; +;; C-x C-f /podman:USER@CONTAINER:/path/to/file +;; ;; Where: ;; USER is the user on the container to connect as (optional) ;; CONTAINER is the container to connect to @@ -46,16 +50,27 @@ :group 'tramp :version "29.1" :type '(choice (const "docker") - (const "podman") + (string))) + +;;;###tramp-autoload +(defcustom tramp-podman-program "podman" + "Name of the Podman client program." + :group 'tramp + :version "29.1" + :type '(choice (const "podman") (string))) ;;;###tramp-autoload (defconst tramp-docker-method "docker" "Tramp method name to use to connect to Docker containers.") +;;;###tramp-autoload +(defconst tramp-podman-method "podman" + "Tramp method name to use to connect to Podman containers.") + ;;;###tramp-autoload (defun tramp-docker--completion-function (&rest _args) - "List Docker containers available for connection. + "List Docker-like containers available for connection. This function is used by `tramp-set-completion-function', please see its function help for a description of the format." @@ -90,8 +105,24 @@ see its function help for a description of the format." (tramp-remote-shell-args ("-i" "-c"))) tramp-methods) + (push `(,tramp-podman-method + (tramp-login-program ,tramp-podman-program) + (tramp-login-args (("exec") + ("-it") + ("-u" "%u") + ("%h") + ("%l"))) + (tramp-remote-shell ,tramp-default-remote-shell) + (tramp-remote-shell-login ("-l")) + (tramp-remote-shell-args ("-i" "-c"))) + tramp-methods) + (tramp-set-completion-function tramp-docker-method + '((tramp-docker--completion-function ""))) + + (tramp-set-completion-function + tramp-podman-method '((tramp-docker--completion-function "")))) (add-hook 'tramp-unload-hook commit a78af3018e30394137b07d94e3b763674a233afc (refs/remotes/origin/emacs-28) Author: Andreas Schwab Date: Tue Oct 4 18:22:58 2022 +0200 * src/emacs.c (load_pdump): Propery handle case when executable wasn't found. diff --git a/src/emacs.c b/src/emacs.c index 92779a8d0d..a8af288bf0 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -867,13 +867,17 @@ load_pdump (int argc, char **argv) } /* Where's our executable? */ - ptrdiff_t exec_bufsize, needed; + ptrdiff_t exec_bufsize, bufsize, needed; emacs_executable = load_pdump_find_executable (argv[0], &exec_bufsize); /* If we couldn't find our executable, go straight to looking for the dump in the hardcoded location. */ if (!(emacs_executable && *emacs_executable)) - goto hardcoded; + { + bufsize = 0; + dump_file = NULL; + goto hardcoded; + } if (dump_file) { @@ -901,7 +905,7 @@ load_pdump (int argc, char **argv) strip_suffix_length)) exenamelen = prefix_length; } - ptrdiff_t bufsize = exenamelen + strlen (suffix) + 1; + bufsize = exenamelen + strlen (suffix) + 1; dump_file = xpalloc (NULL, &bufsize, 1, -1, 1); memcpy (dump_file, emacs_executable, exenamelen); strcpy (dump_file + exenamelen, suffix); commit d543fdcb218bb2fadfd0277e8a0171afed15d75e Merge: db6072f530 4bd8ad2bc5 Author: Eli Zaretskii Date: Tue Oct 4 19:25:18 2022 +0300 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 4bd8ad2bc5cce8024f1bdecdf6b553e3d43a2f4c Author: Alan Mackenzie Date: Tue Oct 4 16:19:33 2022 +0000 CC Mode: Optimize c-fontify-new-found-type and amend a debug spec * lisp/progmodes/cc-fonts.el (c-fontify-new-found-type): Write the `face' property directly, rather than removing `fontified' properties and letting font-lock do the work. * lisp/progmodes/cc-defs.el (cc-eval-when-compile): Amend the debug spec from t to (&rest body), in line with the fix to bug #16184. diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 77aa3e62bb..4f1a08cfa0 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -125,7 +125,7 @@ The result of the body appears to the compiler as a quoted constant. This variant works around bugs in `eval-when-compile' in various \(X)Emacs versions. See cc-defs.el for details." - (declare (indent 0) (debug t)) + (declare (indent 0) (debug (&rest def-form))) (if c-inside-eval-when-compile ;; XEmacs 21.4.6 has a bug in `eval-when-compile' in that it ;; evaluates its body at macro expansion time if it's nested diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 8f930c5437..2e71285cb3 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -2479,8 +2479,12 @@ higher." (widen) (goto-char (point-min)) (while (re-search-forward target-re nil t) - (put-text-property (match-beginning 0) (match-end 0) - 'fontified nil) + (when (and + (get-text-property (match-beginning 0) 'fontified) + (not (memq (c-get-char-property (match-beginning 0) 'face) + c-literal-faces))) + (c-put-font-lock-face (match-beginning 0) (match-end 0) + font-lock-type-face)) (dolist (win-boundary window-boundaries) (when (and (< (match-beginning 0) (cdr win-boundary)) (> (match-end 0) (car win-boundary)) commit db6072f530744fff3f5da50d26b91e2b5185fd84 Author: Eli Zaretskii Date: Tue Oct 4 19:15:17 2022 +0300 Revert "Improve manual display tests of undisplayable chars (bug#58168)" This reverts commit 849b7756fd31a69791e67dfe010b1e10f0168c83. Please don't rush installing changes that are still being discussed. diff --git a/test/manual/redisplay-testsuite.el b/test/manual/redisplay-testsuite.el index 5495146b87..01b0a895a4 100644 --- a/test/manual/redisplay-testsuite.el +++ b/test/manual/redisplay-testsuite.el @@ -305,7 +305,7 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff (let ((label (if display-raw-bytes-as-hex "\\x80" "\\200"))) (overlay-put test-redisplay-5a-expected-overlay 'display (propertize label 'face 'escape-glyph))) - (let ((label (if display-raw-bytes-as-hex "\\xfc" "\\374"))) + (let ((label (if display-raw-bytes-as-hex "\\x3fffc" "\\777774"))) (overlay-put test-redisplay-5b-expected-overlay 'display (propertize label 'face 'escape-glyph)))) @@ -320,36 +320,18 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff (test-insert-overlay " " 'display "\200")) (insert "\n\n") (insert " Expected: ") + ;; This tests a large codepoint, to make sure the internal buffer we + ;; use to produce the representation is large enough. + (aset printable-chars #x3fffc nil) (setq test-redisplay-5b-expected-overlay (test-insert-overlay " " 'display - (propertize "\\374" 'face 'escape-glyph))) + (propertize "\\777774" 'face 'escape-glyph))) (insert "\n Result: ") (setq test-redisplay-5b-result-overlay - (test-insert-overlay " " 'display (char-to-string #x3ffffc))) - (insert "\n\n") - (insert-button "Toggle between octal and hex display for raw bytes" - 'action 'test-redisplay-5-toggle) - (insert "\n\n")) - -(defun test-redisplay-6 () - (insert "Test 6: Display of unprintable Unicode chars:\n\n") - (insert " Expected: ") - (test-insert-overlay " " 'display - (propertize "\\200" 'face 'escape-glyph)) - (insert " (representing U+0100)") - (insert "\n Result: ") - (test-insert-overlay " " 'display "\u0080") + (test-insert-overlay " " 'display (char-to-string #x3fffc))) (insert "\n\n") - ;; This tests a large codepoint, to make sure the internal buffer we - ;; use to produce the representation is large enough. - (insert " Expected: ") - (aset printable-chars #x10abcd nil) - (test-insert-overlay " " 'display - (propertize "\\4125715" 'face 'escape-glyph)) - (insert " (representing U+0010ABCD)") - (insert "\n Result: ") - (test-insert-overlay " " 'display "\U0010ABCD") - (insert "\n\n")) + (insert-button "Toggle between octal and hex display" + 'action 'test-redisplay-5-toggle)) (defun test-redisplay () (interactive) @@ -367,7 +349,6 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff (test-redisplay-3) (test-redisplay-4) (test-redisplay-5) - (test-redisplay-6) (goto-char (point-min)))) ;;; redisplay-testsuite.el ends here commit a36ecc408a30c76d287351b38956f998f84cb8a7 Author: Stefan Kangas Date: Tue Oct 4 17:39:28 2022 +0200 * lisp/subr.el (y-or-n-p): Use substitute-command-keys. diff --git a/lisp/subr.el b/lisp/subr.el index 51172b1cb2..c975c216bb 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3547,11 +3547,12 @@ like) while `y-or-n-p' is running)." (if (or (zerop l) (eq ?\s (aref prompt (1- l)))) "" " ") (if dialog "" - (if help-form - (format "(y, n or %s) " - (key-description - (vector help-char))) - "(y or n) ")))))) + (substitute-command-keys + (if help-form + (format "(\\`y', \\`n' or \\`%s') " + (key-description + (vector help-char))) + "(\\`y' or \\`n') "))))))) ;; Preserve the actual command that eventually called ;; `y-or-n-p' (otherwise `repeat' will be repeating ;; `exit-minibuffer'). commit d9bd14975b60aa46408c67aa11a8a57bd5a8772a Author: Stefan Kangas Date: Tue Oct 4 17:36:09 2022 +0200 image-dired: Shorten several long names * lisp/image/image-dired.el (image-dired-image-mode-map) (image-dired-image-mode): Rename from 'image-dired-display-image-mode-map' and 'image-dired-display-image-mode'. Update all uses and make old names into obsolete aliases. (image-dired-display-this, image-dired-display-next) (image-dired-display-previous): Rename from 'image-dired-display-thumbnail-original-image', 'image-dired-display-next-thumbnail-original', and 'image-dired-display-previous-thumbnail-original'. Update all uses and make old names into obsolete aliases. * doc/emacs/dired.texi (Image-Dired): Update documentation for the above changes, and improve indexing. diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 3dc6f724de..a9b4ff783d 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -1650,14 +1650,16 @@ directory, and displays them all in the thumbnail buffer. The thumbnails are generated in the background and are loaded as they become available. +@findex image-dired-display-this +@findex image-dired-display-next +@findex image-dired-display-previous With point in the thumbnail buffer, you can type @key{RET} -(@code{image-dired-display-thumbnail-original-image}) to display the -image in another window. Use the arrow keys to move around in the -thumbnail buffer. For easy browsing, use @key{SPC} -(@code{image-dired-display-next-thumbnail-original}) to advance and -display the next image. Typing @key{DEL} -(@code{image-dired-display-previous-thumbnail-original}) backs up to -the previous thumbnail and displays that instead. +(@code{image-dired-display-this}) to display the image in another +window. Use the arrow keys to move around in the thumbnail buffer. +For easy browsing, use @key{SPC} (@code{image-dired-display-next}) to +advance and display the next image. Typing @key{DEL} +(@code{image-dired-display-previous}) backs up to the previous +thumbnail and displays that instead. @vindex image-dired-external-viewer Type @kbd{C-@key{RET}} diff --git a/etc/NEWS b/etc/NEWS index 23425eb556..208e83a132 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2169,7 +2169,7 @@ This is done via 'image-converter-add-handler'. ** Image-Dired +++ -*** 'image-dired-display-image-mode' is now based on 'image-mode'. +*** 'image-dired-image-mode' is now based on 'image-mode'. This avoids converting images in the background, and makes Image-Dired noticeably faster. New keybindings from 'image-mode' are now available in the "*image-dired-display-image*" buffer; press '?' or @@ -2178,8 +2178,8 @@ available in the "*image-dired-display-image*" buffer; press '?' or --- *** Navigation and marking commands now work in image display buffer. The following new bindings have been added: -- 'n', 'SPC' => 'image-dired-display-next-thumbnail-original' -- 'p', 'DEL' => 'image-dired-display-previous-thumbnail-original' +- 'n', 'SPC' => 'image-dired-display-next' +- 'p', 'DEL' => 'image-dired-display-previous' - 'm' => 'image-dired-mark-thumb-original-file' - 'd' => 'image-dired-flag-thumb-original-file' - 'u' => 'image-dired-unmark-thumb-original-file' @@ -2301,6 +2301,20 @@ nil to disable this confirmation completely. +++ *** 'image-dired-db-file' renamed to 'image-dired-tags-db-file'. +--- +*** 'image-dired-display-image-mode' renamed to 'image-dired-image-mode'. +The corresponding keymap is now named 'image-dired-image-mode-map'. + ++++ +*** Some commands have been renamed to be shorter to be shorter. +- 'image-dired-display-thumbnail-original-image' has been renamed to + 'image-dired-display-this'. +- 'image-dired-display-next-thumbnail-original' has been renamed to + 'image-dired-display-next'. +- 'image-dired-display-previous-thumbnail-original' has been renamed + to 'image-dired-display-previous'. +The old names are now obsolete aliases. + --- *** 'image-dired-thumb-{height,width}' are now obsolete. Customize 'image-dired-thumb-size' instead, which will set both the diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index 86b8db7a85..d4fd3c62db 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -635,7 +635,7 @@ never ask for confirmation." "Track the original file in the associated Dired buffer. See `image-dired-toggle-movement-tracking'. Interactive use is only useful if `image-dired-track-movement' is nil." - (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive nil image-dired-thumbnail-mode image-dired-image-mode) (let ((file-name (image-dired-original-file-name))) (image-dired--with-dired-buffer (if (not (dired-goto-file file-name)) @@ -649,7 +649,7 @@ Tracking of the movements between thumbnail and Dired buffer so that they are \"mirrored\" in the dired buffer. When this is on, moving around in the thumbnail or dired buffer will find the matching position in the other buffer." - (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive nil image-dired-thumbnail-mode image-dired-image-mode) (setq image-dired-track-movement (not image-dired-track-movement)) (message "Movement tracking %s" (if image-dired-track-movement "on" "off"))) @@ -852,31 +852,31 @@ buffer with `image-dired--thumb-update-mark-at-point'." '(image-dired--thumb-update-mark-at-point)) ,(when maybe-next '(if image-dired-marking-shows-next - (image-dired-display-next-thumbnail-original) + (image-dired-display-next) (image-dired-forward-image))))) (defun image-dired-mark-thumb-original-file () "Mark original image file in associated Dired buffer." - (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive nil image-dired-thumbnail-mode image-dired-image-mode) (image-dired--do-mark-command t t (dired-mark 1))) (defun image-dired-unmark-thumb-original-file () "Unmark original image file in associated Dired buffer." - (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive nil image-dired-thumbnail-mode image-dired-image-mode) (image-dired--do-mark-command t t (dired-unmark 1))) (defun image-dired-flag-thumb-original-file () "Flag original image file for deletion in associated Dired buffer." - (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive nil image-dired-thumbnail-mode image-dired-image-mode) (image-dired--do-mark-command t t (dired-flag-file-deletion 1))) (defun image-dired-unmark-all-marks () "Remove all marks from all files in associated Dired buffer. Also update the marks in the thumbnail buffer." - (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive nil image-dired-thumbnail-mode image-dired-image-mode) (image-dired--do-mark-command nil t (dired-unmark-all-marks)) (image-dired--with-thumbnail-buffer @@ -916,7 +916,7 @@ You probably want to use this together with "t t" #'image-dired-tag-thumbnail "t r" #'image-dired-tag-thumbnail-remove - "RET" #'image-dired-display-thumbnail-original-image + "RET" #'image-dired-display-this "C-" #'image-dired-thumbnail-display-external "L" #'image-dired-rotate-original-left @@ -925,8 +925,8 @@ You probably want to use this together with "D" #'image-dired-thumbnail-set-image-description "S" #'image-dired-slideshow-start "C-d" #'image-dired-delete-char - "SPC" #'image-dired-display-next-thumbnail-original - "DEL" #'image-dired-display-previous-thumbnail-original + "SPC" #'image-dired-display-next + "DEL" #'image-dired-display-previous "c" #'image-dired-comment-thumbnail "w" #'image-dired-copy-filename-as-kill "W" #'image-dired-wallpaper-set @@ -955,7 +955,7 @@ You probably want to use this together with :menu '("Image-Dired" - ["Display image" image-dired-display-thumbnail-original-image] + ["Display image" image-dired-display-this] ["Display in external viewer" image-dired-thumbnail-display-external] ["Jump to Dired buffer" image-dired-jump-original-dired-buffer] "---" @@ -984,20 +984,6 @@ You probably want to use this together with ["Refresh thumb" image-dired-refresh-thumb]) ["Quit" quit-window])) -(defvar-keymap image-dired-display-image-mode-map - :doc "Keymap for `image-dired-display-image-mode'." - "S" #'image-dired-slideshow-start - "SPC" #'image-dired-display-next-thumbnail-original - "DEL" #'image-dired-display-previous-thumbnail-original - "n" #'image-dired-display-next-thumbnail-original - "p" #'image-dired-display-previous-thumbnail-original - "m" #'image-dired-mark-thumb-original-file - "d" #'image-dired-flag-thumb-original-file - "u" #'image-dired-unmark-thumb-original-file - "U" #'image-dired-unmark-all-marks - ;; Disable keybindings from `image-mode-map' that doesn't make sense here. - "o" nil) ; image-save - (define-derived-mode image-dired-thumbnail-mode special-mode "image-dired-thumbnail" "Browse and manipulate thumbnail images using Dired. @@ -1011,7 +997,26 @@ Use `image-dired-minor-mode' to get a nice setup." ;; Use approximately as much vertical spacing as horizontal. (setq-local line-spacing (frame-char-width))) -(define-derived-mode image-dired-display-image-mode + +;;; image-dired-image-mode + +(define-obsolete-variable-alias 'image-dired-display-image-mode-map + 'image-dired-image-mode-map "29.1") +(defvar-keymap image-dired-image-mode-map + :doc "Keymap for `image-dired-image-mode'." + "S" #'image-dired-slideshow-start + "SPC" #'image-dired-display-next + "DEL" #'image-dired-display-previous + "n" #'image-dired-display-next + "p" #'image-dired-display-previous + "m" #'image-dired-mark-thumb-original-file + "d" #'image-dired-flag-thumb-original-file + "u" #'image-dired-unmark-thumb-original-file + "U" #'image-dired-unmark-all-marks + ;; Disable keybindings from `image-mode-map' that doesn't make sense here. + "o" nil) ; image-save + +(define-derived-mode image-dired-image-mode image-mode "image-dired-image-display" "Mode for displaying and manipulating original image. Resized or in full-size." @@ -1041,7 +1046,7 @@ This is used by `image-dired-slideshow-start'." "Step to the next image in a slideshow." (if-let ((buf (get-buffer image-dired-thumbnail-buffer))) (with-current-buffer buf - (image-dired-display-next-thumbnail-original)) + (image-dired-display-next)) (image-dired--slideshow-stop))) (defun image-dired--slideshow-start-timer () @@ -1063,7 +1068,7 @@ With prefix argument ARG, wait that many seconds before going to the next image. With a negative prefix argument, prompt user for the delay." - (interactive "P" image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive "P" image-dired-thumbnail-mode image-dired-image-mode) (let ((delay (cond ((not arg) image-dired-slideshow-delay) @@ -1076,7 +1081,7 @@ With a negative prefix argument, prompt user for the delay." (format-prompt "Delay, in seconds. Decimals are accepted" delay)) delay)))))) - (image-dired-display-thumbnail-original-image) + (image-dired-display-this) (setq image-dired--slideshow-current-delay delay) (add-hook 'post-command-hook 'image-dired--slideshow-stop))) @@ -1085,9 +1090,9 @@ With a negative prefix argument, prompt user for the delay." (message (substitute-command-keys (format (concat - "\\[image-dired-display-next-thumbnail-original] next, " - "\\[image-dired-display-previous-thumbnail-original] previous, " - "\\[image-dired-display-thumbnail-original-image] pause/unpause, " + "\\[image-dired-display-next] next, " + "\\[image-dired-display-previous] previous, " + "\\[image-dired-display-this] pause/unpause, " "any other command to stop%s") (or suffix ""))))) @@ -1096,11 +1101,11 @@ With a negative prefix argument, prompt user for the delay." (cond ((memq this-command '( image-dired-slideshow-start - image-dired-display-next-thumbnail-original - image-dired-display-previous-thumbnail-original)) + image-dired-display-next + image-dired-display-previous)) (image-dired--slideshow-start-timer) (image-dired--slideshow-show-message)) - ((eq this-command 'image-dired-display-thumbnail-original-image) + ((eq this-command 'image-dired-display-this) (let ((pause image-dired--slideshow-timer)) (if pause (image-dired--slideshow-stop-timer) @@ -1200,7 +1205,7 @@ Ask user how many thumbnails should be displayed per row." (defun image-dired-display-image (file &optional _ignored) "Display image FILE in the image buffer window. -If it is an image, the window will use `image-dired-display-image-mode' +If it is an image, the window will use `image-dired-image-mode' which is based on `image-mode'." (declare (advertised-calling-convention (file) "29.1")) (setq file (expand-file-name file)) @@ -1214,12 +1219,12 @@ which is based on `image-mode'." (pop-to-buffer buf) (rename-buffer image-dired-display-image-buffer) (if (string-match (image-file-name-regexp) file) - (image-dired-display-image-mode) + (image-dired-image-mode) ;; Support visiting PDF files. (normal-mode)) (select-window cur-win)))) -(defun image-dired-display-thumbnail-original-image (&optional arg) +(defun image-dired-display-this (&optional arg) "Display current thumbnail's original image in display buffer. See documentation for `image-dired-display-image' for more information. With prefix argument ARG, display image in its original size." @@ -1234,19 +1239,19 @@ With prefix argument ARG, display image in its original size." (t (image-dired-display-image file arg))))) -(defun image-dired-display-next-thumbnail-original (&optional arg) +(defun image-dired-display-next (&optional arg) "Move to the next image in the thumbnail buffer and display it. With prefix ARG, move that many thumbnails." - (interactive "p" image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive "p" image-dired-thumbnail-mode image-dired-image-mode) (image-dired--with-thumbnail-buffer (image-dired-forward-image arg t) - (image-dired-display-thumbnail-original-image))) + (image-dired-display-this))) -(defun image-dired-display-previous-thumbnail-original (arg) +(defun image-dired-display-previous (arg) "Move to the previous image in the thumbnail buffer and display it. With prefix ARG, move that many thumbnails." - (interactive "p" image-dired-thumbnail-mode image-dired-display-image-mode) - (image-dired-display-next-thumbnail-original (- arg))) + (interactive "p" image-dired-thumbnail-mode image-dired-image-mode) + (image-dired-display-next (- arg))) ;;; Misc commands @@ -1525,7 +1530,7 @@ completely fit)." (defun image-dired-toggle-mark-thumb-original-file () "Toggle mark on original image file in associated Dired buffer." (declare (obsolete nil "29.1")) - (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode) + (interactive nil image-dired-thumbnail-mode image-dired-image-mode) (image-dired--do-mark-command nil t (if (image-dired-dired-file-marked-p) (dired-unmark 1) @@ -1963,6 +1968,14 @@ when using per-directory thumbnail file storage")) #'image-dired--update-header-line "29.1") (define-obsolete-function-alias 'image-dired-delete-marked #'image-dired-do-flagged-delete "29.1") +(define-obsolete-function-alias 'image-dired-display-image-mode + #'image-dired-image-mode "29.1") +(define-obsolete-function-alias 'image-dired-display-thumbnail-original-image + #'image-dired-display-this "29.1") +(define-obsolete-function-alias 'image-dired-display-next-thumbnail-original + #'image-dired-display-next "29.1") +(define-obsolete-function-alias 'image-dired-display-previous-thumbnail-original + #'image-dired-display-previous "29.1") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; TEST-SECTION ;;;;;;;;;;; commit 849b7756fd31a69791e67dfe010b1e10f0168c83 Author: Mattias Engdegård Date: Tue Oct 4 16:13:12 2022 +0200 Improve manual display tests of undisplayable chars (bug#58168) Test display of multibyte raw bytes, as well as undisplayable multibyte chars (C1 controls and other values). The test still assumes that raw bytes should be displayed identically to undisplayable characters (such as C1 controls) because that is how the display code currently works. * test/manual/redisplay-testsuite.el (test-redisplay-5-toggle) (test-redisplay-5): Fix likely typo (#x3fffc) of raw byte value. (test-redisplay-6): New. diff --git a/test/manual/redisplay-testsuite.el b/test/manual/redisplay-testsuite.el index 01b0a895a4..5495146b87 100644 --- a/test/manual/redisplay-testsuite.el +++ b/test/manual/redisplay-testsuite.el @@ -305,7 +305,7 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff (let ((label (if display-raw-bytes-as-hex "\\x80" "\\200"))) (overlay-put test-redisplay-5a-expected-overlay 'display (propertize label 'face 'escape-glyph))) - (let ((label (if display-raw-bytes-as-hex "\\x3fffc" "\\777774"))) + (let ((label (if display-raw-bytes-as-hex "\\xfc" "\\374"))) (overlay-put test-redisplay-5b-expected-overlay 'display (propertize label 'face 'escape-glyph)))) @@ -320,18 +320,36 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff (test-insert-overlay " " 'display "\200")) (insert "\n\n") (insert " Expected: ") - ;; This tests a large codepoint, to make sure the internal buffer we - ;; use to produce the representation is large enough. - (aset printable-chars #x3fffc nil) (setq test-redisplay-5b-expected-overlay (test-insert-overlay " " 'display - (propertize "\\777774" 'face 'escape-glyph))) + (propertize "\\374" 'face 'escape-glyph))) (insert "\n Result: ") (setq test-redisplay-5b-result-overlay - (test-insert-overlay " " 'display (char-to-string #x3fffc))) + (test-insert-overlay " " 'display (char-to-string #x3ffffc))) + (insert "\n\n") + (insert-button "Toggle between octal and hex display for raw bytes" + 'action 'test-redisplay-5-toggle) + (insert "\n\n")) + +(defun test-redisplay-6 () + (insert "Test 6: Display of unprintable Unicode chars:\n\n") + (insert " Expected: ") + (test-insert-overlay " " 'display + (propertize "\\200" 'face 'escape-glyph)) + (insert " (representing U+0100)") + (insert "\n Result: ") + (test-insert-overlay " " 'display "\u0080") (insert "\n\n") - (insert-button "Toggle between octal and hex display" - 'action 'test-redisplay-5-toggle)) + ;; This tests a large codepoint, to make sure the internal buffer we + ;; use to produce the representation is large enough. + (insert " Expected: ") + (aset printable-chars #x10abcd nil) + (test-insert-overlay " " 'display + (propertize "\\4125715" 'face 'escape-glyph)) + (insert " (representing U+0010ABCD)") + (insert "\n Result: ") + (test-insert-overlay " " 'display "\U0010ABCD") + (insert "\n\n")) (defun test-redisplay () (interactive) @@ -349,6 +367,7 @@ static unsigned char x_bits[] = {0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff (test-redisplay-3) (test-redisplay-4) (test-redisplay-5) + (test-redisplay-6) (goto-char (point-min)))) ;;; redisplay-testsuite.el ends here commit f4252f317191bfda44e4bfa8c5c58c2ee0e621db Author: Stefan Kangas Date: Tue Oct 4 16:18:13 2022 +0200 image-dired: Fix arrow keys in thumbs buffer * lisp/image/image-dired.el (image-dired-thumbnail-mode-map): Also remap 'left-char' and 'right-char'. diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index c9d6741140..86b8db7a85 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -946,6 +946,8 @@ You probably want to use this together with " " #'image-dired-backward-image " " #'image-dired-next-line " " #'image-dired-previous-line + " " #'image-dired-backward-image + " " #'image-dired-forward-image " " #'image-dired-beginning-of-buffer " " #'image-dired-end-of-buffer " " #'image-dired-move-beginning-of-line commit f0ee4c68f1725675b0a974bcdb8193749e437822 Author: Eli Zaretskii Date: Tue Oct 4 17:15:47 2022 +0300 Fix recent changes for Ukrainian language * etc/HELLO: * lisp/language/cyrillic.el ("Ukrainian"): Fix greetings and remove redundant Ukrainian entry in cyrillic.el. diff --git a/etc/HELLO b/etc/HELLO index 7ddaed44b9..b05c09da3c 100644 --- a/etc/HELLO +++ b/etc/HELLO @@ -114,7 +114,7 @@ Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེག Tigrigna (ትግርኛ) ሰላማት Tirhuta (𑒞𑒱𑒩𑒯𑒳𑒞𑒰) 𑒣𑓂𑒩𑒢𑒰𑒧 / 𑒮𑒲𑒞𑒰𑒩𑒰𑒧 Turkish (Türkçe) Merhaba -Ukrainian (українська) Вітаю +Ukrainian (українська) Вітаю / Добрий день! / Привіт Vietnamese (tiếng Việt) Chào bạn Wancho (𞋒𞋀𞋉𞋃𞋕) 𞋂𞋈𞋛 diff --git a/lisp/language/cyrillic.el b/lisp/language/cyrillic.el index 753e99e9d4..a9017062cc 100644 --- a/lisp/language/cyrillic.el +++ b/lisp/language/cyrillic.el @@ -137,9 +137,9 @@ Support for Russian using koi8-r and the russian-computer input method.") (coding-priority koi8-u) (nonascii-translation . koi8-u) (input-method . "ukrainian-computer") - (sample-text . "Ukrainian (Українська) Доброго дня!") + (sample-text . "Ukrainian (Українська) Вітаю / Добрий день! / Привіт") (documentation - . "Support for Ukrainian with KOI8-U character set.")) + . "Support for Ukrainian with koi8-u character set.")) '("Cyrillic")) ;;; ALTERNATIVNYJ stuff @@ -256,14 +256,6 @@ Support for Russian using koi8-r and the russian-computer input method.") \(The name Belarusian replaced Byelorussian in the early 1990s.)")) '("Cyrillic")) -(set-language-info-alist - "Ukrainian" '((coding-system koi8-u) - (coding-priority koi8-u) - (input-method . "ukrainian-computer") - (documentation - . "Support for Ukrainian with koi8-u character set.")) - '("Cyrillic")) - (provide 'cyrillic) ;;; cyrillic.el ends here commit 682662202d1aca3d43ac50963693cea3fc1b9dcf Author: Lars Ingebrigtsen Date: Tue Oct 4 15:40:53 2022 +0200 Make cropping of images work in message-mode * lisp/gnus/message.el (message-mode): Set the image cropping function. (message--yank-media-image-handler): Factor out... (message--image-part-string): ... here for reuse. (message--update-image-crop): Update the cropped data. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 084dce65f0..beccef6f5f 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -3208,7 +3208,8 @@ Like `text-mode', but with these additional commands: ;; (setq-local syntax-propertize-function #'message--syntax-propertize) (setq-local parse-sexp-ignore-comments t) - (setq-local message-encoded-mail-cache nil)) + (setq-local message-encoded-mail-cache nil) + (setq-local image-crop-buffer-text-function #'message--update-image-crop)) (defun message-setup-fill-variables () "Setup message fill variables." @@ -8927,19 +8928,26 @@ used to take the screenshot." :max-width (truncate (* (frame-pixel-width) 0.8)) :max-height (truncate (* (frame-pixel-height) 0.8)) :scale 1) - (format "<#part type=\"%s\" disposition=inline data-encoding=base64 raw=t>\n%s\n<#/part>" - type - ;; Get a base64 version of the image -- this avoids later - ;; complications if we're auto-saving the buffer and - ;; restoring from a file. - (with-temp-buffer - (set-buffer-multibyte nil) - (insert image) - (base64-encode-region (point-min) (point-max) t) - (buffer-string))) + (message--image-part-string type image) nil nil t) (insert "\n\n")) +(defun message--image-part-string (type image) + (format "<#part type=\"%s\" disposition=inline data-encoding=base64 raw=t>\n%s\n<#/part>" + type + ;; Get a base64 version of the image -- this avoids later + ;; complications if we're auto-saving the buffer and + ;; restoring from a file. + (with-temp-buffer + (set-buffer-multibyte nil) + (insert image) + (base64-encode-region (point-min) (point-max) t) + (buffer-string)))) + +(declare-function image-crop--content-type "image-crop") +(defun message--update-image-crop (_text image) + (message--image-part-string (image-crop--content-type image) image)) + (declare-function gnus-url-unhex-string "gnus-util") (defun message-parse-mailto-url (url) commit 121c3d44be84ad1d4c5cccd629bb6994252950d1 Author: Alan Mackenzie Date: Tue Oct 4 13:22:32 2022 +0000 CC Mode: Make c-forward-declarator move over a suffix after parens, e.g. const Also tidy up several inaccuracies in the code. * lisp/progmodes/cc-engine.el (c-forward-decl-arglist): Move point for modes other than C++ Mode. (c-forward-declarator): Move over a suffix following arglist parens (e.g. const). Set the ARGLIST element of the return value to non-nil on encountering an unbalanced open parenthesis. Don't move forward out of enclosing parens. * lisp/progmodes/cc-mode.el (c-fl-decl-end): Handle being in a multi-line string. Move forward over token after declarator. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index fc00518360..0ac96219a1 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -9609,40 +9609,38 @@ point unchanged and return nil." (forward-char) (c-forward-syntactic-ws limit) (looking-at "[*&]"))) - (when - (save-excursion - (let (c-last-identifier-range) - (forward-char) - (c-forward-syntactic-ws limit) - (catch 'is-function - (while - ;; Go forward one argument at each iteration. - (progn - (while - (cond - ((looking-at c-decl-hangon-key) - (c-forward-keyword-clause 1)) - ((looking-at - c-noise-macro-with-parens-name-re) - (c-forward-noise-clause)))) - (when (eq (char-after) ?\)) - (forward-char) - (c-forward-syntactic-ws limit) - (throw 'is-function t)) - (setq got-type (c-forward-type)) + (save-excursion + (let (c-last-identifier-range) + (forward-char) + (c-forward-syntactic-ws limit) + (catch 'is-function + (while + ;; Go forward one argument at each iteration. + (progn + (while (cond - ((null got-type) - (throw 'is-function nil)) - ((not (eq got-type 'maybe)) - (throw 'is-function t))) - (c-forward-declarator limit t t) - (eq (char-after) ?,)) - (forward-char) - (c-forward-syntactic-ws)) - t))) - (and (c-go-list-forward (point) limit) - (progn (c-forward-syntactic-ws limit) t))))) - t + ((looking-at c-decl-hangon-key) + (c-forward-keyword-clause 1)) + ((looking-at + c-noise-macro-with-parens-name-re) + (c-forward-noise-clause)))) + (when (eq (char-after) ?\)) + (forward-char) + (c-forward-syntactic-ws limit) + (throw 'is-function t)) + (setq got-type (c-forward-type)) + (cond + ((null got-type) + (throw 'is-function nil)) + ((not (eq got-type 'maybe)) + (throw 'is-function t))) + (c-forward-declarator limit t t) + (eq (char-after) ?,)) + (forward-char) + (c-forward-syntactic-ws)) + t))))) + (and (c-go-list-forward (point) limit) + (progn (c-forward-syntactic-ws limit) t)) (goto-char here) nil))) @@ -9654,10 +9652,11 @@ point unchanged and return nil." ;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT DECORATED ;; ARGLIST), where ID-START and ID-END are the bounds of the declarator's ;; identifier, BRACKETS-AFTER-ID is non-nil if a [...] pair is present after - ;; the id, and ARGLIST is non-nil if an arglist has been moved over. - ;; GOT-INIT is non-nil when the declarator is followed by "=" or "(", - ;; DECORATED is non-nil when the identifier is embellished by an operator, - ;; like "*x", or "(*x)". + ;; the id, and ARGLIST is non-nil either when an arglist has been moved + ;; over, or when we have stopped at an unbalanced open-paren. GOT-INIT is + ;; non-nil when the declarator is followed by "=" or "(", DECORATED is + ;; non-nil when the identifier is embellished by an operator, like "*x", or + ;; "(*x)". ;; ;; If ACCEPT-ANON is non-nil, move forward over any "anonymous declarator", ;; i.e. something like the (*) in int (*), such as might be found in a @@ -9707,6 +9706,7 @@ point unchanged and return nil." (if (looking-at c-overloadable-operators-regexp) (progn (goto-char (match-end 0)) + (c-forward-syntactic-ws limit) (setq got-identifier t) nil) t)) @@ -9759,25 +9759,37 @@ point unchanged and return nil." ;; Skip out of the parens surrounding the identifier. If closing ;; parens are missing, this form returns nil. (or (= paren-depth 0) - (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) + (prog1 + (c-safe (goto-char (scan-lists (point) 1 paren-depth))) + (c-forward-syntactic-ws))) (or (eq (point) (point-max)) ; No token after identifier. (< (point) limit)) ;; Skip over any trailing bit, such as "__attribute__". (progn - (while (cond - ((looking-at c-decl-hangon-key) - (c-forward-keyword-clause 1)) - ((looking-at c-type-decl-suffix-key) - (if (save-match-data - (looking-at c-fun-name-substitute-key)) - (c-forward-c++-requires-clause) - (c-forward-keyword-clause 1))) - ((and c-opt-cpp-prefix - (looking-at c-noise-macro-with-parens-name-re)) - (c-forward-noise-clause)))) - (<= (point) limit)) + (while (cond + ((looking-at c-decl-hangon-key) + (c-forward-keyword-clause 1)) + ((looking-at c-type-decl-suffix-key) + (cond + ((save-match-data + (looking-at c-fun-name-substitute-key)) + (c-forward-c++-requires-clause)) + ((eq (char-after) ?\() + (if (c-forward-decl-arglist not-top decorated limit) + (progn (setq arglist t + got-init nil) + t) + (if (c-go-list-forward (point) limit) + t + (setq arglist t) ; For unbalanced (. + nil))) + (t (c-forward-keyword-clause 1)))) + ((and c-opt-cpp-prefix + (looking-at c-noise-macro-with-parens-name-re)) + (c-forward-noise-clause)))) + (<= (point) limit)) ;; Search syntactically to the end of the declarator (";", ;; ",", a closing paren, eob etc) or to the beginning of an @@ -9785,52 +9797,48 @@ point unchanged and return nil." ;; Note that square brackets are now not also treated as ;; initializers, since this broke when there were also ;; initializing brace lists. - (let (found) - (while - (and (< (point) limit) - (progn - ;; In the next loop, we keep searching forward whilst - ;; we find ":"s which aren't single colons inside C++ - ;; "for" statements. - (while - (and - (< (point) limit) - (prog1 - (setq found - (c-syntactic-re-search-forward - "[;:,]\\|\\s)\\|\\(=\\|\\s(\\)" - limit t t)) - (setq got-init - (and found (match-beginning 1)))) - (eq (char-before) ?:) - (if (looking-at c-:-op-cont-regexp) - (progn (goto-char (match-end 0)) t) - (not - (and (c-major-mode-is '(c++-mode java-mode)) - (save-excursion - (and - (c-go-up-list-backward) - (eq (char-after) ?\() - (progn (c-backward-syntactic-ws) - (c-simple-skip-symbol-backward)) - (looking-at c-paren-stmt-key)))))))) - found) - (cond ((eq (char-before) ?\[) - (setq brackets-after-id t) - (prog1 (c-go-up-list-forward) - (c-forward-syntactic-ws))) - ((and (not brackets-after-id) - (eq (char-before) ?\()) - (backward-char) - (if (c-forward-decl-arglist not-top decorated limit) - (setq arglist t - got-init nil) - (forward-char)) - nil)))) ; To end the loop. - (when (and found - (memq (char-before) '(?\; ?\: ?, ?= ?\( ?\[ ?{))) - (backward-char)) - (<= (point) limit))) + (or (eq (char-after) ?\() ; Not an arglist. + (let (found) + (while + (and (< (point) limit) + (progn + ;; In the next loop, we keep searching forward + ;; whilst we find ":"s which aren't single colons + ;; inside C++ "for" statements. + (while + (and + (< (point) limit) + (prog1 + (setq found + (c-syntactic-re-search-forward + "[;:,]\\|\\(=\\|\\s(\\)" + limit 'limit t)) + (setq got-init + (and found (match-beginning 1)))) + (eq (char-before) ?:) + (not + (and (c-major-mode-is '(c++-mode java-mode)) + (save-excursion + (and + (c-go-up-list-backward) + (eq (char-after) ?\() + (progn (c-backward-syntactic-ws) + (c-simple-skip-symbol-backward)) + (looking-at c-paren-stmt-key))))) + (if (looking-at c-:-op-cont-regexp) + (progn (goto-char (match-end 0)) t) + ;; Does this : introduce the class + ;; initialization list, or a bitfield? + (not arglist)))) ; Carry on for a bitfield + found) + (when (eq (char-before) ?\[) + (setq brackets-after-id t) + (prog1 (c-go-up-list-forward) + (c-forward-syntactic-ws))))) + (when (and found + (memq (char-before) '(?\; ?\: ?, ?= ?\( ?\[ ?{))) + (backward-char)) + (<= (point) limit)))) (list id-start id-end brackets-after-id got-init decorated arglist) (goto-char here) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 732b2b1054..2003b09ded 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -2458,9 +2458,12 @@ with // and /*, not more generic line and block comments." (goto-char pos) (let ((lit-start (c-literal-start)) (lim (c-determine-limit 1000)) - enclosing-attribute pos1) + enclosing-attribute pos1 ml-delim) (if lit-start (goto-char lit-start)) + (when (and lit-start c-ml-string-opener-re + (setq ml-delim (c-ml-string-opener-around-point))) + (goto-char (car ml-delim))) (c-backward-syntactic-ws lim) (when (setq enclosing-attribute (c-enclosing-c++-attribute)) (goto-char (car enclosing-attribute)) ; Only happens in C++ Mode. @@ -2471,43 +2474,43 @@ with // and /*, not more generic line and block comments." (c-backward-syntactic-ws lim)) (when (setq pos1 (c-on-identifier)) (goto-char pos1) - (let* ((lim (save-excursion - (and (c-beginning-of-macro) - (progn (c-end-of-macro) (point))))) - (decl-res (c-forward-declarator lim))) - (if (or (cadr (cddr (cddr decl-res))) ; We scanned an arglist. - (and (eq (char-after) ?\() ; Move over a non arglist (...). - (prog1 (c-go-list-forward nil lim) - (c-forward-syntactic-ws lim)))) - (if (looking-at c-symbol-char-key) - ;; Deal with baz (foo((bar)) type var), where `pos' - ;; was inside foo, but foo((bar)) is not semantically - ;; valid. The result must be after var). - (and - (goto-char pos) - (setq pos1 (c-on-identifier)) - (goto-char pos1) - (progn - (c-backward-syntactic-ws lim) - (eq (char-before) ?\()) - (c-fl-decl-end (1- (point)))) - (c-backward-syntactic-ws lim) - (point)) - (if (progn (c-forward-syntactic-ws lim) - (not (eobp))) - (progn - (c-forward-over-token) - ;; Cope with having POS withing a syntactically invalid - ;; (...), by moving backward out of the parens and trying - ;; again. - (when (and (eq (char-before) ?\)) - (c-go-list-backward (point) lim)) - (c-fl-decl-end (point)))) - (let ((lit-start (c-literal-start))) - (when lit-start - (goto-char lit-start)) - (c-backward-syntactic-ws))) - (and (>= (point) pos) (point))))))) + (let* ((lim1 (save-excursion + (and (c-beginning-of-macro) + (progn (c-end-of-macro) (point))))) + (decl-res (c-forward-declarator))) + (if (or (cadr (cddr (cddr decl-res))) ; We scanned an arglist. + (and (eq (char-after) ?\() ; Move over a non arglist (...). + (prog1 (c-go-list-forward) + (c-forward-syntactic-ws)))) + (if (looking-at c-symbol-char-key) + ;; Deal with baz (foo((bar)) type var), where `pos' + ;; was inside foo, but foo((bar)) is not semantically + ;; valid. The result must be after var). + (and + (goto-char pos) + (setq pos1 (c-on-identifier)) + (goto-char pos1) + (progn + (c-backward-syntactic-ws lim1) + (eq (char-before) ?\()) + (c-fl-decl-end (1- (point)))) + (c-forward-over-token) + (point)) + (if (progn (c-forward-syntactic-ws) + (not (eobp))) + (progn + (c-forward-over-token) + ;; Cope with having POS withing a syntactically invalid + ;; (...), by moving backward out of the parens and trying + ;; again. + (when (and (eq (char-before) ?\)) + (c-go-list-backward (point) lim1)) + (c-fl-decl-end (point)))) + (let ((lit-start (c-literal-start))) + (when lit-start + (goto-char lit-start)) + (c-backward-syntactic-ws))) + (and (>= (point) pos) (point))))))) (defun c-change-expand-fl-region (_beg _end _old-len) ;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock commit 9565f45876f4911a0f27fced215f7e86d59655e8 Author: Lars Ingebrigtsen Date: Tue Oct 4 15:09:33 2022 +0200 Move image commands to the 'i' sub map * doc/lispref/display.texi (Showing Images): Adjust. * lisp/image.el (image-map): Move all keys under the "i" prefix. (image--repeat-map): New map. (image-increase-size, image-rotate, image-decrease-size): Make repeatable. (image--delayed-change-size): New function. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 0c217e329e..64400ef931 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -6850,28 +6850,37 @@ keymap installed in the text properties (or overlays) that span the displayed image. This keymap defines the following commands: @table @kbd -@item + +@item i + Increase the image size (@code{image-increase-size}). A prefix value of @samp{4} means to increase the size by 40%. The default is 20%. -@item - +@item i - Decrease the image size (@code{image-increase-size}). A prefix value of @samp{4} means to decrease the size by 40%. The default is 20%. -@item r +@item i r Rotate the image by 90 degrees clockwise (@code{image-rotate}). A prefix means to rotate by 90 degrees counter-clockwise instead. -@item o +@item i h +Flip the image horizontally (@code{image-flip-horizontally}). + +@item i v +Flip the image vertically (@code{image-flip-vertically}). + +@item i o Save the image to a file (@code{image-save}). -@item c +@item i c Crop the image interactively (@code{image-crop}). -@item x +@item i x Cut a rectangle from the image interactively (@code{image-cut}). @end table +The size and rotation commands are ``repeating'', which means that you +can continue adjusting the image without using the @kbd{i} prefix. + @node Multi-Frame Images @subsection Multi-Frame Images @cindex multi-frame images diff --git a/etc/NEWS b/etc/NEWS index d4934fb98d..23425eb556 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -193,6 +193,16 @@ of 'user-emacs-directory'. * Incompatible changes in Emacs 29.1 ++++ +*** The image commands have changed key bindings. +In previous Emacs versions, images have had the '+', '-' and 'r' keys +bound when point is over an image. In Emacs 29.1, additional commands +were added, and this made it more likely that users would trigger the +image commands by mistake. To avoid this, all image commands have +moved to the 'i' keymap, so '+' is now 'i +', '-' is now 'i -', and +'r' is now 'i r'. In addition, these commands are now repeating, so +you can rotate an image twice by saying 'i r r', for instance. + +++ *** Emacs now picks the correct coding system for X input methods. Previously, Emacs would use the locale coding system for input @@ -2134,7 +2144,8 @@ this message for SVG and XPM. +++ *** New commands: 'image-flip-horizontally' and 'image-flip-vertically'. -These commands horizontally and vertically flip the image under point. +These commands horizontally and vertically flip the image under point, +and are bound to 'i h' and 'i v', respectively. +++ *** New command 'image-transform-set-percent'. @@ -2685,8 +2696,8 @@ name. +++ ** New commands 'image-crop' and 'image-cut. These commands allow interactively cropping/cutting the image at -point. The commands are bound to keys 'c' and 'x' (respectively) in -the local keymap over images. They rely on external programs, by +point. The commands are bound to keys 'i c' and 'i x' (respectively) +in the local keymap over images. They rely on external programs, by default "convert" from ImageMagick, to do the actual cropping/eliding of the image file. diff --git a/lisp/image.el b/lisp/image.el index 18b840a651..b6817d3fda 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -174,14 +174,15 @@ or \"ffmpeg\") is installed." (defvar-keymap image-map :doc "Map put into text properties on images." - "-" #'image-decrease-size - "+" #'image-increase-size - "r" #'image-rotate - "o" #'image-save - "c" #'image-crop - "x" #'image-cut - "h" #'image-flip-horizontally - "v" #'image-flip-vertically + "i" (define-keymap + "-" #'image-decrease-size + "+" #'image-increase-size + "r" #'image-rotate + "o" #'image-save + "c" #'image-crop + "x" #'image-cut + "h" #'image-flip-horizontally + "v" #'image-flip-vertically) "C-" #'image-mouse-decrease-size "C-" #'image-mouse-decrease-size "C-" #'image-mouse-increase-size @@ -1151,41 +1152,43 @@ has no effect." (imagemagick-register-types) +(defvar-keymap image--repeat-map + "+" #'image-increase-size + "-" #'image-decrease-size + "r" #'image-rotate) + (defun image-increase-size (&optional n position) "Increase the image size by a factor of N. If N is 3, then the image size will be increased by 30%. The default is 20%." (interactive "P") + (image--delayed-change-size (if n + (1+ (/ (prefix-numeric-value n) 10.0)) + 1.2) + position) + (set-transient-map image--repeat-map nil nil + "Use %k for further adjustments")) + +(defun image--delayed-change-size (size position) ;; Wait for a bit of idle-time before actually performing the change, ;; so as to batch together sequences of closely consecutive size changes. ;; `image--change-size' just changes one value in a plist. The actual ;; image resizing happens later during redisplay. So if those ;; consecutive calls happen without any redisplay between them, ;; the costly operation of image resizing should happen only once. - (run-with-idle-timer 0.3 nil - #'image--change-size - (if n - (1+ (/ (prefix-numeric-value n) 10.0)) - 1.2) - position)) + (run-with-idle-timer 0.3 nil #'image--change-size size position)) (defun image-decrease-size (&optional n position) "Decrease the image size by a factor of N. If N is 3, then the image size will be decreased by 30%. The default is 20%." (interactive "P") - ;; Wait for a bit of idle-time before actually performing the change, - ;; so as to batch together sequences of closely consecutive size changes. - ;; `image--change-size' just changes one value in a plist. The actual - ;; image resizing happens later during redisplay. So if those - ;; consecutive calls happen without any redisplay between them, - ;; the costly operation of image resizing should happen only once. - (run-with-idle-timer 0.3 nil - #'image--change-size - (if n - (- 1 (/ (prefix-numeric-value n) 10.0)) - 0.8) - position)) + (image--delayed-change-size (if n + (- 1 (/ (prefix-numeric-value n) 10.0)) + 0.8) + position) + (set-transient-map image--repeat-map nil nil + "Use %k for further adjustments")) (defun image-mouse-increase-size (&optional event) "Increase the image size using the mouse." @@ -1270,7 +1273,9 @@ rotations by only multiples of 90 degrees." (or angle 90)) ;; We don't want to exceed 360 degrees rotation, ;; because it's not seen as valid in Exif data. - 360))))) + 360)))) + (set-transient-map image--repeat-map nil nil + "Use %k for further adjustments")) (defun image-save () "Save the image under point. commit 07257ac4eedcaedd8731b3b98e723850542aab8e Author: Lars Ingebrigtsen Date: Tue Oct 4 14:31:24 2022 +0200 Fix the arguments in tags--compat-initialize * lisp/progmodes/etags.el (tags--compat-initialize): Fix argument order -- swap the last two arguments (bug#58272). diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index db2c8efbd4..85c5992998 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -1784,10 +1784,10 @@ Bind `case-fold-search' during the evaluation, depending on the value of (defun tags--compat-initialize (initialize) (fileloop-initialize (tags--compat-files initialize) + (lambda () (tags-loop-eval tags-loop-scan)) (if tags-loop-operate (lambda () (tags-loop-eval tags-loop-operate)) - (lambda () (message "Scanning file %s...found" buffer-file-name) nil)) - (lambda () (tags-loop-eval tags-loop-scan)))) + (lambda () (message "Scanning file %s...found" buffer-file-name) nil)))) ;;;###autoload (defun tags-loop-continue (&optional first-time) commit 0f1aabcbaa3d50b81bea7bedaa33c9351644c130 Author: Po Lu Date: Tue Oct 4 20:26:37 2022 +0800 Update Ukrainian language info alist * lisp/language/cyrillic.el ("Ukrainian"): Replace "Glory to Ukraine" with "hello". See www.gnu.org/prep/maintain/html_node/Other-Politics.html. diff --git a/lisp/language/cyrillic.el b/lisp/language/cyrillic.el index 078c22746b..753e99e9d4 100644 --- a/lisp/language/cyrillic.el +++ b/lisp/language/cyrillic.el @@ -137,7 +137,7 @@ Support for Russian using koi8-r and the russian-computer input method.") (coding-priority koi8-u) (nonascii-translation . koi8-u) (input-method . "ukrainian-computer") - (sample-text . "Ukrainian (Українська) Слава Україні!") + (sample-text . "Ukrainian (Українська) Доброго дня!") (documentation . "Support for Ukrainian with KOI8-U character set.")) '("Cyrillic")) commit 4f58d81b446b757afd9464fa66270abcc8ec02dc Author: Denys Nykula Date: Tue Oct 4 14:17:38 2022 +0200 Add Ukrainian tutorial * etc/tutorials/TUTORIAL.uk: Create the translation. * lisp/language/cyrillic.el: Link "Emacs Tutorial" to the translation if the system is Ukrainian, and add our modern greeting as a sample text. * etc/NEWS: * etc/tutorials/TUTORIAL.translators: Attribute my work (bug#55250). diff --git a/etc/NEWS b/etc/NEWS index 78fc431e82..d4934fb98d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1323,6 +1323,9 @@ supported. Type 'C-u C-h t' to select it in case your language setup does not do so automatically. +--- +*** New Ukrainian translation of the Emacs Tutorial. + --- *** New default phonetic input method for the Tamil language environment. The default input method for the Tamil language environment is now diff --git a/etc/tutorials/TUTORIAL.translators b/etc/tutorials/TUTORIAL.translators index 891b6a1682..64d71b61e8 100644 --- a/etc/tutorials/TUTORIAL.translators +++ b/etc/tutorials/TUTORIAL.translators @@ -90,6 +90,10 @@ Maintainer: Mats Lidell Author: Virach Sornlertlamvanich Maintainer: Virach Sornlertlamvanich +* TUTORIAL.uk: +Author: Denys Nykula +Maintainer: Denys Nykula + * TUTORIAL.zh: Author: Chao-Hong Liu Maintainer: Chao-Hong Liu diff --git a/etc/tutorials/TUTORIAL.uk b/etc/tutorials/TUTORIAL.uk new file mode 100644 index 0000000000..4ce59b75f5 --- /dev/null +++ b/etc/tutorials/TUTORIAL.uk @@ -0,0 +1,1150 @@ +Посібник Emacs. Умови копіювання в кінці. + +Команди Emacs передбачають використання клавіші CONTROL (часто +підписаної CTRL чи CTL) або клавіші META (зазвичай підписаної ALT). +Щоб не писати цього щоразу повністю, використовуємо такі скорочення: + + C-<симв> означає затиснути клавішу CONTROL і натиснути клавішу + <симв>. Тобто C-f — це затиснути CONTROL і натиснути f. + + M-<симв> означає затиснути клавішу META чи ALT і натиснути <симв>. + Якщо не маєте клавіші META чи ALT, натисніть по черзі + клавіші ESC та <симв>. Клавішу ESC ми позначаємо . + +Щоб редагувати український текст в Emacs, перемкніться на англійську +розкладку й наберіть C-\ — це активує український режим введення +Emacs, у якому працюватимуть як слід усі описані в посібнику команди. +Щоб знову вводити англійські символи, повторіть C-\. + +Зауважте: щоб завершити сеанс Emacs, наберіть C-x C-c. (Два символи.) +Щоб скасувати частково введену команду, наберіть C-g. Щоб закрити +посібник, наберіть C-x k, а тоді при запиті натисніть (цю +клавішу може бути підписано Enter). Абзаци, що містять „»»“ на +початку, — це вказівки, які вам слід виконати, щоб спробувати +використати ту чи іншу команду. Наприклад: +<<Програма help-with-tutorial огортає наступний рядок відступами>> +[Кілька навмисне порожніх рядків. Скоро зрозумієте, навіщо.] +»» Прямо зараз наберіть C-v (view — переглянути), щоб прогорнути + посібник униз. (Затисніть клавішу CONTROL і наберіть v.) + Робіть так щоразу, коли дочитуєте до кінця екрана. + +Як бачите, гортається не цілий екран, а на два рядки менше; це +допомагає не губитись, коли читаєте довгі тексти. + +Це одноразова, трошки адаптована спеціально для вас копія тексту +посібника Emacs. Будемо пропонувати вам випробовувати прямо на цьому +тексті різні команди, які його змінюватимуть. Якщо зміните цей текст +самостійно навіть без наших вказівок — чудово, це називається +«редагування» й саме для цього створено Emacs. + +Перш за все навчимось пересуватися текстом. Ви вже знаєте, як +прогорнути один екран уперед: C-v. Прогорнути один екран назад — це +M-v (затисніть клавішу META й наберіть v — або наберіть v, якщо +не маєте ні клавіші META, ні клавіші ALT). + +»» Спробуйте набрати M-v й тоді C-v кілька разів по черзі. + +Якщо знаєте інші способи гортати текст, то можете, звісно, +застосовувати і їх. + +* ПІДСУМОК +---------- + +Наступні команди допомагають гортати екрани тексту: + + C-v (View — переглянути.) + Перейти на наступний екран. + + M-v Перейти на попередній екран. + + C-l (Clear — очистити.) + Очистити екран і вивести текст заново, центруючи екран + на тексті біля курсора. (Це CONTROL-L, не CONTROL-1.) + +»» Знайдіть курсор і зверніть увагу, який біля нього текст. Наберіть + C-l. Знайдіть, куди змістився курсор, і зауважте, що біля курсора + досі той самий текст, просто він тепер у центрі екрана. Якщо знов + натиснете C-l, цей самий текст посунеться догори екрана. Натисніть + C-l іще раз, і він посунеться донизу. + +Можете також гортати екрани клавішами PageUp і PageDn, якщо ваш +термінал їх має. Але з C-v та M-v ви редагуватимете спритніше. + +* ОСНОВИ КЕРУВАННЯ КУРСОРОМ +--------------------------- + +Гортати екран за екраном — це вже непогано, але як перейти до +конкретного місця в тексті на екрані? + +Є кілька способів. Можна рухатись клавішами стрілок, але зручніше +тримати руки в стандартному положенні й використовувати команди C-p +(previous — попередній), C-b (backward — назад), C-f (forward — +уперед) і C-n (next — наступний). Ці символи рівнозначні +чотирьом клавішам стрілок: + + Попередній рядок, C-p + : + : + Назад, C-b .... Де курсор зараз .... Уперед, C-f + : + : + Наступний рядок, C-n + +»» Посуньте курсор до рядка посередині рисунка вгорі за допомогою C-n + та C-p. Тоді наберіть C-l, щоб центрувати екран на рисунку. + +Літери в скороченнях Emacs легко запам'ятати за відповідними їм +англійськими словами, як зазначено вгорі. Ці основні команди руху +курсора ви будете використовувати весь час. + +»» Наберіть C-n кілька разів, щоб посунути курсор до цього рядка. + +»» Посуньте курсор до якого-небудь слова в рядку, набравши C-f + декілька разів, а тоді поверніться вгору кількома натисками C-p. + Зауважте, як C-p поводиться, коли курсор не на початку рядка. + +Кожен рядок тексту закінчується символом нового рядка: цей символ +технічно відділяє рядок від наступного. (Зазвичай останній рядок у +файлі теж закінчується символом нового рядка, проте Emacs цього не +вимагає.) + +»» Спробуйте C-b на початку рядка. Курсор має зміститись у кінець + попереднього рядка, бо рух назад (backward) «проїде» по символу + нового рядка. + +C-f — рух уперед (forward) — уміє «їздити» по символах нового рядка +так само, як і C-b. + +»» Наберіть C-b іще кілька разів, щоб відчути, яким чином рухається + курсор. Тоді поверніться в кінець того рядка, з якого почали рух: + кілька разів наберіть C-f. Тоді перейдіть іще одним C-f до + наступного рядка. + +Коли ваш рух перетинає верх чи низ екрана, текст із-за краю +посувається на екран. Це називається «гортання», або scrolling. +Таким чином курсор, куди б у тексті ви його не спрямували, залишається +в межах екрана Emacs. + +»» Спробуйте посунути курсор за нижню межу екрана кількома натисками + C-n — і зверніть увагу на поведінку. + +Коли рухатися символами надто повільно, рухайтеся словами. M-f +(META-f) посуває курсор через ціле слово вперед (forward), а M-b — +через слово назад (backward). + +»» Наберіть M-f і M-b по кілька разів. + +Коли ви посеред слова, M-f посуває курсор до кінця слова. Коли ви на +пробілі, M-f посуває курсор у кінець наступного слова. M-b працює +аналогічно в зворотному напрямі. + +»» Наберіть іще кілька M-f і M-b, розділяючи їх натисками C-f і C-b, + щоб поспостерігати за поведінкою M-f і M-b залежно від перебування + курсора в різних місцях усередині слів і між словами. + +Простежте паралелі між C-f і C-b з одного боку та M-f і M-b з іншого. +Часто Meta-символи використовуються для роботи з одиницями, +визначеними мовою: зі словами, реченнями, абзацами. Тоді як +Control-символи працюють із низькорівневими одиницями, без огляду на +редаговане середовище: з символами, рядками тощо. + +Ця паралель стосується також рядків і речень: C-a та C-e посувають до +початку чи кінця рядка, тоді як M-a та M-e посувають до початку чи +кінця речення. + +»» Наберіть C-a кілька разів, тоді наберіть C-e кілька разів. + Наберіть M-a кілька разів, тоді наберіть M-e кілька разів. + +Зверніть увагу на те, як повторні натиски C-a не викликають нових +рухів, а от повтори M-a щоразу рухають вас на одне речення назад. +Поведінка дещо різна, втім природна для кожного контексту. + +Координати курсора в тексті називаються «точкою». Іншими словами, +курсор позначає на екрані поточну точку в тексті. + +Ось підсумок простих операцій посування курсора, зокрема команд руху +словами й реченнями: + + C-f (Forward — уперед.) Перейти на символ уперед + C-b (Backward — назад.) Перейти на символ назад + + M-f Перейти на слово вперед + M-b Перейти на слово назад + + C-n (Next — наступний.) До наступного рядка + C-p (Previous — попередній.) До попереднього рядка + + C-a (Alpha — початок.) Перейти на початок рядка + C-e (End — кінець.) Перейти в кінець рядка + + M-a Перейти назад на початок речення + M-e Перейти вперед у кінець речення + +»» Випробуйте всі ці команди по кілька разів для практики. + Ними ви користуватиметесь частіше за всі інші. + +Дві інші важливі команди руху курсора — це M-< (META-менше), яка веде +на початок усього тексту, й M-> (META-більше), яка веде в кінець +усього тексту. + +На більшості терміналів знак „<“ — над латинською комою, тобто ви +затискаєте SHIFT, щоб його набрати. Відповідно M-< означає затиск не +лише клавіші META, а ще й клавіші SHIFT. Без SHIFT вийде M-кома. + +»» Спробуйте М-< зараз, щоб перейти на початок посібника. + Тоді кілька разів наберіть C-v, щоб повернутись сюди. + +»» Спробуйте М-> зараз, щоб перейти в кінець посібника. + Тоді кілька разів наберіть M-v, щоб повернутись сюди. + +Можете також рухати курсор клавішами стрілок, якщо ваш термінал має +такі клавіші. Втім, радимо опанувати C-b, C-f, C-n і C-p з трьох +причин. По-перше, вони працюють на будь-яких терміналах. По-друге, +практикуючи використання Emacs, ви невдовзі виявите, що набирати ці +Control-символи швидше, ніж набирати стрілки (бо вам не доводиться +зсувати руки з набірного положення). По-третє, щойно ви звикнете до +використання цих команд із Control-символами, вам стане легко +опанувати й інші розширені команди посування курсора. + +Більшість команд Emacs приймають числовий аргумент; для більшості +команд він означає кількість повторів. Щоб передати команді кількість +повторів, набирайте C-u і цифри, перш ніж набрати команду. Якщо маєте +клавішу META (чи ALT), то маєте й інший, альтернативний шлях увести +числовий аргумент: наберіть цифри, затиснувши клавішу META. Радимо +опанувати шлях C-u, бо він працює на будь-яких терміналах. Числовий +аргумент також називається «префіксним аргументом», бо ви набираєте +його перед відповідною йому командою. + +Наприклад, C-u 8 C-f посуває курсор на вісім символів уперед. + +»» Спробуйте використати C-n чи C-p з числовим аргументом, щоб + посунути курсор до рядка поруч із цим рядком єдиною командою. + +Числовий аргумент означає для більшості команд кількість повторів, але +деякі команди використовують його інакше. Декілька команд (але не ті, +які вам уже відомі) використовують його як прапор: коли передаєте їм +префіксний аргумент, це незалежно від значення змушує команду робити +щось нетипове. + +C-v та M-v також є винятком. За наявності аргументу вони гортають +текст угору чи вниз на означену ним кількість рядків, а не на цілий +екран. Наприклад, C-u 8 C-v прокручує 8 рядків. + +»» Спробуйте набрати C-u 8 C-v прямо зараз. + +Це мало прогорнути текст на 8 рядків угору. Якщо бажаєте прогорнути +його знов донизу, передайте аргумент команді M-v. + +Якщо ви користуєтесь графічним середовищем, наприклад X чи MS-Windows, +то з одного боку вікна Emacs має бути висока прямокутна область, яка +називається панеллю гортання. Можете гортати текст, натискаючи панель +гортання кнопкою миші. + +Якщо у вашої миші є колесо гортання, можете гортати й ним. + + +* ЯКЩО EMACS НЕ ВІДПОВІДАЄ +-------------------------- + +Якщо Emacs перестає відповідати на ваші команди, можете дати йому +копняка, набравши C-g. Використовуйте C-g, щоб припинити команду, яка +виконується надто довго. + +Також використовуйте C-g, щоб відхилити числовий аргумент або початок +команди, яку передумали дописувати. + +»» Наберіть C-u 100, щоб зазначити числовий аргумент «100». Наберіть + C-g. Тепер наберіть C-f. Курсор має посунутись лише на один + символ, бо ви скасували аргумент набранням C-g. + +Ненароком набравши , можете позбутись і його за допомогою C-g. + + +* ВИМКНЕНІ КОМАНДИ +------------------ + +Деякі команди Emacs усталено «вимкнені», щоб не плутати користувачок і +користувачів, які лише починають його вивчати. + +Коли ви набираєте ту чи іншу вимкнену команду, Emacs показує її назву +й запитує, чи точно ви бажаєте виконати цю команду. + +Якщо ви справді бажаєте спробувати команду, наберіть (пробіл) у +відповідь на запитання. Зазвичай, не бажаючи виконувати вимкнену +команду, відповідайте на це питання «n». + +»» Наберіть C-x C-l (цю команду вимкнено), а тоді наберіть n у + відповідь на запитання. + + +* WINDOWS +--------- + +Emacs може мати кілька «вікон» — кожне зі своїм текстом. Згодом +пояснимо, як використовувати декілька вікон одразу. Поки що слід +розібратись, як позбутись зайвих вікон і повернутись до простого +редагування в одному вікні. Це просто: + + C-x 1 Одне вікно (тобто припинити всі інші вікна). + +Це означає набір CONTROL-x і цифри 1. C-x 1 розширює вікно, яке +містить курсор, на весь екран, і видаляє всі інші вікна. + +»» Посуньте курсор до цього рядка й наберіть C-u 0 C-l. Тоді наберіть + C-h k C-f. Це вікно звузиться, й з'явиться нове вікно, в якому + буде показано документацію про команду C-f. + +»» Наберіть C-x 1 — вікно документації зникне. + +Є цілі набори команд, які починаються з CONTROL-x; більшість із них +стосуються вікон, файлів, буферів тощо. Ці команди містять два, три +або чотири символи. + + +* ВВЕДЕННЯ Й ВИДАЛЕННЯ +---------------------- + +Якщо бажаєте ввести текст, просто наберіть цей текст. Звичайні +символи, такі як A, 7, * тощо, вводяться прямо при набранні. Аби +ввести символ нового рядка, натисніть (ця клавіша на +клавіатурі часом підписана «Enter»). + +Щоб видалити символ перед курсором, наберіть . Ця клавіша на +клавіатурі зазвичай підписана «Backspace» — та сама, якою за межами +Emacs ви зазвичай видаляєте останній набраний символ. + +На клавіатурі зазвичай є ще одна клавіша з підписом , але в +Emacs ми позначаємо не її. + +»» Прямо зараз наберіть кілька символів, а тоді видаліть їх, набравши + кілька разів. Сміливо змінюйте цей файл; оригінал посібника + залишиться недоторканим. Це ваша особиста одноразова копія. + +Коли рядок тексту завеликий для одного рядка на екрані, цей рядок +тексту «продовжується» на ще один екранний рядок. Якщо ви +користуєтесь графічним середовищем, на кожному боці текстової області +(на лівому й правому «полях») з'являються маленькі вигнуті стрілки — +позначки, де було продовжено той чи інший рядок. Якщо ви користуєтесь +текстовим терміналом, продовжений рядок позначається оберненою скісною +рискою («\») в крайній правій колонці екрана. + +»» Вводьте текст, доки не сягнете правого поля, а тоді вводьте ще. + Побачите, як з'явиться рядок продовження. + +»» Натискайте раз за разом, щоб видаляти символи, доки рядок + тексту не вміститься знову в один екранний рядок. Рядок + продовження зникне. + +Символ нового рядка можете видалити так само, як будь-який інший. +Видалення символу нового рядка між двома рядками зливає їх в один +рядок. Якщо в результаті сполучений рядок ширший, ніж екран, то його +буде показано з рядком продовження. + +»» Посуньте курсор на початок рядка й наберіть . Це + зіллє той рядок із попереднім. + +»» Наберіть , щоб відновити символ нового рядка на місці щойно + видаленого. + +Клавіша особлива тим, що її натиск може не лише вводити +символ нового рядка. Залежно від навколишнього тексту, її натиск може +ввести пробіли після символу нового рядка таким чином, щоб текст у +новоствореному рядку одразу вирівнювався відносно тексту попереднього +рядка. Ми називаємо цю поведінку (складнішу дію клавіші, ніж просто +введення відповідного символу) «електричною». + +»» Щоб побачити електричну поведінку , + наберіть у кінці цього рядка. + +Простежте, як при введенні символу нового рядка Emacs вводить пробіли +таким чином, що курсор опиняється під «н» слова «наберіть». + +Пам'ятайте, більшості команд Emacs можливо передати кількість +повторень; це стосується й текстових символів. Повторення текстового +символу вводить цей символ декілька разів. + +»» Спробуйте зараз набрати C-u 8 *, аби ввести ********. + +Ви опанували основний спосіб набрати щось в Emacs і виправити помилки. +Також можна видаляти цілі слова й рядки. Ось підсумок операцій +видалення: + + Видалити символ перед курсором + C-d (Delete — видалити.) Видалити символ після курсора + + M- Вирізати слово перед курсором + M-d Вирізати слово після курсора + + C-k (Kill — вирізати.) Вирізати з рядка все після курсора + M-k Вирізати з речення все після курсора + +Зважте на те, як і C-d продовжують щодо M- і M-d паралелі, +розпочаті C-f і M-f (технічно не є керівним символом, але зараз +це несуттєво). C-k та M-k подібні до C-e та M-e тим, як вони працюють +із рядками й реченнями відповідно. + +Є також спосіб вирізати одразу багато тексту. Перейдіть на початок чи +в кінець потрібної частини тексту й натисніть C-. ( — +пробіл.) Тоді посуньте курсор на інший край частини тексту, яку +бажаєте вирізати. Коли ви це робитимете, Emacs підсвітить текст між +курсором і тим місцем, де ви набрали C-. Нарешті наберіть C-w +(whole — повністю). Це повністю виріже позначений текст. + +»» Посуньте курсор до «Є» на початку попереднього абзацу. +»» Введіть C-. Emacs має показати повідомлення «Mark set» + («Позначку встановлено») внизу екрана. +»» Посуньте курсор до «п» в слові «потрібної» другого рядка абзацу. +»» Наберіть C-w. Це виріже текст від «Є» включно до «п» не включно. + Якби ви набрали M-w, це його лише скопіювало б. + +Вирізання й видалення відрізняються тим, що вирізаний текст можливо +вставити (будь-куди), тоді як видалене вставити неможливо (втім, +можливо скасувати видалення — про це згодом). Вставка, так би мовити, +виймає (yank) раніше вилучений текст. Зазвичай усі команди, які +вилучають багато тексту, вирізають його (їх налаштовано таким чином, +щоб ви могли потім вставити цей текст); а от команди, які вилучають +лише один символ або порожні рядки чи пробіли, просто їх видаляють +(без можливості вставлення). і C-d без аргументу здійснюють +видалення. За наявності аргументу вони вирізають. + +»» Посуньте курсор на початок рядка, в якому є символи. + Тоді наберіть C-k, щоб вирізати текст у цьому рядку. +»» Наберіть C-k іще раз. Це виріже той символ нового рядка, + що завершує цей рядок. + +Зауважте, перший C-k вирізає вміст рядка, а другий C-k вирізає сам +рядок і зсуває догори всі наступні рядки. C-k із числовим аргументом +працює інакше: вирізає водночас вміст і самі рядки. Це не просто +повторення. C-u 2 C-k вирізає два рядки разом із їхніми символами +нового рядка; набравши C-k двічі, ви отримаєте інший результат. + +Можете вставити вирізаний текст туди ж, звідки його вирізали, або до +певного іншого місця в редагованому тексті — навіть в інший файл. +Можете вставляти один і той самий текст кілька разів; це створить +кілька його копій. Англійською вирізання називають «kill» або «cut», +виймання (вставку) — «yank» або «paste»; перегляньте згодом глосарій у +підручнику Emacs. + +Команда C-y вставляє останній вирізаний текст туди, де зараз курсор. + +»» Спробуйте набрати C-y, щоб вставити текст назад. + +Якщо наберете C-k декілька разів поспіль, увесь вирізаний текст +збережеться разом, щоб одною командою C-y ви могли вставити водночас +усі рядки. + +»» Спробуйте зараз набрати C-k декілька разів. + +Тепер отримаймо вирізаний текст: + +»» Наберіть C-y. Посуньте курсор на кілька рядків униз і наберіть C-y + знову. Тепер ви знаєте, як копіювати текст. + +Що робити, коли вже вирізали певний текст для вставки, але після цього +вирізали ще щось? C-y вставляє найновіше вирізане. Проте минулого +вирізаного не втрачено. Можете повернутись до нього командою M-y. +Набравши C-y та вийнявши цим найновіше вирізане, наберіть M-y іще раз, +щоб замінити вставлений текст на попереднє вирізане. Набирайте M-y +знову й знову, щоб виймати минулі вирізання. Досягнувши шуканого +тексту, ви не маєте більше нічого робити, щоб його зафіксувати. +Просто продовжуйте редагувати, залишивши вставлений текст на місці. + +Набравши M-y достатньо разів, виймете найновіше вирізане знову. + +»» Виріжте рядок, посуньте курсор і виріжте ще один рядок. + +»» Тоді наберіть C-y, щоб отримати другий вирізаний рядок. Тоді + наберіть M-y, і той рядок заміниться на перший вирізаний рядок. + +»» Наберіть M-y іще кілька разів і простежте, що вийматиметься. + Продовжуйте набирати M-y, доки не виймете знову другий вирізаний + рядок, і тоді наберіть ще декілька M-y. За бажання спробуйте + передати M-y додатні чи від'ємні аргументи. + + +* СКАСУВАННЯ +------------ + +Помилково змінивши текст, можете скасувати цю зміну командою +скасування C-_, тобто затисніть Control та Shift і натисніть дефіс. + +Зазвичай C-_ скасовує зміни, внесені одною командою; якщо ви наберете +кілька C-_ поспіль, кожне повторення скасує ще по одній команді. + +Але є два винятки. Команди, які не змінюють тексту, не враховуються +(зокрема це команди руху курсора й команди гортання). Й текстові +символи зазвичай обробляються по 20 водночас. (Це щоб зменшити +кількість C-_, потрібних для скасування вставки тексту.) + +»» Виріжте цей рядок за допомогою C-k. Тоді наберіть C-_, щоб він + з'явився знову. + +C-/ — альтернативна команда скасування; вона працює так само, як C-_. +Деякі термінали дають змогу набирати C-_ без клавіші Shift. Деякі +термінали насправді передають Emacs саме C-_, коли ви набираєте C-/. +Ще є команда C-x u, котра працює так само, як C-_, але менш зручна для +набрання. Посібники для латинських розкладок описують команду C-/ як +основну, проте українською C-_ набирати легше. + +Числовий аргумент для C-_, C-/ чи C-x u працює як кількість повторень. + +Можете скасувати видалення тексту так само, як скасовуєте вирізання. +Відмінність між вирізанням і видаленням полягає в тому, чи можете ви +вставити текст за допомогою C-y; для скасування нема жодної різниці. + + +* ФАЙЛИ +------- + +Щоб зробити зміни до тексту постійними, їх треба зберегти до файлу. +Інакше ці зміни зникнуть при виході з Emacs. Аби зберегти текст до +файлу, вам потрібно «знайти» файл, перш ніж ввести текст. (Це також +називають «відкриттям» файлу.) + +Знаходження файлу показує його вміст усередині Emacs. Це виглядає, +ніби ви редагуєте файл безпосередньо. Проте зміни, які ви вносите за +допомогою Emacs, не стають постійними, доки ви не «збережете» файл. +Це щоб не залишати лише частково зміненого файлу в системі, коли ви +цього не бажаєте. Навіть після збереження Emacs залишає початковий +файл під іншою назвою, щоб ви змогли згодом скасувати зміни, якщо вони +виявляться помилковими. + +Якщо ви роздивитесь низ екрану, то помітите рядок, який містить дефіси +й починається з чогось на кшталт « -:--- TUTORIAL». Ця частина екрану +зазвичай показує назву файлу, який ви редагуєте. Зараз ви +переглядаєте свою особисту копію посібника Emacs, названу «TUTORIAL». +Коли ви знаходите файл за допомогою Emacs, назва цього файлу +показується саме в тому місці. + +Команда знаходження файлу особлива тим, що запитує вас, який файл вам +треба. Іншими словами, команда «зчитує аргумент» (у цьому випадку +аргумент — назва файлу). Після набрання команди: + + C-x C-f (Find — знайти.) Знайти файл + +Emacs попрохає вас набрати назву файлу. При введенні назву файлу +показано в нижньому рядку екрана. Нижній рядок називають мінібуфером, +коли він використовується для таких запитів. Можете використовувати +звичні команди редагування Emacs, щоб редагувати назву файлу. + +Коли ви вводите назву файлу (чи заповнюєте інший мінібуфер), можете +скасувати команду за допомогою C-g. + +»» Наберіть C-x C-f, а тоді наберіть C-g. Це скасує мінібуфер, а + також команду C-x C-f, яка використовувала мінібуфер. Тому ви не + знайдете жодного файлу. + +Коли ви введете назву файлу до кінця, наберіть , щоб завершити +введення. Мінібуфер зникне, й команда C-x C-f спробує знайти обраний +вами файл. + +Вміст файлу з'явиться на екрані, й ви зможете редагувати цей вміст. +Коли вирішите зберегти зміни на постійно, наберіть команду: + + C-x C-s (Save — зберегти.) Зберегти + +Це скопіює текст із Emacs до файлу. Коли ви робите це вперше, Emacs +перейменовує початковий файл, щоб його не було втрачено. Нова назва +формується доданням «~» у кінець назви початкового файлу. Завершивши +збереження, Emacs показує назву записаного файлу. + +»» Наберіть C-x C-s TUTORIAL . + Це має зберегти посібник у файл із назвою «TUTORIAL» і показати + «Wrote ...TUTORIAL» унизу екрана. + +Можете знайти вже наявний файл, щоб переглянути чи відредагувати його. +Або можете «знайти» файл, якого ще не існує. Так в Emacs створюють +файли: відкривають порожній файл і починають вводити текст у цей файл. +Коли ви попросите «зберегти» файл, Emacs насправді створить файл зі +введеним вами текстом. Відтоді можете вважати, що редагуєте вже +наявний файл. + + +* БУФЕРИ +-------- + +Коли знаходите ще один файл за допомогою C-x C-f, перший файл +залишається в Emacs. Можете перемкнутись на нього, знайшовши його +знову за допомогою C-x C-f. Таким чином в Emacs можливо відкрити +чимало файлів. + +Emacs зберігає текст кожного файлу всередині об'єкта — так званого +«буфера». Знаходження файлу створює буфер усередині Emacs. Щоб +переглянути перелік уже наявних буферів, наберіть + + C-x C-b (Buffer — буфер.) Перелічити буфери + +»» Спробуйте C-x C-b прямо зараз. + +Зауважте, що кожен буфер має власну назву, а ще біля нього може бути +назва того файлу, вміст якого він утримує. Будь-який текст, який ви +бачите у вікні Emacs, завжди є частиною певного буфера. + +»» Наберіть C-x 1, щоб позбутись переліку буферів. + +Коли буферів декілька, лише один із них може бути «поточним». Це той +буфер, який ви редагуєте. Якщо бажаєте редагувати інший буфер, на +нього слід «перемкнутись». Якщо бажаєте перемкнутись на буфер, що +відповідає певному файлу, відкрийте файл знову за допомогою C-x C-f. +Але простіше використати команду C-x b. Цій команді достатньо +передати назву буфера. + +»» Відкрийте файл «foo», набравши C-x C-f foo . Тоді наберіть + C-x b TUTORIAL , щоб повернутись до цього посібника. + +Зазвичай назва буфера збігається з назвою файлу (без шляху). Втім, це +не завжди так. Перелік буферів, відкритий за допомогою C-x C-b, +показує як назву буфера, так і назву файлу кожного буфера. + +Деякі буфери не відповідають файлам. Буфер *Buffer List* («Перелік +буферів»), який показує створені за допомогою C-x C-b буфери, не має +жодного файлу. Цей буфер TUTORIAL спершу не мав файлу, але тепер має, +бо в попередньому розділі ви набрали C-x C-s і зберегли його до файлу. + +Буфер *Messages* також не відповідає жодному файлу. Цей буфер містить +повідомлення, які з'являлись у нижньому рядку вашого сеансу Emacs. + +»» Наберіть C-x b *Messages* , щоб переглянути буфер + повідомлень. Тоді наберіть C-x b TUTORIAL , щоб + повернутись до цього посібника. + +Якщо змінити текст одного файлу й знайти інший файл, то перший файл не +буде збережено. Зміни залишаться всередині Emacs у буфері цього +файлу. Створення чи редагування буфера другого файлу не впливає на +буфер першого файлу. Це дуже корисно, але буфер першого файлу теж +треба якось зберігати. Перемикатись на цей буфер, щоб зберегти його +за допомогою C-x C-s, було б незручно. Тож маємо + + C-x s (Save — зберегти.) + Зберегти певні буфери до їхніх файлів + +C-x s запитує вас про кожен буфер, який ви змінили й не зберегли, чи +бажаєте ви його зберегти. + +»» Введіть рядок тексту й наберіть C-x s. + Маєте отримати запитання, чи бажаєте ви зберегти буфер TUTORIAL. + Погодьтесь, набравши у відповідь «y». + + +* РОЗШИРЕННЯ НАБОРУ КОМАНД +-------------------------- + +Команд Emacs значно більше, ніж можливо розкласти по всіх Control- і +Meta-символах. Emacs обходить це за допомогою команди x (extend — +розширити). Вона має два різновиди: + + C-x Запитує один символ. + M-x Запитує англійську назву команди. + +Ці команди дуже корисні, проте використовуються менш часто, ніж ті +команди, які ви вже опанували. Деякі з цих команд ви вже бачили, +наприклад файлові команди C-x C-f для знаходження й C-x C-s для +збереження. Ще один приклад — команда завершення сеансу Emacs: C-x +C-c пропонує зберегти кожен змінений файл, перш ніж зупинити Emacs. + +Якщо ви користуєтесь графічним середовищем, вам не потрібні жодні +додаткові команди для переходу від Emacs до іншого застосунку. Можете +переходити мишею чи командами менеджера вікон. Але якщо ви +користуєтесь текстовим терміналом, який може показувати лише один +повноекранний застосунок, то вам потрібно «призупинити» Emacs, щоб +перейти до іншого застосунку. + +Команда C-z виходить з Emacs *тимчасово* — тобто ви можете повернутись +до цього ж сеансу Emacs згодом. Коли Emacs запущено в текстовому +терміналі, C-z «призупиняє» Emacs, тобто повертає вас до оболонки, але +не припиняє завдання Emacs. У найпоширеніших оболонках ви можете +відновити Emacs командою «fg» або «%emacs». + +Використовувати C-x C-c слід перед виходом із системи. Ще цією +командою слід закривати той Emacs, який ви запустили для швидкого +редагування, наприклад за допомогою знаряддя обробки пошти. + +Команд C-x чимало. Ось перелік тих, які ви вже опанували: + + C-x C-f (Find — знайти.) Знайти файл. + C-x C-s (Save — зберегти.) Зберегти буфер до файлу. + C-x s Зберегти певні буфери до їхніх файлів. + C-x C-b (Buffer — буфер.) Перелічити буфери. + C-x b Перемкнути буфер. + C-x C-c (Close — закрити.) Вийти з Emacs. + C-x 1 Видалити всі вікна, крім одного. + C-x u (Undo — скасувати.) Скасувати останню дію. + +Розширені команди, які використовуються менш часто чи лише в певних +режимах, мають довші англійські назви. Наприклад, команда +replace-string («замінити рядок») змінює в буфері один рядок на інший. +Коли ви набираєте M-x, Emacs показує внизу екрана запит M-x, у +відповідь на який вам слід набрати назву команди — «replace-string» у +цьому випадку. Просто наберіть «repl s» — і Emacs допише назву +команди. ( — це клавіша Tab, яку зазвичай розміщено над клавішею +Caps Lock чи Shfift ліворуч на клавіатурі.) Підтвердьте назву команди +клавішею . + +Команда replace-string потребує двох аргументів: рядка, який слід +замінити, й рядка, яким ви його замінюєте. Введення кожного аргументу +потрібно завершити клавішею . + +»» Посуньте курсор до порожнього рядка двома рядки нижче, ніж цей. + Тоді наберіть M-x repl sзміненоперетворено. + + Зверніть увагу на те, як зміниться цей рядок: ви заміните слово + «змінено» на слово «перетворено» в усіх місцях після курсора, де + воно зустрічається. + + +* САМОЗБЕРЕЖЕННЯ +---------------- + +Коли ви змінюєте файл, але не зберігаєте змін, то ці зміни може бути +втрачено, якщо комп'ютер зазнає збою. Emacs захищає вас від цього +періодичним записом файлів «самозбереження» для кожного редагованого +файлу. Назва файлу самозбереження починається й закінчується символом +#, тобто якщо ваш файл називається «hello.c», його файл самозбереження +називатиметься «#hello.c#». Коли ви зберігаєте файл звичним шляхом, +Emacs видаляє відповідний файл самозбереження. + +Після збою комп'ютера ви можете відновити самозбережені правки, +знайшовши файл як зазвичай (редагований файл, не файл самозбереження) +й набравши M-x recover-this-file . (Команда перекладається як +«відновити цей файл».) У відповідь на запит підтвердження, наберіть +yes, щоб погодитись і відновити дані самозбереження. + + +* ВІДЛУННЯ +---------- + +Коли Emacs помічає, що ви поволі набираєте багатосимвольну команду, +він показує вам набрану частину команди внизу екрана в області, яку +називають echo — відлунням. Ця область покриває нижній рядок екрана. + + +* РЯДОК РЕЖИМУ +-------------- + +Рядок прямо над областю відлуння називають «рядком режиму». В рядку +режиму має виводитись щось таке: + + -:**- TUTORIAL 63% L749 (Fundamental) + +Цей рядок надає корисні дані про стан Emacs і редагованого тексту. + +Ви вже знаєте, що значить TUTORIAL: це назва того файлу, який ви +знайшли раніше. ЧЧ% повідомляє, в якій частині буфера тексту ви +перебуваєте; це означає, що ЧЧ відсотків буфера зараз над екраном. +Якщо верх буфера видно на екрані, то замість «0%» буде «Top» — «Верх». +Якщо низ буфера видно на екрані, то буде показано «Bot» — «Низ». +Якщо ви читаєте такий маленький буфер, що весь його вміст видно на +одному екрані, то в рядку режиму буде «All» — «Усе». + +Літера L (line — рядок) і цифри показують інший аспект вашого +місцеперебування — номер рядка поточної точки. + +Зірки спереду вказують, що ви змінили текст. Коли файл тільки +відкрито чи збережено, ця частина рядка режиму показує лише дефіси, +без зірок. + +Частина рядка режиму всередині дужок вказує, які режими редагування +наразі чинні. Типовий режим — це Fundamental («основний»); саме ним +ви зараз користуєтесь. Це один із «вищих» режимів. + +Emacs має чимало різних вищих режимів. Деякі з них призначені для +редагування різних мов і/або видів тексту, зокрема режим Lisp (для +мови програмування Лісп), режим Text (для тексту) тощо. В певну мить +активним може бути один і тільки один вищий режим, і його назву завжди +можна знайти в рядку режиму — там, де зараз ви бачите Fundamental. + +Кожен вищий режим змінює поведінку декількох команд. Наприклад, є +команди для створення коментарів у програмі, й оскільки кожна мова +програмування по-своєму визначає вигляд коментарів, то й кожен вищий +режим має вставляти коментарі по-своєму. Кожен вищий режим є назвою +тої команди розширення, якою ви його вмикаєте. Наприклад, командою +M-x fundamental-mode ви вмикаєте основний режим. + +Для редагування тексту мовами людського спілкування, такими як цей +файл, ви зазвичай використовуватимете режим Text. + +»» Наберіть M-x text-mode . + +Не переймайтесь, жодні з уже відомих вам команд Emacs не стануть +поводитись геть інакше. Проте ви можете помітити, що M-f і M-b тепер +обробляють апострофи як частини слів. Досі, в режимі Fundamental, M-f +і M-b обробляли апострофи як пунктуацію. + +Вищі режими зазвичай вносять саме такі невеличкі зміни: більшість +команд продовжують виконувати звичні завдання — з деякими +відмінностями в деталях. + +Щоб переглянути документацію про поточний вищий режим, наберіть C-h m. + +»» Посуньте курсор до рядка, наступного після цього. +»» Наберіть C-l C-l, щоб посунути цей рядок угору екрана. +»» Наберіть C-h m, щоб побачити різницю режимів Text і Fundamental. +»» Наберіть C-x, щоб вилучити документацію з екрана. + +Вищі режими називаються вищими, тому що бувають і нижчі режими. Нижчі +режими не заміщають вищих режимів, а трошки їх змінюють. Кожен нижчий +режим можна ввімкнути чи вимкнути окремо, незалежно від усіх інших +нижчих режимів — і незалежно від вашого вищого режиму. Тож ви можете +не використовувати нижчих режимів зовсім, або використовувати єдиний +нижчий режим, або поєднувати декілька нижчих режимів. + +Один із дуже корисних нижчих режимів, особливо для редагування тексту +мовами людського спілкування, — це режим Auto Fill (самозаповнення). +Коли цей режим увімкнено, Emacs автоматично вставляє символ нового +рядка між словами, коли при введенні тексту певний рядок виявляється +занадто широким. + +Режим самозаповнення вмикається командою M-x auto-fill-mode . +Коли режим увімкнено, можете вимкнути його знову тою ж командою. Якщо +режим вимкнено, команда його вмикає; а коли режим увімкнено, команда +його вимикає. Можна сказати, що команда «перемикає режим». + +»» Наберіть M-x auto-fill-mode . Тоді набирайте «йцук » знов + і знов, доки рядок не поділиться на два. Пробіли слід набирати, + оскільки самозаповнення розбиває рядки тільки на пробілах. + +Поле зазвичай починається після 70 символів, але можете змінити це +командою C-x f. Передайте бажане значення поля числовим аргументом +цій команді. + +»» Наберіть C-x f із аргументом 20. (C-u 2 0 C-x f). + Тоді наберіть будь-який текст і зверніть увагу, яким чином Emacs + поділить його на 20-символьні рядки. Тоді поверніть полю значення + 70 за допомогою ще одної команди C-x f. + +Якщо ви зміните щось посеред абзацу, режим самозаповнення не ділитиме +абзацу на рядки заново без вашого дозволу. +Щоб поділити абзац заново (замінюючи наявні символи нового рядка), +посуньте курсор до цього абзацу й наберіть M-q (META-q). + +»» Посуньте курсор до попереднього абзацу й наберіть M-q. + + +* ПОШУК +------- + +Emacs уміє шукати рядки (групи послідовних символів) в тексті як після +курсора, так і перед ним. Пошук рядка є командою руху курсора, тобто +посуває курсор до наступного місця, де з'являється цей рядок. + +Команда пошуку Emacs є покроковою. Тобто пошук відбувається прямо при +набранні рядка, який ви бажаєте шукати. + +Пошук уперед розпочинає команда C-s (search — пошук), а пошук назад — +команда C-r (reverse — навпаки). АЛЕ ЗАЧЕКАЙТЕ! Не поспішайте +випробовувати ці команди. + +Набравши C-s, ви помітите, що область відлуння покаже рядок +«I-search». Це означатиме, що Emacs перейшов до режиму incremental +search — покрокового пошуку — й очікує, поки ви наберете, що бажаєте +шукати. завершує пошук. + +»» Тепер наберіть C-s, щоб розпочати пошук. ПОВОЛІ, літера за + літерою, наберіть слово «курсор», зупиняючись після кожного символу + й звертаючи увагу на те, що відбувається з курсором. Отже, ви + щойно пошукали «курсор» один раз. +»» Наберіть C-s іще раз — знайдіть наступну послідовність «курсор». +»» Тепер наберіть чотири рази й зауважте, куди зсунеться курсор. +»» Наберіть , щоб завершити пошук. + +Щойно ви спостерігали, як покроковий пошук Emacs намагається перейти +до послідовності, збіжної з набраним вами рядком. Щоб перейти до +наступної послідовності «курсор», наберіть C-s іще раз. Якщо такої +послідовності не існує, Emacs сигналить і повідомляє, що пошук наразі +«failing» — неуспішний. C-g завершує пошук у будь-якому разі. + +Якщо під час покрокового пошуку набрати одразу після C-s — переходу до +наступного збігу з шуканим рядком — то поверне курсор до +попереднього збігу. Якщо збігів перед курсором нема, зітре +останній символ рядка пошуку. Наприклад, наберіть «к», щоб пошукати +перший збіг із «к». Тоді наберіть «у» — це посуне курсор до першого +збігу з «ку». Нарешті наберіть — це зітре «у» з рядка пошуку, +тож курсор повернеться до першого збігу з «к». + +Якщо посеред пошуку ви набираєте Control- чи Meta-символ (за винятком +символів власне пошуку, як-от C-s чи C-r), пошук припиняється. + +C-s розпочинає пошук будь-якого збігу з шуканим рядком ПІСЛЯ того +місця, де курсор зараз. Якщо бажаєте пошукати щось у більш ранньому +тексті, наберіть натомість C-r. Усе, що ми зазначили про C-s, +стосується й C-r, — крім напряму пошуку, який стає зворотним. + + +* ДЕКІЛЬКА ВІКОН +---------------- + +Emacs має ту файну властивість, що ви можете переглядати водночас +декілька вікон на одному екрані. (Зауважте, що Emacs використовує +роз'яснений у наступному розділі термін «рамка», або frame, замість +вжитого в деяких інших застосунках терміна «вікно».) Підручник Emacs +містить глосарій термінів Emacs. + +»» Посуньте курсор до цього рядка й наберіть C-l C-l. + +»» Наберіть C-x 2 — розділіть екран на два вікна. Обидва вікна + показуватимуть цей посібник. Курсор редагування залишатиметься в + горішньому вікні. + +»» Наберіть C-M-v — перегорніть нижнє вікно. + (Якщо не маєте клавіші META, наберіть + +»» Наберіть C-x o (other — інше), щоб посунути курсор до нижнього + вікна. Погортайте нижнє вікно за допомогою C-v та M-v. Читайте ці + вказівки далі в горішньому вікні. + +»» Наберіть C-x o ще раз, щоб посунути курсор назад до горішнього + вікна. Курсор у горішньому вікні опиниться там же, де був досі. + +Можете й надалі перемикатись між вікнами за допомогою C-x o. «Обране» +вікно, в якому переважно відбувається редагування, — це те вікно, в +якому ви бачите помітний курсор, який блимає, коли ви нічого не +набираєте. Кожне вікно має власну точку, на яку вказує його курсор; +якщо ви запускаєте Emacs у графічному середовищі, ці курсори не +блимають і мають вигляд порожніх коробок. + +Команда C-M-v дуже корисна, коли ви редагуєте текст в одному вікні й +використовуєте інше вікно лише як довідку. Не виходячи з обраного +вікна, ви можете гортати текст в іншому вікні за допомогою C-M-v. + +C-M-v — це один із CONTROL-META-символів. Якщо ви маєте клавішу META +(чи Alt), то можете набрати C-M-v, затиснувши водночас клавіші CONTROL +та META й натиснувши v. Неважливо, яку з клавіш CONTROL і META ви +затиснете першою, бо ці клавіші не діють самостійно, а змінюють +символи, які ви набираєте. + +Якщо у вас нема клавіші META, можете використати натомість , але +тоді порядок таки важливий: наберіть спершу , а тоді CONTROL-v. +CONTROL- v не спрацює, бо не змінює інші символи, а є +повноцінною клавішею. + +»» Наберіть C-x 1 (у горішньому вікні), щоб позбутись нижнього вікна. + +(Якби ви набрали C-x 1 у нижньому вікні, то позбулися б горішнього +вікна. Уявляйте цю команду як «Залишити лише одне вікно — те, в якому +я зараз».) + +Показувати один і той самий буфер в обох вікнах необов'язково. Якщо в +одному вікні ви наберете C-x C-f і знайдете файл, то на інше вікно це +не вплине. Можете знаходити файли в обох вікнах незалежно. + +Ось ще один шлях застосування двох вікон для показу двох різних речей: + +»» Наберіть C-x 4 C-f та назву одного зі своїх файлів. Завершіть за + допомогою . Зазначений файл з'явиться в нижньому вікні. + Курсор також туди посунеться. + +»» Наберіть C-x o, щоб перейти до горішнього вікна, + й C-x 1, щоб видалити нижнє вікно. + + +* ДЕКІЛЬКА РАМОК +---------------- + +Emacs також дає змогу створити декілька «рамок» (frames). Рамкою +називають будь-яку добірку вікон разом із її меню, панелями гортання, +областю відлуння тощо. У графічних середовищах Emacs називає рамкою +те, що багато інших застосунків називають «вікном». Екран може +показувати декілька графічних рамок водночас. На текстовому терміналі +може бути видно лише одну рамку. + +»» Наберіть C-x 5 2. + На вашому екрані з'явиться нова рамка. + +У новій рамці ви можете робити все те, що й у початковій рамці. +Початкова рамка не є чимось особливим. + +»» Наберіть C-x 5 0. + Це вилучить обрану рамку. + +Вилучити рамку можна й тим звичним шляхом, який передбачає графічне +середовище (зазвичай це кнопка «X» в одному з горішніх кутів рамки). +Якщо вилучити таким чином останню рамку сеансу Emacs, увесь Emacs буде +припинено. + + +* РІВНІ РЕКУРСІЇ РЕДАГУВАННЯ +---------------------------- + +Інколи ви потраплятимете в так званий «рівень рекурсії редагування». +Його позначають квадратні дужки в рядку режиму навколо круглих дужок +назви вищого режиму. Наприклад, ви можете бачити [(Fundamental)] +замість (Fundamental). + +Щоб вийти з рівня рекурсії редагування, наберіть . +Це всеохопна команда виходу. Можете використовувати її й для закриття +зайвих вікон чи виходу з мінібуфера. + +»» Наберіть M-x, щоб потрапити до мінібуфера. + Тоді наберіть , щоб із нього вийти. + +Вийти з рівня рекурсії редагування за допомогою C-g неможливо, бо C-g +використовується для скасування команд і аргументів УСЕРЕДИНІ рівня +рекурсії редагування. + + +* ОТРИМАТИ БІЛЬШЕ ДОВІДКИ +------------------------- + +Цей посібник намагається надати необхідний для початку роботи з Emacs +мінімум даних. Emacs уміє стільки всього, що одним посібником описати +всі його функції було б неможливо. Проте вам буде цікаво дізнатись +більше про Emacs та його корисні функції. Emacs надає команди для +читання документації про команди Emacs. Усі команди довідки (help) +починаються з CONTROL-h — символу довідки. + +Для отримання довідки наберіть символ C-h, а тоді той символ, довідку +якого бажаєте прочитати. Якщо ви СПРАВДІ загубились, C-h ? попрохає +Emacs перелічити розділи довідки. Якщо ви набрали C-h і передумали +читати довідку, натисніть C-g для скасування. + +(Якщо C-h не показує довідкового повідомлення внизу екрана, спробуйте +набрати клавішу F1 чи M-x help натомість.) + +Основна функція довідки — це C-h c. Наберіть C-h, символ c, а також +символ чи послідовність команди; тоді Emacs покаже коротенький +англійський опис цієї команди. + +»» Наберіть C-h c C-p. + +Має з'явитись повідомлення на кшталт: + + C-p runs the command previous-line + +Тобто «C-p виконує команду previous-line (попередній рядок)». Це +повідомляє вам назву функції. Оскільки назви функцій добираються +таким чином, щоб зображати дії, виконувані відповідною командою, +вони можуть слугувати коротенькою документацією — достатньою, щоб +нагадати вам команди, які ви вже опанували. + +Багатосимвольні команди, такі як C-x C-s чи v (замість M-v, якщо +не маєте клавіш META й ALT), також можна зазначати після C-h c. + +Щоб дізнатися більше про команду, зокрема про клавіші, які можна +набирати після неї, використайте C-h k (keys — клавіші) замість C-h c +(command — команда). + +»» Наберіть C-h k C-p. + +Це покаже у вікні Emacs документацію функції та її назву. Дочитавши +показане, наберіть C-x 1, щоб позбутись того вікна. Робити це одразу +необов'язково. Можете продовжити редагування, звіряючись із текстом +довідки, й набрати C-x 1 лише згодом. + +Ось кілька інших корисних варіантів C-h: + + C-h x Описати команду. Вам буде треба набрати назву команди. + +»» Спробуйте набрати C-h x previous-line . + Це покаже всі наявні в Emacs дані про ту функцію, + яка втілює команду C-p. + +Схожа команда C-h v показує документацію змінних — зокрема тих, +значення яких ви можете змінити для налаштування поведінки Emacs. +Наберіть назву змінної, коли Emacs її у вас запитає. + + C-h a (Apropos — пов'язане.) Наберіть ключове слово — й + Emacs покаже всі команди, назви яких містять це слово. + Всі ці команди можна викликати за допомогою META-x. + Для деяких команд Apropos наводить також символи чи + послідовності, які виконують цю ж команду. + +»» Наберіть C-h a file . + +Це покаже в ще одному вікні перелік усіх команд M-x, назви яких +містять «file» — файл. Поруч із назвами команд ви побачите відповідні +їм символи (як-от C-x C-f поруч із find-file — знайти файл). + +»» Наберіть C-M-v, щоб прогорнути вікно довідки. + Повторіть це декілька разів. + +»» Наберіть C-x 1, щоб видалити вікно довідки. + + C-h i (Info — дані.) Читати вкладені підручники. Ця команда + веде вас до особливого буфера *info*, в якому ви можете + читати підручники про встановлені у вашій системі пакунки. + Наберіть m emacs , щоб почитати підручник Emacs. + Якщо ви досі не користувались Info, наберіть h — і Emacs + запустить для вас путівник можливостями режиму Info. + Опрацювавши цей посібник, звертайтесь до Info-підручника + Emacs як до основної документації. + + +* БІЛЬШЕ ФУНКЦІЙ +---------------- + +Щоб дізнатись більше про Emacs, почитайте його підручник усередині +Emacs, скориставшись меню Help (Довідка) чи набравши C-h r. Дві +функції, які можуть вас особливо зацікавити, це Completion — +доповнення, яке заощаджує натиски клавіш; і Dired — редагування +каталогів, яке спрощує керування файлами. + +Доповнення дає змогу набирати менше тексту. Наприклад, щоб +перемкнутись на буфер *Messages*, можете набрати C-x b *M* — і +Emacs заповнить решту назви буфера настільки, наскільки зможе вивести +з уже набраного вами тексту. Доповнення також працює з назвами команд +і файлів. Підручник Emacs описує доповнення в розділі «Completion». + +Dired дає змогу перелічувати файли в каталозі (а на вимогу ще й у +підкаталогах), рухатися цим переліком, відкривати, перейменовувати й +видаляти файли тощо. Підручник Emacs описує керування файлами в +розділі «Dired». + +Підручник також описує безліч інших функцій Emacs. + + +* ВСТАНОВЛЕННЯ ПАКУНКІВ +----------------------- + +Спільнотою Emacs розроблено величезну добірку пакунків, які роблять +Emacs потужнішим. Ці пакунки містять підтримку нових мов, теми +оформлення, додатки для взаємодії з іншими застосунками — й ще +багато-багато всього. + +Щоб переглянути перелік усіх доступних пакунків, наберіть M-x +list-packages. З'явиться екран, за допомогою якого ви можете +встановлювати й видаляти пакунки, а також читати описи пакунків. +Підручник Emacs розповідає про керування пакунками докладніше. + + +* ОТОЖ +------ + +Щоб вийти з Emacs, наберіть C-x C-c. + +Посібник має на меті бути зрозумілим усім новим користувачкам і +користувачам, тож якщо будь-що роз'яснено нечітко чи помилково — +скаржтесь! Український переклад: Денис Никула . + + +* КОПІЮВАННЯ +------------ + +Цей посібник — нащадок цілого родоводу посібників Emacs, починаючи з +первісного посібника Emacs, який написав Стюарт Кракрафт. + +Ця версія посібника — складник GNU Emacs. Її захищено авторським +правом. Розповсюджувати копії дозволено за певних умов: + + Copyright (C) 1985, 1996, 1998, 2001-2022 Free Software Foundation, + Inc. (Фонд вільного програмного забезпечення, Inc.) + + Цей файл — складник GNU Emacs. + + GNU Emacs — вільне програмне забезпечення: можете розповсюджувати + й/або змінювати його згідно з умовами Загальної громадської ліцензії + GNU в тому вигляді, в якому її публікує Фонд вільного програмного + забезпечення, — версії 3 чи (на ваш розсуд) будь-якої новішої. + + GNU Emacs поширюється зі сподіванням, що він стане в нагоді, але БЕЗ + ЖОДНИХ ГАРАНТІЙ; без навіть уявної гарантії КОМЕРЦІЙНОЇ ПРИДАТНОСТІ + чи ВІДПОВІДНОСТІ БУДЬ-ЯКОМУ ПЕВНОМУ ЗАСТОСУВАННЮ. Докладніше про це + йдеться в Загальній громадській ліцензії GNU. + + Ви мали отримати копію Загальної громадської ліцензії GNU разом із + GNU Emacs. Якщо ні, перегляньте . + +Будь ласка, прочитайте файл COPYING і поширте після цього копії +GNU Emacs вашим подругам і друзям. Зупинімо гальмування розвитку +програмного забезпечення (так звану «власність» над ним), +використовуючи, пишучи й поширюючи вільні програми! diff --git a/lisp/language/cyrillic.el b/lisp/language/cyrillic.el index 4576373a6d..078c22746b 100644 --- a/lisp/language/cyrillic.el +++ b/lisp/language/cyrillic.el @@ -131,11 +131,13 @@ Support for Russian using koi8-r and the russian-computer input method.") :mime-charset 'koi8-u) (set-language-info-alist - "Ukrainian" '((charset koi8-u) + "Ukrainian" '((tutorial . "TUTORIAL.uk") + (charset koi8-u) (coding-system koi8-u) (coding-priority koi8-u) (nonascii-translation . koi8-u) (input-method . "ukrainian-computer") + (sample-text . "Ukrainian (Українська) Слава Україні!") (documentation . "Support for Ukrainian with KOI8-U character set.")) '("Cyrillic")) commit 3ed29eedfcdfd2c7bd4c8281ce7930822ef14a10 Author: Lars Ingebrigtsen Date: Tue Oct 4 14:12:22 2022 +0200 Fix NEWS item about obsoleting the `eq' gv diff --git a/etc/NEWS b/etc/NEWS index e0e2178d28..78fc431e82 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3065,8 +3065,8 @@ The following generalized variables have been made obsolete: 'buffer-name', 'buffer-string', 'buffer-substring', 'current-buffer', 'current-column', 'current-global-map', 'current-input-mode', 'current-local-map', 'current-window-configuration', -'default-file-modes', 'documentation-property', 'frame-height', -'frame-width', 'frame-visible-p', 'global-key-binding', `if' +'default-file-modes', 'documentation-property', `eq', 'frame-height', +'frame-width', 'frame-visible-p', 'global-key-binding', 'local-key-binding', 'mark', 'mark-marker', 'marker-position', 'mouse-position', 'point', 'point-marker', 'point-max', 'point-min', 'read-mouse-position', 'screen-height', 'screen-width', commit 79d9f3b845fc94726e242239574be21f5f49813c Author: Lars Ingebrigtsen Date: Tue Oct 4 14:11:04 2022 +0200 Make `eq' obsolete as a generalized variable * lisp/emacs-lisp/gv.el (eq): Make obsolete as a generalized variable. diff --git a/etc/NEWS b/etc/NEWS index 2b87641358..e0e2178d28 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3066,7 +3066,7 @@ The following generalized variables have been made obsolete: 'current-column', 'current-global-map', 'current-input-mode', 'current-local-map', 'current-window-configuration', 'default-file-modes', 'documentation-property', 'frame-height', -'frame-width', 'frame-visible-p', 'global-key-binding', +'frame-width', 'frame-visible-p', 'global-key-binding', `if' 'local-key-binding', 'mark', 'mark-marker', 'marker-position', 'mouse-position', 'point', 'point-marker', 'point-max', 'point-min', 'read-mouse-position', 'screen-height', 'screen-width', diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index ade8064114..a96fa19a3f 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -812,6 +812,7 @@ REF must have been previously obtained with `gv-ref'." `(cond (,v ,(funcall setter val)) ((eq ,getter ,val) ,(funcall setter `(not ,val)))))))))) +(make-obsolete-generalized-variable 'eq nil "29.1") (gv-define-expander substring (lambda (do place from &optional to) commit 25b97474ef00ee27fe5c1adf765e062ebd13454e Author: Lars Ingebrigtsen Date: Tue Oct 4 13:57:45 2022 +0200 Mention cond/if as generalized variables in the manual * doc/lispref/variables.texi (Setting Generalized Variables): Mention cond and if (bug#52290). diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index c70942cf35..1d891618da 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -2697,7 +2697,17 @@ a @result{} ("hello" "wood") @end example -@c FIXME? Also 'eq'? (see gv.el) +@item +The @code{if} and @code{cond} conditionals will work as generalized +variables. For instance, this will set either the @code{foo} or the +@code{bar} variable to @code{zot}: + +@example +(setf (if (zerop (random 2)) + foo + bar) + 'zot) +@end example @end itemize @noindent commit b560ce3560fc1559a08667798710cf37af0e079a Author: Eli Zaretskii Date: Tue Oct 4 14:23:20 2022 +0300 Avoid assertion violations in STRING_CHAR * src/xdisp.c (handle_composition_prop): * src/editfns.c (styled_format): Don't call 'STRING_CHAR' on unibyte strings. This avoids assertion violation in 'string_char_and_length'. (cherry picked from commit d52d6e1e106117eb4bba81a65e256e2e793037b6) diff --git a/src/editfns.c b/src/editfns.c index 790f66e3a0..203d3a4a57 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3468,7 +3468,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) || conversion == 'o' || conversion == 'x' || conversion == 'X')) error ("Invalid format operation %%%c", - STRING_CHAR ((unsigned char *) format - 1)); + multibyte_format + ? STRING_CHAR ((unsigned char *) format - 1) + : *((unsigned char *) format - 1)); else if (! (FIXNUMP (arg) || ((BIGNUMP (arg) || FLOATP (arg)) && conversion != 'c'))) error ("Format specifier doesn't match argument type"); diff --git a/src/xdisp.c b/src/xdisp.c index f5f3a811e9..0d0f77566b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -6034,7 +6034,10 @@ handle_composition_prop (struct it *it) pos_byte = IT_STRING_BYTEPOS (*it); string = it->string; s = SDATA (string) + pos_byte; - it->c = STRING_CHAR (s); + if (STRING_MULTIBYTE (string)) + it->c = STRING_CHAR (s); + else + it->c = *s; } else { commit d52d6e1e106117eb4bba81a65e256e2e793037b6 Author: Eli Zaretskii Date: Tue Oct 4 14:23:20 2022 +0300 Avoid assertion violations in STRING_CHAR * src/xdisp.c (handle_composition_prop): * src/editfns.c (styled_format): Don't call 'STRING_CHAR' on unibyte strings. This avoids assertion violation in 'string_char_and_length'. diff --git a/src/editfns.c b/src/editfns.c index b774e79337..c1414071c7 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3552,7 +3552,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) || conversion == 'o' || conversion == 'x' || conversion == 'X')) error ("Invalid format operation %%%c", - STRING_CHAR ((unsigned char *) format - 1)); + multibyte_format + ? STRING_CHAR ((unsigned char *) format - 1) + : *((unsigned char *) format - 1)); else if (! (FIXNUMP (arg) || ((BIGNUMP (arg) || FLOATP (arg)) && conversion != 'c'))) error ("Format specifier doesn't match argument type"); diff --git a/src/xdisp.c b/src/xdisp.c index 818cf5e3f8..9534e27843 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -6312,7 +6312,10 @@ handle_composition_prop (struct it *it) pos_byte = IT_STRING_BYTEPOS (*it); string = it->string; s = SDATA (string) + pos_byte; - it->c = STRING_CHAR (s); + if (STRING_MULTIBYTE (string)) + it->c = STRING_CHAR (s); + else + it->c = *s; } else { commit 9fb0aaa1ce4ed0050d2e13552f078a563c8a20ed Author: Lars Ingebrigtsen Date: Tue Oct 4 13:04:16 2022 +0200 Make loaddefs-generate more resilient * lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate): Don't bug out when there's an existing loaddefs file that's not formatted properly (bug#58280). diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index 095d6b14e6..964d23c770 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -632,7 +632,7 @@ instead of just updating them with the new/changed autoloads." ;; It's a new file; put the data at the end. (progn (goto-char (point-max)) - (search-backward "\f\n")) + (search-backward "\f\n" nil t)) ;; Delete the old version of the section. (delete-region (match-beginning 0) (and (search-forward "\n\f\n;;;") commit 535eec3bca36b84b104a4041f7bcdd5b1649a94b Author: Lars Ingebrigtsen Date: Tue Oct 4 12:49:49 2022 +0200 Don't bug out in advice--make-docstring when there's not doc string * lisp/emacs-lisp/nadvice.el (advice--make-docstring): Don't bug out on functions with no documentation (bug#58284). diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index b4acd423b8..429052bfdf 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el @@ -157,7 +157,8 @@ DOC is a string where \"FUNCTION\" and \"OLDFUN\" are expected.") (when before (insert before) (ensure-empty-lines 1)) - (insert origdoc) + (when origdoc + (insert origdoc)) (when after (ensure-empty-lines 1) (insert after)) commit 2b2d8ce41edee0ef8f27ccf5c7b5e4233b3f20bc Author: Eli Zaretskii Date: Tue Oct 4 12:57:04 2022 +0300 Avoid errors in interactive calls of 'calendar-goto-day-of-year' * lisp/calendar/cal-move.el (calendar-goto-day-of-year): Fix the default value of DAY; doc fix. (Bug#58283) diff --git a/lisp/calendar/cal-move.el b/lisp/calendar/cal-move.el index 4febad53fc..211e0f1e62 100644 --- a/lisp/calendar/cal-move.el +++ b/lisp/calendar/cal-move.el @@ -384,7 +384,8 @@ Moves forward if ARG is negative." ;;;###cal-autoload (defun calendar-goto-day-of-year (year day &optional noecho) "Move cursor to YEAR, DAY number; echo DAY/YEAR unless NOECHO is non-nil. -Negative DAY counts backward from end of year." +Negative DAY counts backward from end of year. +Interactively, prompt for YEAR and DAY number." (interactive (let* ((year (calendar-read-sexp "Year (>0)" @@ -394,7 +395,7 @@ Negative DAY counts backward from end of year." (day (calendar-read-sexp "Day number (+/- 1-%d)" (lambda (x) (and (<= 1 (abs x)) (<= (abs x) last))) - nil + (calendar-day-number (calendar-current-date)) last))) (list year day))) (calendar-goto-date commit 78c262e1c2cf93d3101cb942926d170a816a8d3f Author: Eli Zaretskii Date: Tue Oct 4 10:32:06 2022 +0300 ; * lisp/progmodes/glasses.el (glasses-face): Expand the doc string. diff --git a/lisp/progmodes/glasses.el b/lisp/progmodes/glasses.el index f760ccf368..87bb7318d0 100644 --- a/lisp/progmodes/glasses.el +++ b/lisp/progmodes/glasses.el @@ -84,12 +84,22 @@ performed." (defcustom glasses-face nil - "Face to be put on capitals of an identifier looked through glasses. -If it is nil, no face is placed at the capitalized letter. + "Face to use for capital letters of identifiers where separators were added. +If it is nil, the capital letters will display with their usual faces. For example, you can set `glasses-separator' to an empty string and `glasses-face' to `bold'. Then unreadable identifiers will have no separators, -but will have their capitals in bold." +but will have their capitals in bold. + +As another example, you may wish to have a clear visual indication of +where the `glasses-separator' string was inserted by `glasses-mode', +as opposed to where they are part of the original identifiers. This +can be useful when the program source code uses mixed CamelCase and +normal_readable identifiers, and you want to know which underscores +were added by this mode. Customizing this face to something like `bold' +will show the capital letters following the inserted `glasses-separator' +in a distinct face. Note that you must use `customize-variable' for +changing the face; just assigning the value has no effect." :type '(choice (const :tag "None" nil) face) :set 'glasses-custom-set :initialize 'custom-initialize-default)