* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' @ 2018-02-27 9:22 Michael Heerdegen 2018-02-27 11:21 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-02-27 9:22 UTC (permalink / raw) To: 30626 Hello, Traversing a `stream-of-directory-files' over a huge directory hierarchy crashes my Emacs. Here is a recipe: I have a file "/home/micha/Treasure/today/stream-crash.el" with these contents: #+begin_src emacs-lisp ;; -*- lexical-binding: t -*- (require 'stream) (seq-doseq (_file (stream-of-directory-files "/home/micha" t nil t nil (lambda (file) (and (file-readable-p file) (file-regular-p file))))) nil) #+end_src Then I micha> emacs -Q -L /home/micha/software/elpa/packages/stream\ -l /home/micha/Treasure/today/stream-crash.el and I get a segfault after ~ 1 minute. This kind of crash only seems to occur when the traversed directory is sufficiently large. Thanks in advance, Michael. In GNU Emacs 26.0.91 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.28) of 2018-02-26 built on drachen Repository revision: ea8f9fd7be138708a52aad418d09d5d4ca6b2a7e Windowing system distributor 'The X.Org Foundation', version 11.0.11906000 System Description: Debian GNU/Linux testing (buster) ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 9:22 bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' Michael Heerdegen @ 2018-02-27 11:21 ` Eli Zaretskii 2018-02-27 11:39 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-02-27 11:21 UTC (permalink / raw) To: 30626, michael_heerdegen On February 27, 2018 11:22:26 AM GMT+02:00, Michael Heerdegen <michael_heerdegen@web.de> wrote: > > Hello, > > Traversing a `stream-of-directory-files' over a huge directory > hierarchy > crashes my Emacs. > > Here is a recipe: I have a file > "/home/micha/Treasure/today/stream-crash.el" with these contents: > > #+begin_src emacs-lisp > ;; -*- lexical-binding: t -*- > > (require 'stream) > > (seq-doseq (_file (stream-of-directory-files > "/home/micha" t nil t nil > (lambda (file) (and (file-readable-p file) (file-regular-p file))))) > nil) > #+end_src > > Then I > > micha> emacs -Q -L /home/micha/software/elpa/packages/stream\ > -l /home/micha/Treasure/today/stream-crash.el > > and I get a segfault after ~ 1 minute. > > This kind of crash only seems to occur when the traversed directory is > sufficiently large. I guess it's a stack overflow: that function recurses into subdirectories. To avoid such problems, the function should be rewritten to work by BFS, not DFS. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 11:21 ` Eli Zaretskii @ 2018-02-27 11:39 ` Michael Heerdegen 2018-02-27 12:08 ` Michael Heerdegen 2018-02-27 18:00 ` bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' Eli Zaretskii 0 siblings, 2 replies; 253+ messages in thread From: Michael Heerdegen @ 2018-02-27 11:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 30626 Eli Zaretskii <eliz@gnu.org> writes: > I guess it's a stack overflow: that function recurses into > subdirectories. > > To avoid such problems, the function should be rewritten to work by > BFS, not DFS. Here is the backtrace I'm now able to produce. Looks like the crash happens in gc: | [lots of more lines like these cut] | #104019 0x00000000005e0526 in mark_object (arg=XIL(0x5a15413)) at alloc.c:6624 | #104020 0x00000000005dfab5 in mark_vectorlike (ptr=0x5a584e0) at alloc.c:6227 | #104021 0x00000000005e0526 in mark_object (arg=XIL(0x5bd7cf3)) at alloc.c:6624 | #104022 0x00000000005dfab5 in mark_vectorlike (ptr=0x5873a80) at alloc.c:6227 | #104023 0x00000000005e0526 in mark_object (arg=XIL(0x5bd7cb3)) at alloc.c:6624 | #104024 0x00000000006070ea in mark_specpdl (first=0x58a1348, ptr=0x58a1b90) at eval.c:3868 | #104025 0x00000000006856b2 in mark_one_thread (thread=0xcd5340 <main_thread>) at thread.c:614 | #104026 0x00000000006857c7 in mark_threads_callback (ignore=0x0) at thread.c:649 | #104027 0x00000000005dda03 in flush_stack_call_func (func=0x685781 <mark_threads_callback>, arg=0x0) at alloc.c:5220 | #104028 0x00000000006857f5 in mark_threads () at thread.c:656 | #104029 0x00000000005df2d2 in garbage_collect_1 (end=0x7fffffff63f0) at alloc.c:5997 | #104030 0x00000000005df929 in Fgarbage_collect () at alloc.c:6168 | #104031 0x000000000055746c in maybe_gc () at lisp.h:4749 | #104032 0x00000000006047cb in Ffuncall (nargs=4, args=0x7fffffff64d0) at eval.c:2751 | #104033 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f83c4), vector=XIL(0x3255bb5), maxdepth=make_number(13), args_template=make_number(128), nargs=2, args=0x7fffffff6b38) at bytecode.c:629 | #104034 0x000000000060529c in funcall_lambda (fun=XIL(0x3255c15), nargs=2, arg_vector=0x7fffffff6b38) at eval.c:2970 | #104035 0x00000000006048d4 in Ffuncall (nargs=3, args=0x7fffffff6b30) at eval.c:2771 | #104036 0x000000000060395b in Fapply (nargs=3, args=0x7fffffff6b30) at eval.c:2346 | #104037 0x0000000000604b87 in funcall_subr (subr=0xc3d7c0 <Sapply>, numargs=3, args=0x7fffffff6b30) at eval.c:2824 | #104038 0x0000000000604890 in Ffuncall (nargs=4, args=0x7fffffff6b28) at eval.c:2769 | #104039 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f83e4), vector=XIL(0x15372775), maxdepth=make_number(8), args_template=make_number(256), nargs=0, args=0x7fffffff6ff8) at bytecode.c:629 | #104040 0x000000000060529c in funcall_lambda (fun=XIL(0x153727c5), nargs=0, arg_vector=0x7fffffff6ff8) at eval.c:2970 | #104041 0x00000000006048d4 in Ffuncall (nargs=1, args=0x7fffffff6ff0) at eval.c:2771 | #104042 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42b7ad4), vector=XIL(0x930825), maxdepth=make_number(2), args_template=make_number(257), nargs=1, args=0x7fffffff7460) at bytecode.c:629 | #104043 0x000000000060529c in funcall_lambda (fun=XIL(0x3b73d75), nargs=1, arg_vector=0x7fffffff7458) at eval.c:2970 | #104044 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffff7450) at eval.c:2771 | #104045 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f82f4), vector=XIL(0x3255aa5), maxdepth=make_number(3), args_template=make_number(257), nargs=1, args=0x7fffffff78e0) at bytecode.c:629 | #104046 0x000000000060529c in funcall_lambda (fun=XIL(0x3255ab5), nargs=1, arg_vector=0x7fffffff78d8) at eval.c:2970 | #104047 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffff78d0) at eval.c:2771 | #104048 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f83e4), vector=XIL(0x153727f5), maxdepth=make_number(8), args_template=make_number(256), nargs=0, args=0x7fffffff7da8) at bytecode.c:629 | #104049 0x000000000060529c in funcall_lambda (fun=XIL(0x15372845), nargs=0, arg_vector=0x7fffffff7da8) at eval.c:2970 | #104050 0x00000000006048d4 in Ffuncall (nargs=1, args=0x7fffffff7da0) at eval.c:2771 | #104051 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42b7ad4), vector=XIL(0x930825), maxdepth=make_number(2), args_template=make_number(257), nargs=1, args=0x7fffffff8210) at bytecode.c:629 | #104052 0x000000000060529c in funcall_lambda (fun=XIL(0x3b73d75), nargs=1, arg_vector=0x7fffffff8208) at eval.c:2970 | #104053 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffff8200) at eval.c:2771 | #104054 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f82f4), vector=XIL(0x3255aa5), maxdepth=make_number(3), args_template=make_number(257), nargs=1, args=0x7fffffff8690) at bytecode.c:629 | #104055 0x000000000060529c in funcall_lambda (fun=XIL(0x3255ab5), nargs=1, arg_vector=0x7fffffff8688) at eval.c:2970 | #104056 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffff8680) at eval.c:2771 | #104057 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f83e4), vector=XIL(0x15372875), maxdepth=make_number(8), args_template=make_number(256), nargs=0, args=0x7fffffff8b58) at bytecode.c:629 | #104058 0x000000000060529c in funcall_lambda (fun=XIL(0x153728c5), nargs=0, arg_vector=0x7fffffff8b58) at eval.c:2970 | #104059 0x00000000006048d4 in Ffuncall (nargs=1, args=0x7fffffff8b50) at eval.c:2771 | #104060 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42b7ad4), vector=XIL(0x930825), maxdepth=make_number(2), args_template=make_number(257), nargs=1, args=0x7fffffff8fc0) at bytecode.c:629 | #104061 0x000000000060529c in funcall_lambda (fun=XIL(0x3b73d75), nargs=1, arg_vector=0x7fffffff8fb8) at eval.c:2970 | #104062 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffff8fb0) at eval.c:2771 | #104063 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f82f4), vector=XIL(0x3255aa5), maxdepth=make_number(3), args_template=make_number(257), nargs=1, args=0x7fffffff9440) at bytecode.c:629 | #104064 0x000000000060529c in funcall_lambda (fun=XIL(0x3255ab5), nargs=1, arg_vector=0x7fffffff9438) at eval.c:2970 | #104065 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffff9430) at eval.c:2771 | #104066 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f83e4), vector=XIL(0x153728f5), maxdepth=make_number(8), args_template=make_number(256), nargs=0, args=0x7fffffff9908) at bytecode.c:629 | #104067 0x000000000060529c in funcall_lambda (fun=XIL(0x15372945), nargs=0, arg_vector=0x7fffffff9908) at eval.c:2970 | #104068 0x00000000006048d4 in Ffuncall (nargs=1, args=0x7fffffff9900) at eval.c:2771 | #104069 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42b7ad4), vector=XIL(0x930825), maxdepth=make_number(2), args_template=make_number(257), nargs=1, args=0x7fffffff9d70) at bytecode.c:629 | #104070 0x000000000060529c in funcall_lambda (fun=XIL(0x3b73d75), nargs=1, arg_vector=0x7fffffff9d68) at eval.c:2970 | #104071 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffff9d60) at eval.c:2771 | #104072 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f82f4), vector=XIL(0x3255aa5), maxdepth=make_number(3), args_template=make_number(257), nargs=1, args=0x7fffffffa1e8) at bytecode.c:629 | #104073 0x000000000060529c in funcall_lambda (fun=XIL(0x3255ab5), nargs=1, arg_vector=0x7fffffffa1e0) at eval.c:2970 | #104074 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffffa1d8) at eval.c:2771 | #104075 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f8c64), vector=XIL(0x153729a5), maxdepth=make_number(7), args_template=make_number(256), nargs=0, args=0x7fffffffa6a8) at bytecode.c:629 | #104076 0x000000000060529c in funcall_lambda (fun=XIL(0x153729f5), nargs=0, arg_vector=0x7fffffffa6a8) at eval.c:2970 | #104077 0x00000000006048d4 in Ffuncall (nargs=1, args=0x7fffffffa6a0) at eval.c:2771 | #104078 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42b7ad4), vector=XIL(0x930825), maxdepth=make_number(2), args_template=make_number(257), nargs=1, args=0x7fffffffab10) at bytecode.c:629 | #104079 0x000000000060529c in funcall_lambda (fun=XIL(0x3b73d75), nargs=1, arg_vector=0x7fffffffab08) at eval.c:2970 | #104080 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffffab00) at eval.c:2771 | #104081 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f82f4), vector=XIL(0x3255aa5), maxdepth=make_number(3), args_template=make_number(257), nargs=1, args=0x7fffffffaf88) at bytecode.c:629 | #104082 0x000000000060529c in funcall_lambda (fun=XIL(0x3255ab5), nargs=1, arg_vector=0x7fffffffaf80) at eval.c:2970 | #104083 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffffaf78) at eval.c:2771 | #104084 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42f8c04), vector=XIL(0x331ede5), maxdepth=make_number(5), args_template=make_number(514), nargs=2, args=0x7fffffffb5d0) at bytecode.c:629 | #104085 0x000000000060529c in funcall_lambda (fun=XIL(0x331ee05), nargs=2, arg_vector=0x7fffffffb5c0) at eval.c:2970 | #104086 0x00000000006048d4 in Ffuncall (nargs=3, args=0x7fffffffb5b8) at eval.c:2771 | #104087 0x000000000060390d in Fapply (nargs=4, args=0x7fffffffb5b8) at eval.c:2342 | #104088 0x0000000000604b87 in funcall_subr (subr=0xc3d7c0 <Sapply>, numargs=4, args=0x7fffffffb5b8) at eval.c:2824 | #104089 0x0000000000604890 in Ffuncall (nargs=5, args=0x7fffffffb5b0) at eval.c:2769 | #104090 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x42fb574), vector=XIL(0x425f285), maxdepth=make_number(15), args_template=make_number(642), nargs=2, args=0x7fffffffba40) at bytecode.c:629 | #104091 0x000000000060529c in funcall_lambda (fun=XIL(0x425f305), nargs=2, arg_vector=0x7fffffffba30) at eval.c:2970 | #104092 0x000000000060500d in apply_lambda (fun=XIL(0x425f305), args=XIL(0x5bd89c3), count=30) at eval.c:2906 | #104093 0x0000000000603602 in eval_sub (form=XIL(0x5bd89d3)) at eval.c:2279 | #104094 0x0000000000632c69 in readevalloop_eager_expand_eval (val=XIL(0x5bd8a73), macroexpand=XIL(0xda5d0)) at lread.c:1850 | #104095 0x00000000006335f0 in readevalloop (readcharfun=XIL(0x5b75ce5), infile0=0x0, sourcename=XIL(0x55c2e14), printflag=false, unibyte=XIL(0), readfun=XIL(0), start=XIL(0), end=XIL(0)) at lread.c:2036 | #104096 0x0000000000633a0a in Feval_buffer (buffer=XIL(0), printflag=XIL(0), filename=XIL(0x56ea3c4), unibyte=XIL(0), do_allow_print=XIL(0)) at lread.c:2103 | #104097 0x0000000000604d25 in funcall_subr (subr=0xc40240 <Seval_buffer>, numargs=0, args=0x7fffffffbfa0) at eval.c:2856 | #104098 0x0000000000604890 in Ffuncall (nargs=1, args=0x7fffffffbf98) at eval.c:2769 | #104099 0x00000000005fc8f7 in Ffuncall_interactively (nargs=1, args=0x7fffffffbf98) at callint.c:252 | #104100 0x0000000000604b87 in funcall_subr (subr=0xc3cfc0 <Sfuncall_interactively>, numargs=1, args=0x7fffffffbf98) at eval.c:2824 | #104101 0x0000000000604890 in Ffuncall (nargs=2, args=0x7fffffffbf90) at eval.c:2769 | #104102 0x00000000005fec50 in Fcall_interactively (function=XIL(0xad320), record_flag=XIL(0xaad0), keys=XIL(0x5a55745)) at callint.c:854 | #104103 0x0000000000604cac in funcall_subr (subr=0xc3d000 <Scall_interactively>, numargs=3, args=0x7fffffffc300) at eval.c:2849 | #104104 0x0000000000604890 in Ffuncall (nargs=4, args=0x7fffffffc2f8) at eval.c:2769 | #104105 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x9f4bec), vector=XIL(0x9f4c0d), maxdepth=make_number(13), args_template=make_number(1025), nargs=2, args=0x7fffffffc868) at bytecode.c:629 | #104106 0x000000000060529c in funcall_lambda (fun=XIL(0x9f4bbd), nargs=2, arg_vector=0x7fffffffc858) at eval.c:2970 | #104107 0x00000000006048d4 in Ffuncall (nargs=3, args=0x7fffffffc850) at eval.c:2771 | #104108 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x9f489c), vector=XIL(0x9f48bd), maxdepth=make_number(15), args_template=make_number(769), nargs=3, args=0x7fffffffce00) at bytecode.c:629 | #104109 0x000000000060529c in funcall_lambda (fun=XIL(0x9f485d), nargs=3, arg_vector=0x7fffffffcde8) at eval.c:2970 | #104110 0x00000000006048d4 in Ffuncall (nargs=4, args=0x7fffffffcde0) at eval.c:2771 | #104111 0x0000000000603cdb in Fapply (nargs=2, args=0x7fffffffcfc0) at eval.c:2389 | #104112 0x0000000000604b87 in funcall_subr (subr=0xc3d7c0 <Sapply>, numargs=2, args=0x7fffffffcfc0) at eval.c:2824 | #104113 0x0000000000604890 in Ffuncall (nargs=3, args=0x7fffffffcfb8) at eval.c:2769 | #104114 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x505da94), vector=XIL(0x5044095), maxdepth=make_number(3), args_template=XIL(0), nargs=0, args=0x0) at bytecode.c:629 | #104115 0x0000000000605615 in funcall_lambda (fun=XIL(0x50c3185), nargs=5, arg_vector=0x5044095) at eval.c:3052 | #104116 0x00000000006048d4 in Ffuncall (nargs=6, args=0x7fffffffd450) at eval.c:2771 | #104117 0x0000000000603cdb in Fapply (nargs=3, args=0x7fffffffd648) at eval.c:2389 | #104118 0x0000000000604b87 in funcall_subr (subr=0xc3d7c0 <Sapply>, numargs=3, args=0x7fffffffd648) at eval.c:2824 | #104119 0x0000000000604890 in Ffuncall (nargs=4, args=0x7fffffffd640) at eval.c:2769 | #104120 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x14402c4), vector=XIL(0x50441c5), maxdepth=make_number(5), args_template=make_number(128), nargs=4, args=0x7fffffffdbf0) at bytecode.c:629 | #104121 0x000000000060529c in funcall_lambda (fun=XIL(0x50441f5), nargs=4, arg_vector=0x7fffffffdbf0) at eval.c:2970 | #104122 0x00000000006048d4 in Ffuncall (nargs=5, args=0x7fffffffdbe8) at eval.c:2771 | #104123 0x00000000005fc8f7 in Ffuncall_interactively (nargs=5, args=0x7fffffffdbe8) at callint.c:252 | #104124 0x0000000000604b87 in funcall_subr (subr=0xc3cfc0 <Sfuncall_interactively>, numargs=5, args=0x7fffffffdbe8) at eval.c:2824 | #104125 0x0000000000604890 in Ffuncall (nargs=6, args=0x7fffffffdbe0) at eval.c:2769 | #104126 0x0000000000603cdb in Fapply (nargs=3, args=0x7fffffffdd90) at eval.c:2389 | #104127 0x00000000005fcd7d in Fcall_interactively (function=XIL(0xda3c0), record_flag=XIL(0), keys=XIL(0x5a3e0a5)) at callint.c:389 | #104128 0x0000000000604cac in funcall_subr (subr=0xc3d000 <Scall_interactively>, numargs=3, args=0x7fffffffdfe0) at eval.c:2849 | #104129 0x0000000000604890 in Ffuncall (nargs=4, args=0x7fffffffdfd8) at eval.c:2769 | #104130 0x000000000064cc41 in exec_byte_code (bytestr=XIL(0x9f4bec), vector=XIL(0x9f4c0d), maxdepth=make_number(13), args_template=make_number(1025), nargs=1, args=0x7fffffffe520) at bytecode.c:629 | #104131 0x000000000060529c in funcall_lambda (fun=XIL(0x9f4bbd), nargs=1, arg_vector=0x7fffffffe518) at eval.c:2970 | #104132 0x00000000006048d4 in Ffuncall (nargs=2, args=0x7fffffffe510) at eval.c:2771 | #104133 0x00000000006042a0 in call1 (fn=XIL(0x3f00), arg1=XIL(0xda3c0)) at eval.c:2620 | #104134 0x000000000055ec02 in command_loop_1 () at keyboard.c:1482 | #104135 0x00000000006013b2 in internal_condition_case (bfun=0x55e45e <command_loop_1>, handlers=XIL(0x5250), hfun=0x55dc1d <cmd_error>) at eval.c:1332 | #104136 0x000000000055e151 in command_loop_2 (ignore=XIL(0)) at keyboard.c:1110 | #104137 0x0000000000600c94 in internal_catch (tag=XIL(0xc6f0), func=0x55e124 <command_loop_2>, arg=XIL(0)) at eval.c:1097 | #104138 0x000000000055e0ef in command_loop () at keyboard.c:1089 | #104139 0x000000000055d7ef in recursive_edit_1 () at keyboard.c:695 | #104140 0x000000000055d970 in Frecursive_edit () at keyboard.c:766 | #104141 0x000000000055b5f0 in main (argc=1, argv=0x7fffffffe9f8) at emacs.c:1713 | Cannot access memory at address 0x7fffff66ff4f Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 11:39 ` Michael Heerdegen @ 2018-02-27 12:08 ` Michael Heerdegen 2018-02-27 18:08 ` Eli Zaretskii 2018-02-27 18:00 ` bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-02-27 12:08 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 30626 Michael Heerdegen <michael_heerdegen@web.de> writes: > Here is the backtrace I'm now able to produce. Looks like the crash > happens in gc. Here is a much simpler example that crashes as well: #+begin_src emacs-lisp (seq-doseq (_ (stream-range 1 1000000)) nil) #+end_src Note that this is executed as a loop due how to streams are implemented, although the definition of `seq-doseq' looks recursive. But it seems that gc has a problem with the large number of conses created when processing that. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 12:08 ` Michael Heerdegen @ 2018-02-27 18:08 ` Eli Zaretskii 2018-02-28 1:29 ` Noam Postavsky ` (3 more replies) 0 siblings, 4 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-02-27 18:08 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30626 > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: bug-gnu-emacs@gnu.org, 30626@debbugs.gnu.org > Date: Tue, 27 Feb 2018 13:08:59 +0100 > > #+begin_src emacs-lisp > (seq-doseq (_ (stream-range 1 1000000)) nil) > #+end_src > > Note that this is executed as a loop due how to streams are implemented, > although the definition of `seq-doseq' looks recursive. But it seems > that gc has a problem with the large number of conses created when > processing that. What can we do instead in such cases? Stack-overflow protection cannot work in GC, so you are shooting yourself in the foot by creating such large recursive structures. By the time we get to GC, where the problem will happen, it's too late, because the memory was already allocated. Does anyone has a reasonable idea for avoiding the crash in such programs? ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 18:08 ` Eli Zaretskii @ 2018-02-28 1:29 ` Noam Postavsky 2018-02-28 10:58 ` Michael Heerdegen 2018-02-28 11:05 ` Michael Heerdegen ` (2 subsequent siblings) 3 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-02-28 1:29 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, 30626 Eli Zaretskii <eliz@gnu.org> writes: >> From: Michael Heerdegen <michael_heerdegen@web.de> >> Cc: bug-gnu-emacs@gnu.org, 30626@debbugs.gnu.org >> Date: Tue, 27 Feb 2018 13:08:59 +0100 >> >> #+begin_src emacs-lisp >> (seq-doseq (_ (stream-range 1 1000000)) nil) >> #+end_src >> >> Note that this is executed as a loop due how to streams are implemented, >> although the definition of `seq-doseq' looks recursive. Doesn't look recursive to me, it expands to a call to seq-do, which uses a simple loop. >> But it seems that gc has a problem with the large number of conses >> created when processing that. > > What can we do instead in such cases? Stack-overflow protection > cannot work in GC, so you are shooting yourself in the foot by > creating such large recursive structures. By the time we get to GC, > where the problem will happen, it's too late, because the memory was > already allocated. > > Does anyone has a reasonable idea for avoiding the crash in such > programs? I don't have a quick answer for the general case, but I think it's a bug in stream.el that it's creating such large structures in the first place. As far as I understand it, the point of streams is to handle long lists by encoding them as (FIRST-VALUE . FUNCTION-TO-PRODUCE-REST-OF-LIST) so as to avoid allocating large amounts of memory. Is there an easy way to find out what the large structures are, and where they are coming from? ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 1:29 ` Noam Postavsky @ 2018-02-28 10:58 ` Michael Heerdegen 2018-02-28 16:00 ` Eli Zaretskii 2019-04-25 3:20 ` Noam Postavsky 0 siblings, 2 replies; 253+ messages in thread From: Michael Heerdegen @ 2018-02-28 10:58 UTC (permalink / raw) To: Noam Postavsky; +Cc: 30626 Noam Postavsky <npostavs@gmail.com> writes: > >> #+begin_src emacs-lisp > >> (seq-doseq (_ (stream-range 1 1000000)) nil) > >> #+end_src > >> > >> Note that this is executed as a loop due how to streams are > >> implemented, although the definition of `seq-doseq' looks > >> recursive. > > Doesn't look recursive to me, it expands to a call to seq-do, which uses > a simple loop. I was imprecise, I meant that the streams are defined recursively (most of the time). Though, it's a delayed type of recursion. Anyway, I think that this doesn't matter here. > > Does anyone has a reasonable idea for avoiding the crash in such > > programs? > > I don't have a quick answer for the general case, but I think it's a bug > in stream.el that it's creating such large structures in the first > place. As far as I understand it, the point of streams is to handle > long lists by encoding them as > > (FIRST-VALUE . FUNCTION-TO-PRODUCE-REST-OF-LIST) Yes, that's exactly how it's implemented. When requesting more elements from the stream, that becomes (FIRST-VALUE . (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST)) When we loop over the string, the cons whose car is the FIRST-VALUE, let's call it cons1, is immediately thrown away, and we continue with (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST) etc. AFAIU the problem is that the cons1 still exists in memory until garbage collection kicks in. When that happens, the cons1 points to a largely recursive cons structure, though this structure is never referenced from Lisp in this form. > so as to avoid allocating large amounts of memory. Is there an easy way > to find out what the large structures are, and where they are coming > from? I think I've answered that. At least, I think so. What I don't understand is that when I force the `seq-doseq' to call `garbace-collect' explicitly every 1000 cycles, or so, it doesn't help: the crash still happens after generating ~ 70 000 elements, or some more, but I can't avoid the crash, no matter how often I call gc. So I'm not sure whether these long lists are the problem or something else. The FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST looks harmless when I print it, even after thousands of iterations, so I would not understand why that could be problematic. streams.el implements things in a way that these rest functions are not deeply nested lambdas. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 10:58 ` Michael Heerdegen @ 2018-02-28 16:00 ` Eli Zaretskii 2018-02-28 16:20 ` Michael Heerdegen 2019-04-25 3:20 ` Noam Postavsky 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-02-28 16:00 UTC (permalink / raw) To: Michael Heerdegen; +Cc: npostavs, 30626 > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Eli Zaretskii <eliz@gnu.org>, 30626@debbugs.gnu.org > Date: Wed, 28 Feb 2018 11:58:49 +0100 > > > (FIRST-VALUE . FUNCTION-TO-PRODUCE-REST-OF-LIST) > > Yes, that's exactly how it's implemented. When requesting more elements > from the stream, that becomes > > (FIRST-VALUE . > (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST)) > > When we loop over the string, the cons whose car is the FIRST-VALUE, > let's call it cons1, is immediately thrown away, and we continue with > > (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST) > > etc. How do you see that the car is immediately thrown away? > AFAIU the problem is that the cons1 still exists in memory until garbage > collection kicks in. When that happens, the cons1 points to a largely > recursive cons structure, though this structure is never referenced from > Lisp in this form. What is "cons1" in this context? ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 16:00 ` Eli Zaretskii @ 2018-02-28 16:20 ` Michael Heerdegen 2018-02-28 17:22 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-02-28 16:20 UTC (permalink / raw) To: Eli Zaretskii; +Cc: npostavs, 30626 Eli Zaretskii <eliz@gnu.org> writes: > How do you see that the car is immediately thrown away? After expansion and dispatch, this is what gets executed: #+begin_src emacs-lisp (let ((stream (stream-range 1 1000000))) (while (not (stream-empty-p stream)) (funcall #'ignore (stream-first stream)) (setq stream (stream-rest stream)))) #+end_src Creating an element and throwing away the outermost cons alternate. > > AFAIU the problem is that the cons1 still exists in memory until > > garbage collection kicks in. When that happens, the cons1 points to > > a largely recursive cons structure, though this structure is never > > referenced from Lisp in this form. > What is "cons1" in this context? I said it some lines above: I defined it as name of the "first cons", i.e. the original stream. The return value of `stream-range' in the above example. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 16:20 ` Michael Heerdegen @ 2018-02-28 17:22 ` Eli Zaretskii 2018-02-28 18:25 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-02-28 17:22 UTC (permalink / raw) To: Michael Heerdegen; +Cc: npostavs, 30626 > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: npostavs@gmail.com, 30626@debbugs.gnu.org > Date: Wed, 28 Feb 2018 17:20:53 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > > How do you see that the car is immediately thrown away? > > After expansion and dispatch, this is what gets executed: > > #+begin_src emacs-lisp > (let ((stream (stream-range 1 1000000))) > (while (not (stream-empty-p stream)) > (funcall #'ignore (stream-first stream)) > (setq stream (stream-rest stream)))) > #+end_src > > Creating an element and throwing away the outermost cons alternate. I don't think it's thrown away from the POV of GC. But you can easily see what is going on if you trace the GC on the C level. You should be able to see which object causes recursion in mark_object. I didn't look long enough, but what I did see looks very much like the entire unwound stream. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 17:22 ` Eli Zaretskii @ 2018-02-28 18:25 ` Michael Heerdegen 2018-03-01 11:25 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-02-28 18:25 UTC (permalink / raw) To: Eli Zaretskii; +Cc: npostavs, 30626 Eli Zaretskii <eliz@gnu.org> writes: > I don't think it's thrown away from the POV of GC. But you can easily > see what is going on if you trace the GC on the C level. You should > be able to see which object causes recursion in mark_object. I didn't > look long enough, but what I did see looks very much like the entire > unwound stream. I have an idea what could be going on. In the stream-range example, this is how the stream is build: #+begin_src emacs-lisp (list stream--identifier (let (forced val) (lambda (&optional check) (if check forced (unless forced (setf val (progn (cons start (stream-range (+ start step) end step)))) (setf forced t)) val)))) #+end_src The inner `stream-range' call results in a closure, and I guess that this closure includes a reference to the outside VAL, which is the stream from one step back (though there isn't a lexical reference to the variable...does that make sense?) So there could be a chain of references via closure variables back to the first cons. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 18:25 ` Michael Heerdegen @ 2018-03-01 11:25 ` Michael Heerdegen 2018-03-01 15:00 ` Eli Zaretskii 2018-03-02 14:11 ` Noam Postavsky 0 siblings, 2 replies; 253+ messages in thread From: Michael Heerdegen @ 2018-03-01 11:25 UTC (permalink / raw) To: Eli Zaretskii; +Cc: npostavs, 30626 Michael Heerdegen <michael_heerdegen@web.de> writes: > The inner `stream-range' call results in a closure, and I guess that > this closure includes a reference to the outside VAL, which is the > stream from one step back (though there isn't a lexical reference to the > variable...does that make sense?) This is probably only a part of the puzzle. Some examples: test1.el: This is more or less the `stream-range' example reimplemented without dependencies so that it works in emacs -Q: #+begin_src emacs-lisp ;; -*- lexical-binding: t -*- (defun my-range (start) (let (forced val) (lambda () (unless forced (setq val (cons start (my-range (1+ start))) forced t)) val))) (defun my-test () (let ((range-object (my-range 1)) current-cons) (while (< (car (setq current-cons (funcall range-object))) (* 1000 1000)) (message "%d" (car current-cons)) (setq range-object (cdr current-cons))))) (my-test) #+end_src Loading this file test1.el crashes Emacs - but if you compile it, loading the compiled file doesn't crash. This is what I expected from my previous thoughts, because only the uncompiled closures include a reference to the outer VALs. test2.el: #+begin_src emacs-lisp ;; -*- lexical-binding: t -*- (require 'stream) (let ((stream (stream-range 1 1000000))) (stream-flush stream)) #+end_src This traverses the whole stream ignoring the elements. Loading this file crashes Emacs, no matter if compiled or not. I'm surprised it doesn't work even when compiled. test3.el: #+begin_src emacs-lisp ;; -*- lexical-binding: t -*- (require 'stream) (let ((stream (stream-range 1 1000000))) (while (not (stream-empty-p stream)) (cl-callf stream-rest stream))) #+end_src This is semantically exactly like test2.el, only the call to `stream-flush' has been replaced by literally writing out the definition. Nonetheless, the compiled file suddenly doesn't crash Emacs when loaded. Loading the uncompiled file test3.el still crashes. Seems that whether we get a crash or not depends on details in the implementation of lexical-binding. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-01 11:25 ` Michael Heerdegen @ 2018-03-01 15:00 ` Eli Zaretskii 2018-03-02 14:11 ` Noam Postavsky 1 sibling, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-01 15:00 UTC (permalink / raw) To: Michael Heerdegen; +Cc: npostavs, 30626 > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: npostavs@gmail.com, 30626@debbugs.gnu.org > Date: Thu, 01 Mar 2018 12:25:43 +0100 > > Seems that whether we get a crash or not depends on details in the > implementation of lexical-binding. Byte compilation doesn't just produce byte code, it also changes the code into an equivalent one, but "equivalence" in this context doesn't include side effects like stack usage. As an extreme example, consider a tail-recursive program that the byte compiler converts (or at least might convert theoretically) into a loop. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-01 11:25 ` Michael Heerdegen 2018-03-01 15:00 ` Eli Zaretskii @ 2018-03-02 14:11 ` Noam Postavsky 2018-03-02 15:06 ` Michael Heerdegen ` (2 more replies) 1 sibling, 3 replies; 253+ messages in thread From: Noam Postavsky @ 2018-03-02 14:11 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Nicolas Petton, 30626 Michael Heerdegen <michael_heerdegen@web.de> writes: > #+begin_src emacs-lisp > ;; -*- lexical-binding: t -*- > > (require 'stream) > > (let ((stream (stream-range 1 1000000))) > (while (not (stream-empty-p stream)) > (cl-callf stream-rest stream))) > #+end_src > > This is semantically exactly like test2.el, only the call to > `stream-flush' has been replaced by literally writing out the > definition. Nonetheless, the compiled file suddenly doesn't crash Emacs > when loaded. Loading the uncompiled file test3.el still crashes. Aha, but the following also crashes, whether compiled or not: ;; -*- lexical-binding: t -*- (require 'stream) (let* ((stream0 (stream-range 1 1000000)) (stream stream0)) (while (not (stream-empty-p stream)) (cl-callf stream-rest stream))) So the problem is that the initial stream0 object can reach the entire unfolding stream as it goes, and just holding on to that reference is enough to keep the whole thing in memory. Now, I can see that letting stream0 automagically get access to the unfolded result can be an optimization in some cases, although in this case it's a pessimization. It could also affect the semantics if unfolding the stream has side effects, not sure if stream.el makes guarantees about that though. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 14:11 ` Noam Postavsky @ 2018-03-02 15:06 ` Michael Heerdegen 2018-03-02 15:43 ` Eli Zaretskii 2018-03-02 20:16 ` Nicolas Petton 2018-03-02 21:48 ` John Mastro 2 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-03-02 15:06 UTC (permalink / raw) To: Noam Postavsky; +Cc: Nicolas Petton, 30626 Noam Postavsky <npostavs@gmail.com> writes: > Aha, but the following also crashes, whether compiled or not: > > ;; -*- lexical-binding: t -*- > > (require 'stream) > > (let* ((stream0 (stream-range 1 1000000)) > (stream stream0)) > (while (not (stream-empty-p stream)) > (cl-callf stream-rest stream))) I guess you should have some awe if you write something like (stream-range 1 1000000) and keep in mind what happens with this gigantic thing. Though, could the object `stream0' references not already be garbage-collected when the loop has been entered, since there is no lexical reference to that variable there? BTW, it gets even worse if you append streams, since the original streams are not copied and magically unfolded when you generate elements from the concatenation. > Now, I can see that letting stream0 automagically get access to the > unfolded result can be an optimization in some cases, although in this > case it's a pessimization. It could also affect the semantics if > unfolding the stream has side effects, not sure if stream.el makes > guarantees about that though. AFAICT we make no such guarantees at all. When generating stream elements has side effects (which is not ideal, but it's not forbidden), then you must know what you are doing. In my experience, side effects often directly correlate with element generation - e.g. for a stream of search matches, a side effect is to set a variable to the position where to continue searching. These kind of side effects are not problematic. For non-trivial side-effects, dunno, never wanted something like that. But this problem also concerns other forms of delayed evaluation, including thunks, and generally everything you can do with closures. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 15:06 ` Michael Heerdegen @ 2018-03-02 15:43 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-02 15:43 UTC (permalink / raw) To: Michael Heerdegen; +Cc: nicolas, npostavs, 30626 > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Fri, 02 Mar 2018 16:06:49 +0100 > Cc: Nicolas Petton <nicolas@petton.fr>, 30626@debbugs.gnu.org > > > (let* ((stream0 (stream-range 1 1000000)) > > (stream stream0)) > > (while (not (stream-empty-p stream)) > > (cl-callf stream-rest stream))) > > I guess you should have some awe if you write something like > (stream-range 1 1000000) and keep in mind what happens with this > gigantic thing. Though, could the object `stream0' references not > already be garbage-collected when the loop has been entered, since there > is no lexical reference to that variable there? It's still referenced by the let* form, I think. But even if it didn't, you cannot rely on it being GC'ed, because Emacs triggers GC at times which are hard or even impossible to predict. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 14:11 ` Noam Postavsky 2018-03-02 15:06 ` Michael Heerdegen @ 2018-03-02 20:16 ` Nicolas Petton 2018-03-02 20:58 ` Nicolas Petton 2018-03-03 7:54 ` Michael Heerdegen 2018-03-02 21:48 ` John Mastro 2 siblings, 2 replies; 253+ messages in thread From: Nicolas Petton @ 2018-03-02 20:16 UTC (permalink / raw) To: Noam Postavsky, Michael Heerdegen; +Cc: 30626 [-- Attachment #1: Type: text/plain, Size: 894 bytes --] Noam Postavsky <npostavs@gmail.com> writes: > Now, I can see that letting stream0 automagically get access to the > unfolded result can be an optimization in some cases, although in this > case it's a pessimization. stream.el is at its core just an implementation of lazy-cons cells, so not letting stream0 get access to the result would mean changing the core implementation (I'm not necessarily against it). If we accept that `seq-elt', and other positional functions of seq.el should not work on streams, then I could rewrite stream.el to make it a positioned stream where previous elements are discarded after each element generation. However the list of supported functions from seq.el API would be significantly reduced. > It could also affect the semantics if unfolding the stream has side > effects, not sure if stream.el makes guarantees about that though. No, it doesn't. Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 20:16 ` Nicolas Petton @ 2018-03-02 20:58 ` Nicolas Petton 2018-03-03 7:56 ` Michael Heerdegen 2018-03-03 7:54 ` Michael Heerdegen 1 sibling, 1 reply; 253+ messages in thread From: Nicolas Petton @ 2018-03-02 20:58 UTC (permalink / raw) To: Noam Postavsky, Michael Heerdegen; +Cc: 30626 [-- Attachment #1: Type: text/plain, Size: 1031 bytes --] Nicolas Petton <nicolas@petton.fr> writes: > If we accept that `seq-elt', and other positional functions of seq.el > should not work on streams, then I could rewrite stream.el to make it a > positioned stream where previous elements are discarded after each > element generation. However the list of supported functions from seq.el > API would be significantly reduced. I had something like the following in mind: (cl-defstruct nstream current next-function) (cl-defmethod nstream-next ((stream nstream)) (setf (nstream-current stream) (funcall (nstream-next-function stream) (nstream-current stream)))) (defun nstream-range (&optional start end step) (unless start (setq start 0)) (unless step (setq step 1)) (make-nstream :current start :next-function (lambda (cur) (if (equal cur end) nil (+ cur step))))) Cheers, Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 20:58 ` Nicolas Petton @ 2018-03-03 7:56 ` Michael Heerdegen 0 siblings, 0 replies; 253+ messages in thread From: Michael Heerdegen @ 2018-03-03 7:56 UTC (permalink / raw) To: Nicolas Petton; +Cc: Noam Postavsky, 30626 Nicolas Petton <nicolas@petton.fr> writes: > I had something like the following in mind: > > (cl-defstruct nstream current next-function) > > (cl-defmethod nstream-next ((stream nstream)) > (setf (nstream-current stream) (funcall (nstream-next-function stream) > (nstream-current stream)))) > > (defun nstream-range (&optional start end step) > (unless start (setq start 0)) > (unless step (setq step 1)) > (make-nstream :current start > :next-function (lambda (cur) > (if (equal cur end) > nil > (+ cur step))))) This is an implementation of iterators, not streams. We already have an implementation of iterators in Emacs. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 20:16 ` Nicolas Petton 2018-03-02 20:58 ` Nicolas Petton @ 2018-03-03 7:54 ` Michael Heerdegen 2018-03-03 8:47 ` Nicolas Petton 1 sibling, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-03-03 7:54 UTC (permalink / raw) To: Nicolas Petton; +Cc: Noam Postavsky, 30626 Nicolas Petton <nicolas@petton.fr> writes: > stream.el is at its core just an implementation of lazy-cons cells, so > not letting stream0 get access to the result would mean changing the > core implementation (I'm not necessarily against it). Please don't do this. The semantics of streams is worth keeping. I make use of it in el-search and other stuff. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-03 7:54 ` Michael Heerdegen @ 2018-03-03 8:47 ` Nicolas Petton 0 siblings, 0 replies; 253+ messages in thread From: Nicolas Petton @ 2018-03-03 8:47 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Noam Postavsky, 30626 [-- Attachment #1: Type: text/plain, Size: 214 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: > Please don't do this. The semantics of streams is worth keeping. I > make use of it in el-search and other stuff. I'm not saying that I want this :) Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 14:11 ` Noam Postavsky 2018-03-02 15:06 ` Michael Heerdegen 2018-03-02 20:16 ` Nicolas Petton @ 2018-03-02 21:48 ` John Mastro 2018-03-03 23:00 ` Noam Postavsky 2 siblings, 1 reply; 253+ messages in thread From: John Mastro @ 2018-03-02 21:48 UTC (permalink / raw) To: 30626; +Cc: Michael Heerdegen, Nicolas Petton, Noam Postavsky Noam Postavsky <npostavs@gmail.com> wrote: > Aha, but the following also crashes, whether compiled or not: > > ;; -*- lexical-binding: t -*- > > (require 'stream) > > (let* ((stream0 (stream-range 1 1000000)) > (stream stream0)) > (while (not (stream-empty-p stream)) > (cl-callf stream-rest stream))) > > So the problem is that the initial stream0 object can reach the entire > unfolding stream as it goes, and just holding on to that reference is > enough to keep the whole thing in memory. > > Now, I can see that letting stream0 automagically get access to the > unfolded result can be an optimization in some cases, although in this > case it's a pessimization. It could also affect the semantics if > unfolding the stream has side effects, not sure if stream.el makes > guarantees about that though. Clojure has/had a similar issue. They describe this scenario (having a live reference to the beginning of the stream, preventing GC from collecting it) as "holding onto the head" of the stream (in Clojure they're called lazy seqs). Their solution was what they call "locals clearing". The compiler tracks the lifetimes of local bindings and "clears" them (by setting them to nil/null) after their point of last use, e.g.: (let* ((stream0 (stream-range 1 1000000)) (stream stream0)) (setq stream0 nil) ;; <<< Inserted by compiler (while (not (stream-empty-p stream)) (cl-callf stream-rest stream))) If the code does reference stream0 later, locals clearing can't help you, but that's considered a "if it hurts, don't do it" situation. This probably isn't practical for Emacs, especially since it could only work for byte-compiled code, but thought the prior art may be of interest. John ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 21:48 ` John Mastro @ 2018-03-03 23:00 ` Noam Postavsky 2018-03-04 15:56 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-03 23:00 UTC (permalink / raw) To: John Mastro; +Cc: Michael Heerdegen, Nicolas Petton, 30626 John Mastro <john.b.mastro@gmail.com> writes: > (let* ((stream0 (stream-range 1 1000000)) > (stream stream0)) > (setq stream0 nil) ;; <<< Inserted by compiler > (while (not (stream-empty-p stream)) > (cl-callf stream-rest stream))) > > If the code does reference stream0 later, locals clearing can't help > you, but that's considered a "if it hurts, don't do it" situation. > > This probably isn't practical for Emacs, especially since it could only > work for byte-compiled code, but thought the prior art may be of > interest. Not sure how doable this solution is, but the fact that it works only for byte-compiled code seems fine to me. The interpreted case is doomed to fail anyway since the interpreter doesn't prune redundant variables from closures. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-03 23:00 ` Noam Postavsky @ 2018-03-04 15:56 ` Noam Postavsky 2018-03-04 17:02 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-04 15:56 UTC (permalink / raw) To: John Mastro; +Cc: Michael Heerdegen, Nicolas Petton, 30626 Noam Postavsky <npostavs@gmail.com> writes: > John Mastro <john.b.mastro@gmail.com> writes: > >> (let* ((stream0 (stream-range 1 1000000)) >> (stream stream0)) >> (setq stream0 nil) ;; <<< Inserted by compiler >> (while (not (stream-empty-p stream)) >> (cl-callf stream-rest stream))) >> >> If the code does reference stream0 later, locals clearing can't help >> you, but that's considered a "if it hurts, don't do it" situation. >> >> This probably isn't practical for Emacs, especially since it could only >> work for byte-compiled code, but thought the prior art may be of >> interest. > > Not sure how doable this solution is, but the fact that it works only > for byte-compiled code seems fine to me. The interpreted case is doomed > to fail anyway since the interpreter doesn't prune redundant variables > from closures. Hmm, I think it won't work by itself though, just doing (stream-flush (stream-range 1 1000000)) also crashes, due to the head of the stream being referenced from the C stack somewhere (I can get the address from gdb, but I can't figure out how to get to the corresponding C variable from there). ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-04 15:56 ` Noam Postavsky @ 2018-03-04 17:02 ` Eli Zaretskii 2018-03-11 18:52 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-04 17:02 UTC (permalink / raw) To: Noam Postavsky; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > From: Noam Postavsky <npostavs@gmail.com> > Date: Sun, 04 Mar 2018 10:56:36 -0500 > Cc: Michael Heerdegen <michael_heerdegen@web.de>, > Nicolas Petton <nicolas@petton.fr>, 30626@debbugs.gnu.org > > Hmm, I think it won't work by itself though, just doing > > (stream-flush (stream-range 1 1000000)) > > also crashes, due to the head of the stream being referenced from the C > stack somewhere (I can get the address from gdb, but I can't figure out > how to get to the corresponding C variable from there). Did you try "info symbol ADDRESS"? (I'm not sure this will work for automatic variables, though.) You could also try "info locals" after "set print address on" and/or "set print symbol on". ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-04 17:02 ` Eli Zaretskii @ 2018-03-11 18:52 ` Noam Postavsky 2018-03-11 20:31 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-11 18:52 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 [-- Attachment #1: Type: text/plain, Size: 1319 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> also crashes, due to the head of the stream being referenced from the C >> stack somewhere (I can get the address from gdb, but I can't figure out >> how to get to the corresponding C variable from there). > > Did you try "info symbol ADDRESS"? (I'm not sure this will work for > automatic variables, though.) Doesn't seem to work. I guess it wouldn't work if the address was in the middle of an array either. > You could also try "info locals" after "set print address on" and/or > "set print symbol on". Those settings don't seem to help. I first guessed that the problem is due to saving function arguments during funcall, so I tried the following to check it: --- i/src/bytecode.c +++ w/src/bytecode.c @@ -387,7 +387,10 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, make_number (nargs))); ptrdiff_t pushedargs = min (nonrest, nargs); for (ptrdiff_t i = 0; i < pushedargs; i++, args++) - PUSH (*args); + { + PUSH (*args); + *args = Qnil; + } if (nonrest < nargs) PUSH (Flist (nargs - nonrest, args)); else This did change the backtrace (from starting with mark_specpdl to mark_stack), meaning I did find one reference, but it still crashes, so there must be more. [-- Attachment #2: gdb log excerpts --] [-- Type: text/plain, Size: 7995 bytes --] No stack. Starting program: /home/npostavs/src/emacs/emacs-26/lucid/src/emacs -Q -batch -l elpa/packages/stream/stream.elc -l bug-30626-stream-crash/test5.elc [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x000000000060e9b5 in live_cons_holding (m=0x2f6e290, p=0x2f77620) at ../../src/alloc.c:4613 4613 return make_lisp_ptr (s, Lisp_Cons); #0 0x000000000060e9b5 in live_cons_holding (m=0x2f6e290, p=0x2f77620) at ../../src/alloc.c:4613 #1 0x000000000060e9ec in live_cons_p (m=0x2f6e290, p=0x2f77620) at ../../src/alloc.c:4622 #2 0x0000000000612f94 in mark_object (arg=XIL(0x2f77623)) at ../../src/alloc.c:6717 #3 0x0000000000611d4f in mark_vectorlike (ptr=0x2f78b50) at ../../src/alloc.c:6227 [...] #4850 0x0000000000612b42 in mark_object (arg=XIL(0x2efcb83)) at ../../src/alloc.c:6624 #4851 0x0000000000611d4f in mark_vectorlike (ptr=0x2e64c90) at ../../src/alloc.c:6227 #4852 0x0000000000612b42 in mark_object (arg=XIL(0x2e64c95)) at ../../src/alloc.c:6624 #4853 0x000000000060f3ce in mark_maybe_pointer (p=0x2e64c90) at ../../src/alloc.c:4936 #4854 0x000000000060f452 in mark_memory (start=0x7fffffffa520, end=0x7fffffffe868) at ../../src/alloc.c:4985 #4855 0x000000000060f493 in mark_stack (bottom=0x7fffffffe868 "a\036h\364\377\177", end=0x7fffffffa520 "0\245\377\377\377\177") at ../../src/alloc.c:5193 #4856 0x00000000006cdd75 in mark_one_thread (thread=0xe103e0 <main_thread>) at ../../src/thread.c:616 #4857 0x00000000006cdf0a in mark_threads_callback (ignore=0x0) at ../../src/thread.c:649 #4858 0x000000000060f4da in flush_stack_call_func (func=0x6cde77 <mark_threads_callback>, arg=0x0) at ../../src/alloc.c:5220 #4859 0x00000000006cdf3c in mark_threads () at ../../src/thread.c:656 #4860 0x00000000006114a7 in garbage_collect_1 (end=0x7fffffffa700) at ../../src/alloc.c:5997 #4861 0x0000000000611b94 in Fgarbage_collect () at ../../src/alloc.c:6168 #4862 0x000000000057999d in maybe_gc () at ../../src/lisp.h:4749 #4863 0x000000000063c2cb in Ffuncall (nargs=6, args=0x7fffffffa7f8) at ../../src/eval.c:2751 #4864 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2e7aad4), vector=XIL(0x2e72715), maxdepth=make_number(18), args_template=make_number(768), nargs=3, args=0x7fffffffad20) at ../../src/bytecode.c:632 #4865 0x000000000063cfef in funcall_lambda (fun=XIL(0x1450e45), nargs=3, arg_vector=0x7fffffffad08) at ../../src/eval.c:2970 #4866 0x000000000063c402 in Ffuncall (nargs=4, args=0x7fffffffad00) at ../../src/eval.c:2771 #4867 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2e7b2d4), vector=XIL(0x2fe2945), maxdepth=make_number(7), args_template=make_number(256), nargs=0, args=0x7fffffffb1d8) at ../../src/bytecode.c:632 #4868 0x000000000063cfef in funcall_lambda (fun=XIL(0x2fe2985), nargs=0, arg_vector=0x7fffffffb1d8) at ../../src/eval.c:2970 #4869 0x000000000063c402 in Ffuncall (nargs=1, args=0x7fffffffb1d0) at ../../src/eval.c:2771 #4870 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2e769d4), vector=XIL(0x9d00a5), maxdepth=make_number(2), args_template=make_number(257), nargs=1, args=0x7fffffffb670) at ../../src/bytecode.c:632 #4871 0x000000000063cfef in funcall_lambda (fun=XIL(0x1626f05), nargs=1, arg_vector=0x7fffffffb668) at ../../src/eval.c:2970 #4872 0x000000000063c402 in Ffuncall (nargs=2, args=0x7fffffffb660) at ../../src/eval.c:2771 #4873 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2e7f7b4), vector=XIL(0x1622fe5), maxdepth=make_number(3), args_template=make_number(257), nargs=1, args=0x7fffffffbb10) at ../../src/bytecode.c:632 #4874 0x000000000063cfef in funcall_lambda (fun=XIL(0x1450f35), nargs=1, arg_vector=0x7fffffffbb08) at ../../src/eval.c:2970 #4875 0x000000000063c402 in Ffuncall (nargs=2, args=0x7fffffffbb00) at ../../src/eval.c:2771 #4876 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2ee3c94), vector=XIL(0x2e664f5), maxdepth=make_number(3), args_template=make_number(257), nargs=1, args=0x7fffffffbfa8) at ../../src/bytecode.c:632 #4877 0x000000000063cfef in funcall_lambda (fun=XIL(0x2e66515), nargs=1, arg_vector=0x7fffffffbfa0) at ../../src/eval.c:2970 #4878 0x000000000063c402 in Ffuncall (nargs=2, args=0x7fffffffbf98) at ../../src/eval.c:2771 #4879 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2e91054), vector=XIL(0x1699ef5), maxdepth=make_number(4), args_template=XIL(0), nargs=0, args=0x0) at ../../src/bytecode.c:632 #4880 0x000000000068cb20 in Fbyte_code (bytestr=XIL(0x2e91054), vector=XIL(0x1699ef5), maxdepth=make_number(4)) at ../../src/bytecode.c:321 #4881 0x000000000063ac83 in eval_sub (form=XIL(0x2eeb413)) at ../../src/eval.c:2240 #4882 0x0000000000672b34 in readevalloop (readcharfun=XIL(0x68a0), infile0=0x7fffffffc6b0, sourcename=XIL(0x2e90f94), printflag=false, unibyte=XIL(0), readfun=XIL(0), start=XIL(0), end=XIL(0)) at ../../src/lread.c:2038 #4883 0x0000000000670e85 in Fload (file=XIL(0x2e8d884), noerror=XIL(0), nomessage=XIL(0xc090), nosuffix=XIL(0), must_suffix=XIL(0)) at ../../src/lread.c:1425 #4884 0x000000000063c945 in funcall_subr (subr=0xd7a420 <Sload>, numargs=3, args=0x7fffffffc8e8) at ../../src/eval.c:2856 #4885 0x000000000063c3be in Ffuncall (nargs=4, args=0x7fffffffc8e0) at ../../src/eval.c:2769 #4886 0x000000000068d950 in exec_byte_code (bytestr=XIL(0xadcc2c), vector=XIL(0xadcc4d), maxdepth=make_number(23), args_template=make_number(257), nargs=1, args=0x7fffffffd248) at ../../src/bytecode.c:632 #4887 0x000000000063cfef in funcall_lambda (fun=XIL(0xadcbfd), nargs=1, arg_vector=0x7fffffffd240) at ../../src/eval.c:2970 #4888 0x000000000063c402 in Ffuncall (nargs=2, args=0x7fffffffd238) at ../../src/eval.c:2771 #4889 0x000000000068d950 in exec_byte_code (bytestr=XIL(0xad7424), vector=XIL(0xad7445), maxdepth=make_number(21), args_template=make_number(0), nargs=0, args=0x7fffffffde58) at ../../src/bytecode.c:632 #4890 0x000000000063cfef in funcall_lambda (fun=XIL(0xad73f5), nargs=0, arg_vector=0x7fffffffde58) at ../../src/eval.c:2970 #4891 0x000000000063c402 in Ffuncall (nargs=1, args=0x7fffffffde50) at ../../src/eval.c:2771 #4892 0x000000000068d950 in exec_byte_code (bytestr=XIL(0xad6614), vector=XIL(0xad6635), maxdepth=make_number(12), args_template=make_number(0), nargs=0, args=0x7fffffffe480) at ../../src/bytecode.c:632 #4893 0x000000000063cfef in funcall_lambda (fun=XIL(0xad65e5), nargs=0, arg_vector=0x7fffffffe480) at ../../src/eval.c:2970 #4894 0x000000000063cc29 in apply_lambda (fun=XIL(0xad65e5), args=XIL(0), count=4) at ../../src/eval.c:2906 #4895 0x000000000063ae2a in eval_sub (form=XIL(0x149a8e3)) at ../../src/eval.c:2279 #4896 0x000000000063a19f in Feval (form=XIL(0x149a8e3), lexical=XIL(0)) at ../../src/eval.c:2054 #4897 0x000000000058150f in top_level_2 () at ../../src/keyboard.c:1119 #4898 0x00000000006384ce in internal_condition_case (bfun=0x5814ec <top_level_2>, handlers=XIL(0x5250), hfun=0x580ef1 <cmd_error>) at ../../src/eval.c:1332 #4899 0x0000000000581554 in top_level_1 (ignore=XIL(0)) at ../../src/keyboard.c:1127 #4900 0x00000000006379d7 in internal_catch (tag=XIL(0xc6f0), func=0x581511 <top_level_1>, arg=XIL(0)) at ../../src/eval.c:1097 #4901 0x000000000058143e in command_loop () at ../../src/keyboard.c:1088 #4902 0x00000000005809db in recursive_edit_1 () at ../../src/keyboard.c:695 #4903 0x0000000000580bd0 in Frecursive_edit () at ../../src/keyboard.c:766 #4904 0x000000000057e76b in main (argc=7, argv=0x7fffffffe9e8) at ../../src/emacs.c:1713 Cannot access memory at address 0x7ffffff7ef7f (gdb) frame 4854 #4854 0x000000000060f452 in mark_memory (start=0x7fffffffa520, end=0x7fffffffe868) at ../../src/alloc.c:4985 4985 mark_maybe_pointer (*(void **) pp); (gdb) info locals pp = 0x7fffffffa968 "\220L\346\002" (gdb) info symbol 0x7fffffffa968 No symbol matches 0x7fffffffa968. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-11 18:52 ` Noam Postavsky @ 2018-03-11 20:31 ` Eli Zaretskii 2018-03-11 21:51 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-11 20:31 UTC (permalink / raw) To: Noam Postavsky; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > From: Noam Postavsky <npostavs@gmail.com> > Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org > Date: Sun, 11 Mar 2018 14:52:22 -0400 > > This did change the backtrace (from starting with mark_specpdl to > mark_stack), meaning I did find one reference, but it still crashes, so > there must be more. If you have the address, you could first find the stack frame to which it belongs, right? Then go to that stack frame and type "info locals", which should give you the locals in that frame. One of them is your variable. It could also be a temporary slot, in which case disassembly of that frame's function should show it. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-11 20:31 ` Eli Zaretskii @ 2018-03-11 21:51 ` Noam Postavsky 2018-03-12 3:28 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-11 21:51 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 Eli Zaretskii <eliz@gnu.org> writes: >> From: Noam Postavsky <npostavs@gmail.com> >> Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org >> Date: Sun, 11 Mar 2018 14:52:22 -0400 >> >> This did change the backtrace (from starting with mark_specpdl to >> mark_stack), meaning I did find one reference, but it still crashes, so >> there must be more. > > If you have the address, you could first find the stack frame to which > it belongs, right? Um, how do I do that part? ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-11 21:51 ` Noam Postavsky @ 2018-03-12 3:28 ` Eli Zaretskii 2018-03-13 1:59 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-12 3:28 UTC (permalink / raw) To: Noam Postavsky; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > From: Noam Postavsky <npostavs@gmail.com> > Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org > Date: Sun, 11 Mar 2018 17:51:19 -0400 > > > If you have the address, you could first find the stack frame to which > > it belongs, right? > > Um, how do I do that part? By comparing the address with the value of $bp in each frame, I'd say. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-12 3:28 ` Eli Zaretskii @ 2018-03-13 1:59 ` Noam Postavsky 2018-03-13 16:06 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-13 1:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 Eli Zaretskii <eliz@gnu.org> writes: >> From: Noam Postavsky <npostavs@gmail.com> >> Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org >> Date: Sun, 11 Mar 2018 17:51:19 -0400 >> >> > If you have the address, you could first find the stack frame to which >> > it belongs, right? >> >> Um, how do I do that part? > > By comparing the address with the value of $bp in each frame, I'd say. Hmm, I found a match, but it doesn't make any sense. #4851 0x0000000000611d4f in mark_vectorlike (ptr=0x2e64c90) at ../../src/alloc.c:6227 #4852 0x0000000000612b42 in mark_object (arg=XIL(0x2e64c95)) at ../../src/alloc.c:6624 #4853 0x000000000060f3ce in mark_maybe_pointer (p=0x2e64c90) at ../../src/alloc.c:4936 #4854 0x000000000060f452 in mark_memory (start=0x7fffffffa520, end=0x7fffffffe868) at ../../src/alloc.c:4985 #4855 0x000000000060f493 in mark_stack (bottom=0x7fffffffe868 "a\036h\364\377\177", end=0x7fffffffa520 "0\245\377\377\377\177") at ../../src/alloc.c:5193 (gdb) frame 4854 #4854 0x000000000060f452 in mark_memory (start=0x7fffffffa520, end=0x7fffffffe868) at ../../src/alloc.c:4985 4985 mark_maybe_pointer (*(void **) pp); (gdb) p pp $28 = 0x7fffffffa968 "\220L\346\002" (gdb) frame 4864 #4864 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2e7aad4), vector=XIL(0x2e72715), maxdepth=make_number(18), args_template=make_number(768), nargs=3, args=0x7fffffffad20) at ../../src/bytecode.c:632 632 TOP = Ffuncall (op + 1, &TOP); (gdb) p $rbp $29 = (void *) 0x7fffffffabd0 (gdb) p/x $rbp - $28 $32 = 0x268 (gdb) disas /s [...] 1180 CASE (Bbuffer_substring): 1181 { 1182 Lisp_Object v1 = POP; 0x000000000068fea4 <+13154>: mov -0x40(%rbp),%rax 0x000000000068fea8 <+13158>: lea -0x8(%rax),%rdx 0x000000000068feac <+13162>: mov %rdx,-0x40(%rbp) 0x000000000068feb0 <+13166>: mov (%rax),%rax 0x000000000068feb3 <+13169>: mov %rax,-0x268(%rbp) 1183 TOP = Fbuffer_substring (TOP, v1); 0x000000000068feba <+13176>: mov -0x268(%rbp),%rdx 0x000000000068fec1 <+13183>: mov -0x40(%rbp),%rax 0x000000000068fec5 <+13187>: mov %rdx,%rsi 0x000000000068fec8 <+13190>: mov (%rax),%rdi 0x000000000068fecb <+13193>: callq 0x627e0a <Fbuffer_substring> It can't be a buffer-substring arg, but that's the only reference to -0x268(%rbp) in that function. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-13 1:59 ` Noam Postavsky @ 2018-03-13 16:06 ` Eli Zaretskii 2018-03-14 0:09 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-13 16:06 UTC (permalink / raw) To: Noam Postavsky; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > From: Noam Postavsky <npostavs@gmail.com> > Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org > Date: Mon, 12 Mar 2018 21:59:57 -0400 > > 4985 mark_maybe_pointer (*(void **) pp); > (gdb) p pp > $28 = 0x7fffffffa968 "\220L\346\002" Should you look at pp or at *pp? Also note that for Lisp objects that are marked you need to reset their mark bit before trying to determine their type and value. If none of the above helps, please walk me through the steps that led you to look at -0x268(%rbp), because I'm not sure I follow. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-13 16:06 ` Eli Zaretskii @ 2018-03-14 0:09 ` Noam Postavsky 2018-03-15 16:34 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-14 0:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 Eli Zaretskii <eliz@gnu.org> writes: > Should you look at pp or at *pp? I think it should be pp, but I'm not sure. The context: #4854 0x000000000060f452 in mark_memory (start=0x7fffffffa520, end=0x7fffffffe868) at ../../src/alloc.c:4985 #4855 0x000000000060f493 in mark_stack (bottom=0x7fffffffe868 "a\036h\364\377\177", end=0x7fffffffa520 "0\245\377\377\377\177") at ../../src/alloc.c:5193 mark_memory (void *start, void *end) { ... for (pp = start; (void *) pp < end; pp += GC_POINTER_ALIGNMENT) { mark_maybe_pointer (*(void **) pp); mark_maybe_object (*(Lisp_Object *) pp); } So the value of pp ranges over stack addresses and *pp would be the contents of the stack location. > Also note that for Lisp objects that are marked you need to reset > their mark bit before trying to determine their type and value. I think I'm looking for a C variable, and not a Lisp object (although the C variable presumably contains/points to a Lisp object). > If none of the above helps, please walk me through the steps that led > you to look at -0x268(%rbp), because I'm not sure I follow. Starting with the value of pp, I then go up looking for a close value of $rbp: (gdb) p pp $39 = 0x7fffffffa968 "\220L\346\002" (gdb) up #4855 0x000000000060f493 in mark_stack (bottom=0x7fffffffe868 "a\036h\364\377\177", end=0x7fffffffa520 "0\245\377\377\377\177") at ../../src/alloc.c:5193 5193 mark_memory (bottom, end); (gdb) p $rbp $40 = (void *) 0x7fffffffa420 (gdb) up #4856 0x00000000006cdd75 in mark_one_thread (thread=0xe103e0 <main_thread>) at ../../src/thread.c:616 616 mark_stack (thread->m_stack_bottom, stack_top); (gdb) p $rbp $41 = (void *) 0x7fffffffa470 [...] (gdb) up #4863 0x000000000063c2cb in Ffuncall (nargs=6, args=0x7fffffffa7f8) at ../../src/eval.c:2751 2751 maybe_gc (); (gdb) p $rbp $48 = (void *) 0x7fffffffa780 (gdb) up #4864 0x000000000068d950 in exec_byte_code (bytestr=XIL(0x2e7aad4), vector=XIL(0x2e72715), maxdepth=make_number(18), args_template=make_number(768), nargs=3, args=0x7fffffffad20) at ../../src/bytecode.c:632 632 TOP = Ffuncall (op + 1, &TOP); (gdb) p $rbp $49 = (void *) 0x7fffffffabd0 Now I see that $rbp is higher than the target address, and the difference is 0x268, so the target location should be -0x268(%rbp). (gdb) p $rbp - 0x7fffffffa968 $52 = (void *) 0x268 Except something must be wrong in my reasoning, since the only ocurrences of -0x268(%rbp) are the buffer-string args, which could only hold integers or markers (neither of which could further point to long chains of objects). ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-14 0:09 ` Noam Postavsky @ 2018-03-15 16:34 ` Eli Zaretskii 2018-03-17 15:53 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-15 16:34 UTC (permalink / raw) To: Noam Postavsky; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > From: Noam Postavsky <npostavs@gmail.com> > Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org > Date: Tue, 13 Mar 2018 20:09:17 -0400 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Should you look at pp or at *pp? > > I think it should be pp, but I'm not sure. The context: > > #4854 0x000000000060f452 in mark_memory (start=0x7fffffffa520, end=0x7fffffffe868) > at ../../src/alloc.c:4985 > #4855 0x000000000060f493 in mark_stack (bottom=0x7fffffffe868 "a\036h\364\377\177", > end=0x7fffffffa520 "0\245\377\377\377\177") at ../../src/alloc.c:5193 > > mark_memory (void *start, void *end) > { > ... > for (pp = start; (void *) pp < end; pp += GC_POINTER_ALIGNMENT) > { > mark_maybe_pointer (*(void **) pp); > mark_maybe_object (*(Lisp_Object *) pp); > } > > So the value of pp ranges over stack addresses and *pp would be the > contents of the stack location. But the call to mark_maybe_pointer means that we consider pp to be a pointer (in)to a Lisp object. Anyway, wouldn't it be easier to look one frame lower? We have this: #4850 0x0000000000612b42 in mark_object (arg=XIL(0x2efcb83)) at ../../src/alloc.c:6624 #4851 0x0000000000611d4f in mark_vectorlike (ptr=0x2e64c90) at ../../src/alloc.c:6227 #4852 0x0000000000612b42 in mark_object (arg=XIL(0x2e64c95)) at ../../src/alloc.c:6624 #4853 0x000000000060f3ce in mark_maybe_pointer (p=0x2e64c90) at ../../src/alloc.c:4936 #4854 0x000000000060f452 in mark_memory (start=0x7fffffffa520, end=0x7fffffffe868) at ../../src/alloc.c:4985 #4855 0x000000000060f493 in mark_stack (bottom=0x7fffffffe868 "a\036h\364\377\177", end=0x7fffffffa520 "0\245\377\377\377\177") at ../../src/alloc.c:5193 In frame #4852, we have found an object, and we are marking it. Did you try looking at that object? With these caveats: > > Also note that for Lisp objects that are marked you need to reset > > their mark bit before trying to determine their type and value. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-15 16:34 ` Eli Zaretskii @ 2018-03-17 15:53 ` Noam Postavsky 2018-03-17 16:10 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-17 15:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 Eli Zaretskii <eliz@gnu.org> writes: > In frame #4852, we have found an object, and we are marking it. Did > you try looking at that object? With these caveats: > >> > Also note that for Lisp objects that are marked you need to reset >> > their mark bit before trying to determine their type and value. Okay, I think xpr takes care of that, right? (I've restarted the debug sessions a few times, so numbers may not match exactly) #4853 0x000000000060f429 in mark_maybe_pointer (p=0x2e64c90) at ../../src/alloc.c:4936 4936 mark_object (obj); (gdb) p obj $60 = XIL(0x2e64c95) (gdb) xpr Lisp_Vectorlike PVEC_NORMAL_VECTOR $61 = (struct Lisp_Vector *) 0x2e64c90 {XIL(0x2efcb63), make_number(1000000), XIL(0x2efcb53), XIL(0x2efcb73), XIL(0x2efcb83), XIL(0x20ab5b0), XIL(0xc090)} (gdb) p $61->contents[0] $62 = XIL(0x2efcb63) (gdb) xpr Lisp_Cons $63 = (struct Lisp_Cons *) 0x2efcb60 { [...] car = make_number(2369), [...] chain = 0x0 [...] (gdb) p $61->contents[1] $64 = make_number(1000000) (gdb) p $61->contents[2] $65 = XIL(0x2efcb53) (gdb) xpr Lisp_Cons [...] car = make_number(1), [...] chain = 0x0 [...] (gdb) p $61->contents[3] $67 = XIL(0x2efcb73) (gdb) xpr [...] car = XIL(0xc090), [...] chain = 0x0 [...] (gdb) p $61->contents[4] [...] car = XIL(0x2efc443), [...] chain = 0x0 [...] (gdb) p $61->contents[5] [...] $72 = (struct Lisp_Symbol *) 0x2e97ef0 "stream-range" (gdb) p $61->contents[6] [...] $74 = (struct Lisp_Symbol *) 0xdf89d0 <lispsym+49296> "t" It looks like a the lexical environment of a bytecode function, probably the initial stream, e.g., (stream-range 1 1000000) gives: (--stream-- #[256 "\211\203\303\242\207\303\242\204 \304\300\242\305\300\242\302\242\\\301\302\242#B\240\210\303\306\240\210\304\242\207" [(1) 1000000 (1) (nil) (nil) stream-range t] 7 " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (fn &optional CHECK)"]) Not sure where to go next with this. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-17 15:53 ` Noam Postavsky @ 2018-03-17 16:10 ` Eli Zaretskii 2018-03-17 16:27 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-17 16:10 UTC (permalink / raw) To: Noam Postavsky; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > From: Noam Postavsky <npostavs@gmail.com> > Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org > Date: Sat, 17 Mar 2018 11:53:36 -0400 > > It looks like a the lexical environment of a bytecode function, probably > the initial stream, e.g., (stream-range 1 1000000) gives: > > (--stream-- #[256 "\211\203\303\242\207\303\242\204 \304\300\242\305\300\242\302\242\\\301\302\242#B\240\210\303\306\240\210\304\242\207" > [(1) 1000000 (1) (nil) (nil) stream-range t] 7 " > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > (fn &optional CHECK)"]) > > Not sure where to go next with this. The goal was to find out which variable holds a reference to the entire long stream, right? So it sounds like a pointer to it is kept in an automatic variable on the stack of exec_byte_code, right? Which kinda makes sense, since the stream is still being processed, I think. Or am I confused? ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-17 16:10 ` Eli Zaretskii @ 2018-03-17 16:27 ` Eli Zaretskii 2018-03-17 17:28 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-17 16:27 UTC (permalink / raw) To: npostavs; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > Date: Sat, 17 Mar 2018 18:10:24 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, > 30626@debbugs.gnu.org > > > (--stream-- #[256 "\211\203\303\242\207\303\242\204 \304\300\242\305\300\242\302\242\\\301\302\242#B\240\210\303\306\240\210\304\242\207" > > [(1) 1000000 (1) (nil) (nil) stream-range t] 7 " > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > > > (fn &optional CHECK)"]) > > > > Not sure where to go next with this. > > The goal was to find out which variable holds a reference to the > entire long stream, right? So it sounds like a pointer to it is kept > in an automatic variable on the stack of exec_byte_code, right? Which > kinda makes sense, since the stream is still being processed, I think. > > Or am I confused? Actually, there's still some mystery: if this object is a 7-element vector, where do all the other GC frame come from? Hmm... how long/deep is each of the cons cells in elements 1 through 4 of the vector? If they are deeply nested, then that's the answer we've been looking for, I think. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-17 16:27 ` Eli Zaretskii @ 2018-03-17 17:28 ` Noam Postavsky 2018-03-19 20:05 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-17 17:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 Eli Zaretskii <eliz@gnu.org> writes: >> The goal was to find out which variable holds a reference to the >> entire long stream, right? So it sounds like a pointer to it is kept >> in an automatic variable on the stack of exec_byte_code, right? Which >> kinda makes sense, since the stream is still being processed, I >> think. Yeah, but which variable exactly? I'd like to find it and add 'X = Qnil;' to confirm we've found where it is. > Actually, there's still some mystery: if this object is a 7-element > vector, where do all the other GC frame come from? Hmm... how > long/deep is each of the cons cells in elements 1 through 4 of the > vector? If they are deeply nested, then that's the answer we've been > looking for, I think. It's a bit confusing because of the indirection: stream-range uses the stream-cons macro, which uses the stream-make macro, which uses the thunk-delay macro. I believe the end result is that the lexical environment of the resulting closure has access to the next stream-element in the chain, so the nesting depth is the length of the stream (i.e., 100000 in the example). Perhaps this example makes it clearer: (setq print-circle t) (let* ((s0 (stream-range 1 2)) (s1 (stream-rest s0))) (list s0 s1)) ;=> ((--stream-- #[256 "\211\203..." [(1) 2 (1) (t) ((1 . #1=(--stream-- #[256 "\211\203..." [(nil) (nil) nil t] 3 "\n\n(fn &optional CHECK)"]))) stream-range t] 7 "\n\n(fn &optional CHECK)"]) #1#) ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-17 17:28 ` Noam Postavsky @ 2018-03-19 20:05 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-19 20:05 UTC (permalink / raw) To: Noam Postavsky; +Cc: michael_heerdegen, john.b.mastro, nicolas, 30626 > From: Noam Postavsky <npostavs@gmail.com> > Cc: michael_heerdegen@web.de, john.b.mastro@gmail.com, nicolas@petton.fr, 30626@debbugs.gnu.org > Date: Sat, 17 Mar 2018 13:28:22 -0400 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> The goal was to find out which variable holds a reference to the > >> entire long stream, right? So it sounds like a pointer to it is kept > >> in an automatic variable on the stack of exec_byte_code, right? Which > >> kinda makes sense, since the stream is still being processed, I > >> think. > > Yeah, but which variable exactly? I'd like to find it and add 'X = > Qnil;' to confirm we've found where it is. I don't think you will be able to tell without stepping through the byte-code interpreter code, keeping track of what it stores where. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 10:58 ` Michael Heerdegen 2018-02-28 16:00 ` Eli Zaretskii @ 2019-04-25 3:20 ` Noam Postavsky 2019-04-25 5:19 ` Michael Heerdegen 1 sibling, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2019-04-25 3:20 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Nicolas Petton, 30626 [-- Attachment #1: Type: text/plain, Size: 1382 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: >> I don't have a quick answer for the general case, but I think it's a bug >> in stream.el that it's creating such large structures in the first >> place. As far as I understand it, the point of streams is to handle >> long lists by encoding them as >> >> (FIRST-VALUE . FUNCTION-TO-PRODUCE-REST-OF-LIST) > > Yes, that's exactly how it's implemented. When requesting more elements > from the stream, that becomes > > (FIRST-VALUE . > (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST)) > > When we loop over the string, the cons whose car is the FIRST-VALUE, > let's call it cons1, is immediately thrown away, and we continue with > > (SECOND-VALUE . FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST) Coming back to this again. I think I got lost in the weeds of the byte-code function objects before. The core problem is that streams are not exactly encoded like the above, because even after forcing it you don't have just a plain SECOND-VALUE stored in the stream. The original FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST stays around and keeps referencing all the code and all the following elements. So a possible solution is change the stream to get rid of the lambda part and just leave the computed value after it's forced. With the following patch (stream-flush (stream-range 1 1000000)) succeeds: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: patch --] [-- Type: text/x-diff, Size: 2937 bytes --] From 5e7139618f1b4cebbe9785ea5a9303b80d1b2c92 Mon Sep 17 00:00:00 2001 From: Noam Postavsky <npostavs@users.sourceforge.net> Date: Wed, 24 Apr 2019 22:51:19 -0400 Subject: [PATCH] [WIP] Drop forced lambda's from stream (Bug#30626) Let the stream id distinguish between forced and unforced stream values, replacing (think-delay BODY) with just (lambda () BODY). When the value is forced, replace the lambda with its result. --- packages/stream/stream.el | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/stream/stream.el b/packages/stream/stream.el index 3f6bc4b5b..fa7a3b520 100644 --- a/packages/stream/stream.el +++ b/packages/stream/stream.el @@ -65,18 +65,28 @@ (eval-when-compile (require 'cl-lib)) (require 'seq) -(require 'thunk) (eval-and-compile - (defconst stream--identifier '--stream-- - "Symbol internally used to identify streams.")) + (defconst stream--fresh-identifier '--stream-fresh-- + "Symbol internally used to streams whose head was not evaluated.") + (defconst stream--evald-identifier '--stream-evald-- + "Symbol internally used to streams whose head was evaluated.")) (defmacro stream-make (&rest body) "Return a stream built from BODY. BODY must return nil or a cons cell whose cdr is itself a stream." (declare (debug t)) - `(list ',stream--identifier (thunk-delay ,@body))) + `(list ',stream--fresh-identifier (lambda () ,@body))) + +(defun stream-force (stream) + (cond + ((eq (car-safe stream) stream--evald-identifier) + (cadr stream)) + ((eq (car-safe stream) stream--fresh-identifier) + (setf (car stream) stream--evald-identifier) + (setf (cadr stream) (funcall (cadr stream)))) + (t (signal 'wrong-type-argument (list 'streamp stream))))) (defmacro stream-cons (first rest) "Return a stream built from the cons of FIRST and REST. @@ -159,24 +169,26 @@ (defun stream-range (&optional start end step) (defun streamp (stream) "Return non-nil if STREAM is a stream, nil otherwise." - (eq (car-safe stream) stream--identifier)) + (let ((car (car-safe stream))) + (or (eq car stream--fresh-identifier) + (eq car stream--evald-identifier)))) (defun stream-empty () "Return a new empty stream." - (list stream--identifier (thunk-delay nil))) + (list stream--evald-identifier nil)) (defun stream-empty-p (stream) "Return non-nil if STREAM is empty, nil otherwise." - (null (thunk-force (cadr stream)))) + (null (cadr (stream-force stream)))) (defun stream-first (stream) "Return the first element of STREAM. Return nil if STREAM is empty." - (car (thunk-force (cadr stream)))) + (car (stream-force stream))) (defun stream-rest (stream) "Return a stream of all but the first element of STREAM." - (or (cdr (thunk-force (cadr stream))) + (or (cdr (stream-force stream)) (stream-empty))) (defun stream-append (&rest streams) -- 2.11.0 [-- Attachment #3: Type: text/plain, Size: 494 bytes --] The reason I didn't do this in thunk.el is that thunks are just bare lambdas, so there is no way to get rid it "from the inside", as it were. Whereas for streams, it's just a matter of list editing. Some additional things that I thought of changing, but I didn't yet: - stream--identifier vs just using '--stream-- directly, I don't see what's the benefit of indirection here. - stream-make should use cons instead of list (or maybe a struct?). - stream-empty should just be a constant. ^ permalink raw reply related [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2019-04-25 3:20 ` Noam Postavsky @ 2019-04-25 5:19 ` Michael Heerdegen 2019-05-10 13:20 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2019-04-25 5:19 UTC (permalink / raw) To: Noam Postavsky; +Cc: Nicolas Petton, 30626 Noam Postavsky <npostavs@gmail.com> writes: > Coming back to this again. I think I got lost in the weeds of the > byte-code function objects before. The core problem is that streams > are not exactly encoded like the above, because even after forcing it > you don't have just a plain SECOND-VALUE stored in the stream. The > original FUNCTION-TO-PRODUCE-MORE-REST-OF-LIST stays around and keeps > referencing all the code and all the following elements. So a > possible solution is change the stream to get rid of the lambda part > and just leave the computed value after it's forced. With the > following patch (stream-flush (stream-range 1 1000000)) succeeds: > > [Patch...] Works for me, and it makes sense. As a test case I recompiled el-search.el (it uses streams for several things) with your patch applied to stream.el, and it worked well. > Some additional things that I thought of changing, but I didn't yet: > - stream--identifier vs just using '--stream-- directly, I don't see > what's the benefit of indirection here. A matter of taste I guess. > - stream-make should use cons instead of list (or maybe a struct?). I think cons would be ok. Would a struct make things slower? > - stream-empty should just be a constant. Dunno if there are cases where this would be problematic, but I guess we could do this as well. Anyway, thanks for looking into this again, I like your solution. Maybe Nicolas can also chime in. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2019-04-25 5:19 ` Michael Heerdegen @ 2019-05-10 13:20 ` Michael Heerdegen 2019-05-25 20:29 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2019-05-10 13:20 UTC (permalink / raw) To: Noam Postavsky; +Cc: Nicolas Petton, 30626 Michael Heerdegen <michael_heerdegen@web.de> writes: > > [Patch...] > > Works for me, and it makes sense. As a test case I recompiled > el-search.el (it uses streams for several things) with your patch > applied to stream.el, and it worked well. @Nicolas: If you are short on time, can we just install this patch? I've tested it for a while and it works well, and I'm quite sure it is harmless (doesn't change any semantics apart from fixing the crashes). > > - stream-make should use cons instead of list (or maybe a struct?). > > I think cons would be ok. Would a struct make things slower? > > > - stream-empty should just be a constant. > > Dunno if there are cases where this would be problematic, but I guess we > could do this as well. @Nicolas: Do you want us to care about this or do you want to have a look yourself? I don't want to hurry, I just don't want this to be forgotten. If you say you have time in four months, it's still ok. Thanks, Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2019-05-10 13:20 ` Michael Heerdegen @ 2019-05-25 20:29 ` Noam Postavsky 2019-05-26 0:32 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2019-05-25 20:29 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Nicolas Petton, 30626 [-- Attachment #1: Type: text/plain, Size: 2457 bytes --] tags 30626 + patch quit Michael Heerdegen <michael_heerdegen@web.de> writes: >> > - stream-make should use cons instead of list (or maybe a struct?). >> >> I think cons would be ok. Would a struct make things slower? A struct might be slower, and cons has the advantage that the print output is more readable for humans too. E.g., with this code: (let ((s (stream-range 1 5))) (stream-flush s) s) ;; Using cons (patch in this message): (--stream-evald-- 1 --stream-evald-- 2 --stream-evald-- 3 --stream-evald-- 4 --stream-evald--) ;; Using list (previous patch): (--stream-evald-- (1 --stream-evald-- (2 --stream-evald-- (3 --stream-evald-- (4 --stream-evald-- nil))))) ;; I guess using a struct would look something like this: #(--stream-evald-- (1 . #(--stream-evald-- (2 . #(--stream-evald-- (3 . #(--stream-evald-- (4 . #(--stream-evald-- nil))))))))) ;; Using list with thunk (current, v2.2.4) (--stream-- #[256 "\211\203\007\0\303\242\207\303\242\204 \0\304\300\242\305\300\242\302\242\\\301\302\242#B\240\210\303\306\240\210\304\242\207" [(1) 5 (1) (t) ((1 --stream-- #[256 "\211\203\007\0\303\242\207\303\242\204 \0\304\300\242\305\300\242\302\242\\\301\302\242#B\240\210\303\306\240\210\304\242\207" [(2) 5 (1) (t) ((2 --stream-- #[256 "\211\203\007\0\303\242\207\303\242\204 \0\304\300\242\305\300\242\302\242\\\301\302\242#B\240\210\303\306\240\210\304\242\207" [(3) 5 (1) (t) ((3 --stream-- #[256 "\211\203\007\0\303\242\207\303\242\204 \0\304\300\242\305\300\242\302\242\\\301\302\242#B\240\210\303\306\240\210\304\242\207" [(4) 5 (1) (t) ((4 --stream-- #[256 "\211\203\007\0\300\242\207\300\242\204\024\0\301\302\240\210\300\303\240\210\301\242\207" [(t) (nil) nil t] 3 " (fn &optional CHECK)"])) stream-range t] 7 " (fn &optional CHECK)"])) stream-range t] 7 " (fn &optional CHECK)"])) stream-range t] 7 " (fn &optional CHECK)"])) stream-range t] 7 " (fn &optional CHECK)"]) >> > - stream-empty should just be a constant. >> >> Dunno if there are cases where this would be problematic, but I guess we >> could do this as well. I've done this in the patch below. Passes all the tests, and I can't see why it would be problematic. > @Nicolas: Do you want us to care about this or do you want to have a > look yourself? I don't want to hurry, I just don't want this to be > forgotten. If you say you have time in four months, it's still ok. Not getting any response; I'll wait another week for comments and then push. [-- Attachment #2: patch --] [-- Type: text/plain, Size: 5752 bytes --] From 7b126616c87bf034c933de711befcd80a7ada3bb Mon Sep 17 00:00:00 2001 From: Noam Postavsky <npostavs@users.sourceforge.net> Date: Wed, 24 Apr 2019 22:51:19 -0400 Subject: [PATCH] Drop forced lambda's from stream (Bug#30626) Let the stream id distinguish between forced and unforced stream values. When the value is forced, replace the lambda with its result. This lets the lambda and anything it references be garbage collected. Change the representation of a stream from (--stream-- THUNK) to (--stream-fresh-- . (lambda () VALUE)) or (--stream-evald . VALUE). * packages/stream/stream.el (stream--identifier): Remove. (stream--fresh-identifier, stream--evald-identifier): New constants to replace it. (streamp): Check for new constants. (stream-make): Use cons and lambda instead of list and thunk-delay. (stream--force): New function. (stream-empty-p, stream-first, stream-rest): Use it. (stream-empty): New constant, return it from the function instead of creating a new one each time. * packages/stream/tests/stream-tests.el (stream-to-list): Remove. (stream-list-test): Use seq-into instead. --- packages/stream/stream.el | 41 +++++++++++++++++++++++++---------- packages/stream/tests/stream-tests.el | 12 ++-------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/packages/stream/stream.el b/packages/stream/stream.el index 3f6bc4b5b..9f73e8b86 100644 --- a/packages/stream/stream.el +++ b/packages/stream/stream.el @@ -1,6 +1,6 @@ ;;; stream.el --- Implementation of streams -*- lexical-binding: t -*- -;; Copyright (C) 2016 Free Software Foundation, Inc. +;; Copyright (C) 2016-2019 Free Software Foundation, Inc. ;; Author: Nicolas Petton <nicolas@petton.fr> ;; Keywords: stream, laziness, sequences @@ -41,7 +41,7 @@ ;; - ... ;; ;; All functions are prefixed with "stream-". -;; All functions are tested in test/automated/stream-tests.el +;; All functions are tested in tests/stream-tests.el ;; ;; Here is an example implementation of the Fibonacci numbers ;; implemented as in infinite stream: @@ -65,18 +65,30 @@ (eval-when-compile (require 'cl-lib)) (require 'seq) -(require 'thunk) (eval-and-compile - (defconst stream--identifier '--stream-- - "Symbol internally used to identify streams.")) + (defconst stream--fresh-identifier '--stream-fresh-- + "Symbol internally used to streams whose head was not evaluated.") + (defconst stream--evald-identifier '--stream-evald-- + "Symbol internally used to streams whose head was evaluated.")) (defmacro stream-make (&rest body) "Return a stream built from BODY. BODY must return nil or a cons cell whose cdr is itself a stream." (declare (debug t)) - `(list ',stream--identifier (thunk-delay ,@body))) + `(cons ',stream--fresh-identifier (lambda () ,@body))) + +(defun stream--force (stream) + "Evaluate and return the first cons cell of STREAM. +That value is the one passed to `stream-make'." + (cond + ((eq (car-safe stream) stream--evald-identifier) + (cdr stream)) + ((eq (car-safe stream) stream--fresh-identifier) + (setf (car stream) stream--evald-identifier) + (setf (cdr stream) (funcall (cdr stream)))) + (t (signal 'wrong-type-argument (list 'streamp stream))))) (defmacro stream-cons (first rest) "Return a stream built from the cons of FIRST and REST. @@ -159,24 +171,29 @@ (defun stream-range (&optional start end step) (defun streamp (stream) "Return non-nil if STREAM is a stream, nil otherwise." - (eq (car-safe stream) stream--identifier)) + (let ((car (car-safe stream))) + (or (eq car stream--fresh-identifier) + (eq car stream--evald-identifier)))) + +(defconst stream-empty (cons stream--evald-identifier nil) + "The empty stream.") (defun stream-empty () - "Return a new empty stream." - (list stream--identifier (thunk-delay nil))) + "Return the empty stream." + stream-empty) (defun stream-empty-p (stream) "Return non-nil if STREAM is empty, nil otherwise." - (null (thunk-force (cadr stream)))) + (null (cdr (stream--force stream)))) (defun stream-first (stream) "Return the first element of STREAM. Return nil if STREAM is empty." - (car (thunk-force (cadr stream)))) + (car (stream--force stream))) (defun stream-rest (stream) "Return a stream of all but the first element of STREAM." - (or (cdr (thunk-force (cadr stream))) + (or (cdr (stream--force stream)) (stream-empty))) (defun stream-append (&rest streams) diff --git a/packages/stream/tests/stream-tests.el b/packages/stream/tests/stream-tests.el index 021ed65cf..7487ef69b 100644 --- a/packages/stream/tests/stream-tests.el +++ b/packages/stream/tests/stream-tests.el @@ -1,6 +1,6 @@ ;;; stream-tests.el --- Unit tests for stream.el -*- lexical-binding: t -*- -;; Copyright (C) 2015, 2017 Free Software Foundation, Inc. +;; Copyright (C) 2015, 2017-2019 Free Software Foundation, Inc. ;; Author: Nicolas Petton <nicolas@petton.fr> @@ -29,14 +29,6 @@ (require 'stream) (require 'generator) (require 'cl-lib) -(defun stream-to-list (stream) - "Eagerly traverse STREAM and return a list of its elements." - (let (result) - (seq-do (lambda (elt) - (push elt result)) - stream) - (reverse result))) - (ert-deftest stream-empty-test () (should (streamp (stream-empty))) (should (stream-empty-p (stream-empty)))) @@ -240,7 +232,7 @@ (ert-deftest stream-range-test () (ert-deftest stream-list-test () (dolist (list '(nil '(1 2 3) '(a . b))) - (should (equal list (stream-to-list (stream list)))))) + (should (equal list (seq-into (stream list) 'list))))) (ert-deftest stream-seq-subseq-test () (should (stream-empty-p (seq-subseq (stream-range 2 10) 0 0))) -- 2.11.0 ^ permalink raw reply related [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2019-05-25 20:29 ` Noam Postavsky @ 2019-05-26 0:32 ` Michael Heerdegen 2019-05-26 0:40 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2019-05-26 0:32 UTC (permalink / raw) To: Noam Postavsky; +Cc: Nicolas Petton, 30626 Noam Postavsky <npostavs@gmail.com> writes: > >> > - stream-make should use cons instead of list (or maybe a struct?). > >> > >> I think cons would be ok. Would a struct make things slower? > > A struct might be slower, and cons has the advantage that the print > output is more readable for humans too. E.g., with this code: [...] I see no reason not to switch to cons. Better readable, and less cons garbage than with `list'. Would you like to do this? > >> > - stream-empty should just be a constant. > >> > >> Dunno if there are cases where this would be problematic, but I > >> guess we > >> could do this as well. > > I've done this in the patch below. Passes all the tests, and I can't > see why it would be problematic. Looks good to me. Also passes my tests (which are all my stream.el uses, including el-search.el). > > @Nicolas: Do you want us to care about this or do you want to have a > > look yourself? I don't want to hurry, I just don't want this to be > > forgotten. If you say you have time in four months, it's still ok. > > Not getting any response; I'll wait another week for comments and then > push. Ok, let's do this. Thanks, Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2019-05-26 0:32 ` Michael Heerdegen @ 2019-05-26 0:40 ` Noam Postavsky 2019-05-26 1:15 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2019-05-26 0:40 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Nicolas Petton, 30626 Michael Heerdegen <michael_heerdegen@web.de> writes: > I see no reason not to switch to cons. Better readable, and less cons > garbage than with `list'. > > Would you like to do this? Yes, just to be clear, the patch in my previous message did already include the switch to cons. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2019-05-26 0:40 ` Noam Postavsky @ 2019-05-26 1:15 ` Michael Heerdegen 2019-06-04 0:26 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2019-05-26 1:15 UTC (permalink / raw) To: Noam Postavsky; +Cc: Nicolas Petton, 30626 Noam Postavsky <npostavs@gmail.com> writes: > Yes, just to be clear, the patch in my previous message did already > include the switch to cons. Ah - of course - sorry, I was already a bit tired, I read it but wasn't aware of it. Sorry, I had spent the time finding a bug in your patch that turned out was just my oversight of some file to recompile. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2019-05-26 1:15 ` Michael Heerdegen @ 2019-06-04 0:26 ` Noam Postavsky 0 siblings, 0 replies; 253+ messages in thread From: Noam Postavsky @ 2019-06-04 0:26 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Nicolas Petton, 30626 tags 30626 fixed close 30626 quit Pushed to elpa. b5f4061db 2019-06-03T20:23:03-04:00 "Drop forced lambda's from stream (Bug#30626)" https://git.savannah.gnu.org/cgit/emacs/elpa.git/commit/?id=b5f4061db4226d1d49fcb0ff53db0424f359e344 > I had spent the time finding a bug in your patch that turned out was > just my oversight of some file to recompile. Oh, I hate it when that happens. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 18:08 ` Eli Zaretskii 2018-02-28 1:29 ` Noam Postavsky @ 2018-02-28 11:05 ` Michael Heerdegen 2018-02-28 13:20 ` Nicolas Petton 2018-03-01 10:44 ` Daniel Colascione 2018-03-01 23:22 ` Let's make the GC safe and iterative (Was: Re: bug#30626) Daniel Colascione 3 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-02-28 11:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: nicolas, 30626 Hello, I had written that > > (seq-doseq (_ (stream-range 1 1000000)) nil) crashes. CC'ing Nicolas, the author of stream.el. > What can we do instead in such cases? Stack-overflow protection > cannot work in GC, so you are shooting yourself in the foot by > creating such large recursive structures. By the time we get to GC, > where the problem will happen, it's too late, because the memory was > already allocated. > > Does anyone has a reasonable idea for avoiding the crash in such > programs? I would appreciate any effort to fix that, because it seems that currently streams are broken by design, and there is no way to fix that from the Lisp implementation. Yes, we could implement iterators instead of streams - that's what we get when we avoid the consing. But it's something different and not always an alternative, depending on what you want to do. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-28 11:05 ` Michael Heerdegen @ 2018-02-28 13:20 ` Nicolas Petton 0 siblings, 0 replies; 253+ messages in thread From: Nicolas Petton @ 2018-02-28 13:20 UTC (permalink / raw) To: Michael Heerdegen, Eli Zaretskii; +Cc: 30626 [-- Attachment #1: Type: text/plain, Size: 239 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: > Hello, Hi, > I had written that > >> > (seq-doseq (_ (stream-range 1 1000000)) nil) > > crashes. CC'ing Nicolas, the author of stream.el. Thanks, I'll look into it. Cheers, Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 18:08 ` Eli Zaretskii 2018-02-28 1:29 ` Noam Postavsky 2018-02-28 11:05 ` Michael Heerdegen @ 2018-03-01 10:44 ` Daniel Colascione 2018-03-01 15:51 ` Noam Postavsky 2018-03-01 23:22 ` Let's make the GC safe and iterative (Was: Re: bug#30626) Daniel Colascione 3 siblings, 1 reply; 253+ messages in thread From: Daniel Colascione @ 2018-03-01 10:44 UTC (permalink / raw) To: Eli Zaretskii, Michael Heerdegen; +Cc: 30626 On 02/27/2018 10:08 AM, Eli Zaretskii wrote: >> From: Michael Heerdegen <michael_heerdegen@web.de> >> Cc: bug-gnu-emacs@gnu.org, 30626@debbugs.gnu.org >> Date: Tue, 27 Feb 2018 13:08:59 +0100 >> >> #+begin_src emacs-lisp >> (seq-doseq (_ (stream-range 1 1000000)) nil) >> #+end_src >> >> Note that this is executed as a loop due how to streams are implemented, >> although the definition of `seq-doseq' looks recursive. But it seems >> that gc has a problem with the large number of conses created when >> processing that. > > What can we do instead in such cases? Stack-overflow protection > cannot work in GC, so you are shooting yourself in the foot by > creating such large recursive structures. By the time we get to GC, > where the problem will happen, it's too late, because the memory was > already allocated. > > Does anyone has a reasonable idea for avoiding the crash in such > programs? We need to fix GC being deeply recursive once and for all. Tweaking stack sizes on various platforms and trying to spot-fix GC for the occasional deeply recursive structure is annoying. Here's my proposal: Turn garbage_collect_1 into a queue-draining loop, initializing the object queue with the GC roots before draining it. We'll make mark_object put an object on this queue, turning the existing mark_object code into a mark_queued_object function. garbage_collect_1 will just call mark_queued_object in a loop; mark_queued_object can call mark_object, but since mark_object just enqueues an object and doesn't recurse, we can't exhaust the stack with deep object graphs. (We'll repurpose the mark bit to mean that the object is on the to-mark queue; by the time we fully drain the queue, just before we sweep, the mark bit will have the same meaning it does now.) We can't allocate memory to hold the queue during GC, so we'll have to pre-allocate it. We can implement the queue as a list of queue blocks, where each queue block is an array of 16k or so Lisp_Objects. During allocation, we'll just make sure we have one Lisp_Object queue-block slot for every non-self-representing Lisp object we allocate. Since we know that we'll have enough queue blocks for the worst GC case, we can have mark_object pull queue blocks from a free list, aborting if for some reason it ever runs out of queue blocks. (The previous paragraph guarantees we won't.) garbage_collect_1 will churn through these heap blocks and place each back on the free list after it's called mark_queued_object on every Lisp_Object in the queue block. In this way, in non-pathological cases of GC, we'll end up using the same few queue blocks over and over. That's a nice optimization, because we can MADV_DONTNEED unused queue blocks so the OS doesn't actually have to remember their contents. In this way, I think we can make the current GC model recursion-proof without drastically changing how we allocate Lisp objects. The additional memory requirements should be modest: it's basically one Lisp_Object per Lisp object allocated. The naive version of this scheme needs about 4.6MB of overhead on my current 20MB Emacs heap, but it should be possible to reduce the overhead significantly by taking advantage of the block allocation we do for conses and other types --- we can put whole blocks on the queue instead of pointers to individual block parts, so we can get away with a much smaller queue. Under this approach, the reserved-queue-block scheme would impose an overhead of somewhere around 1MB on the same heap. This amount of overhead seems reasonable. We may end up actually using less memory that we would for recursive mark_object stack invocation. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-01 10:44 ` Daniel Colascione @ 2018-03-01 15:51 ` Noam Postavsky 2018-03-01 16:54 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-01 15:51 UTC (permalink / raw) To: Daniel Colascione; +Cc: Michael Heerdegen, 30626 On Thu, Mar 1, 2018 at 5:44 AM, Daniel Colascione <dancol@dancol.org> wrote: > We need to fix GC being deeply recursive once and for all. Tweaking stack > sizes on various platforms and trying to spot-fix GC for the occasional > deeply recursive structure is annoying. Agreed, but could you please open a new thread for it? AFAICT, this bug thread is about streams.el functions producing structures proportional in size to the length of the entire stream, which is a bug in itself, regardless of whether or not the GC can handle the result. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-01 15:51 ` Noam Postavsky @ 2018-03-01 16:54 ` Michael Heerdegen 2018-03-01 17:15 ` Noam Postavsky 0 siblings, 1 reply; 253+ messages in thread From: Michael Heerdegen @ 2018-03-01 16:54 UTC (permalink / raw) To: Noam Postavsky; +Cc: 30626 Noam Postavsky <npostavs@gmail.com> writes: > Agreed, but could you please open a new thread for it? AFAICT, this > bug thread is about streams.el functions producing structures > proportional in size to the length of the entire stream, which is a > bug in itself, regardless of whether or not the GC can handle the > result. No, it is a feature: we want streams to produce these structures, streams are delayed lists, not just iterators. Lists are also potentially unlimited nested conses, and that's not a bug. Streams are the same realized with delayed conses. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-01 16:54 ` Michael Heerdegen @ 2018-03-01 17:15 ` Noam Postavsky 2018-03-02 7:08 ` Michael Heerdegen 0 siblings, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-01 17:15 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30626 On Thu, Mar 1, 2018 at 11:54 AM, Michael Heerdegen <michael_heerdegen@web.de> wrote: > Noam Postavsky <npostavs@gmail.com> writes: > >> Agreed, but could you please open a new thread for it? AFAICT, this >> bug thread is about streams.el functions producing structures >> proportional in size to the length of the entire stream, which is a >> bug in itself, regardless of whether or not the GC can handle the >> result. > > No, it is a feature: we want streams to produce these structures, > streams are delayed lists, not just iterators. Lists are also > potentially unlimited nested conses, and that's not a bug. Streams are > the same realized with delayed conses. Maybe I've misunderstood, but is it not the case that iterating over (stream-range 1 n) should require only a constant amount of memory, regardless of the value of n? ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-01 17:15 ` Noam Postavsky @ 2018-03-02 7:08 ` Michael Heerdegen 2018-03-02 13:01 ` Noam Postavsky 2018-03-02 13:04 ` Michael Heerdegen 0 siblings, 2 replies; 253+ messages in thread From: Michael Heerdegen @ 2018-03-02 7:08 UTC (permalink / raw) To: Noam Postavsky; +Cc: 30626 Noam Postavsky <npostavs@gmail.com> writes: > Maybe I've misunderstood, but is it not the case that iterating over > (stream-range 1 n) should require only a constant amount of memory, > regardless of the value of n? Depends on your definition of `require'. Like, for example, (dolist (i 1000000) (message "%S" (cons i (1+ i)))) each iteration step creates and discards a new cons (or a constant number of conses). Not a exceptional thing in Lisp. When iterating over (stream-range 1 n), the garbage collector seems to have problems with how the garbage is structured. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 7:08 ` Michael Heerdegen @ 2018-03-02 13:01 ` Noam Postavsky 2018-03-02 13:13 ` Michael Heerdegen 2018-03-02 13:04 ` Michael Heerdegen 1 sibling, 1 reply; 253+ messages in thread From: Noam Postavsky @ 2018-03-02 13:01 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30626 Michael Heerdegen <michael_heerdegen@web.de> writes: > Noam Postavsky <npostavs@gmail.com> writes: > >> Maybe I've misunderstood, but is it not the case that iterating over >> (stream-range 1 n) should require only a constant amount of memory, >> regardless of the value of n? > > Depends on your definition of `require'. Like, for example, > > (dolist (i 1000000) (message "%S" (cons i (1+ i)))) > > each iteration step creates and discards a new cons (or a constant > number of conses). Not a exceptional thing in Lisp. When iterating > over (stream-range 1 n), the garbage collector seems to have problems > with how the garbage is structured. Ah, so let me be more precise. Iterating over (stream-range 1 n) should require only a constant amount of *reachable* memory at any particular instant. So your example above is okay, but the following one would be not acceptable (I mean, it's fine if some random lisp code does that, but stream-range should not be creating such long lists, or equivalently large structures): (let ((list nil)) (dotimes (i 1000000) (push i list) (message "%S" (car list)))) ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 13:01 ` Noam Postavsky @ 2018-03-02 13:13 ` Michael Heerdegen 0 siblings, 0 replies; 253+ messages in thread From: Michael Heerdegen @ 2018-03-02 13:13 UTC (permalink / raw) To: Noam Postavsky; +Cc: 30626 Noam Postavsky <npostavs@gmail.com> writes: > Ah, so let me be more precise. Iterating over (stream-range 1 n) should > require only a constant amount of *reachable* memory at any particular > instant. So your example above is okay, but the following one would be > not acceptable (I mean, it's fine if some random lisp code does that, > but stream-range should not be creating such long lists, or equivalently > large structures): > > (let ((list nil)) > (dotimes (i 1000000) > (push i list) > (message "%S" (car list)))) Yes, absolutely agreed. Using streams, you can logically refer to the complete list of elements as one object, but the programmer must ensure that the referable list of generated elements doesn't get too large. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-03-02 7:08 ` Michael Heerdegen 2018-03-02 13:01 ` Noam Postavsky @ 2018-03-02 13:04 ` Michael Heerdegen 1 sibling, 0 replies; 253+ messages in thread From: Michael Heerdegen @ 2018-03-02 13:04 UTC (permalink / raw) To: Noam Postavsky; +Cc: 30626 Michael Heerdegen <michael_heerdegen@web.de> writes: > Noam Postavsky <npostavs@gmail.com> writes: > > > Maybe I've misunderstood, but is it not the case that iterating over > > (stream-range 1 n) should require only a constant amount of memory, > > regardless of the value of n? But in this regard, we have a problem with how lexical-binding is implemented for interpreted code. Nested thunks (as implemented in "thunk.el") accumulate useless variable bindings - e.g. (defun test () (thunk-force (thunk-delay (thunk-force (thunk-delay (thunk-force (thunk-delay (lambda () 1)))))))) (test) ==> #1=(closure ((check) (#:val . #1#) (#:forced . t) (check) (#:val . #1#) (#:forced . t) (check) (#:val . #1#) (#:forced . t) t) nil 1) The length of the variable list is equivalent to the number of thunk wrappers. I believe that these useless variable lists are responsible for the crashes of the uncompiled versions of the test files I had posted. I think this problem is different from the gc issue. Streams use nested thunks. Of course does thunk.el not explicitly add such variable lists to the result - this is how closures are built in interpreted code. For nested thunks these just add up. BTW, if you byte-compile the above `test' function, then (disassemble (test)) ==> byte code: args: nil 0 constant 1 1 return and this problem is gone. Michael. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Let's make the GC safe and iterative (Was: Re: bug#30626) 2018-02-27 18:08 ` Eli Zaretskii ` (2 preceding siblings ...) 2018-03-01 10:44 ` Daniel Colascione @ 2018-03-01 23:22 ` Daniel Colascione 2018-03-01 23:29 ` Paul Eggert 2018-03-01 23:38 ` Let's make the GC safe and iterative Stefan Monnier 3 siblings, 2 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-01 23:22 UTC (permalink / raw) To: Emacs developers Noam mentioned that I should make a new thread for this proposal, so I'm posting an edited version of my original message. tl;dr: we should be able to make the GC non-recursive with minimal overhead, solving the "Emacs crashed because we ran out of stack space in GC" problem once and for all. On 02/27/2018 10:08 AM, Eli Zaretskii wrote: > What can we do instead in such cases? Stack-overflow protection > cannot work in GC, so you are shooting yourself in the foot by > creating such large recursive structures. By the time we get to GC, > where the problem will happen, it's too late, because the memory was > already allocated. > > Does anyone has a reasonable idea for avoiding the crash in such > programs? We need to fix GC being deeply recursive once and for all. Tweaking stack sizes on various platforms and trying to spot-fix GC for the occasional deeply recursive structure is annoying. Here's my proposal: I. NAIVE APPROACH Turn garbage_collect_1 into a queue-draining loop, initializing the object queue with the GC roots before draining it. We'll make mark_object put an object on this queue, turning the existing mark_object code into a mark_queued_object function. garbage_collect_1 will just call mark_queued_object in a loop; mark_queued_object can call mark_object, but since mark_object just enqueues an object and doesn't recurse, we can't exhaust the stack with deep object graphs. (We'll repurpose the mark bit to mean that the object is on the to-mark queue; by the time we fully drain the queue, just before we sweep, the mark bit will have the same meaning it does now.) We can't allocate memory to hold the queue during GC, so we'll have to pre-allocate it. We can implement the queue as a list of queue blocks, where each queue block is an array of 16k or so Lisp_Objects. During allocation, we'll just make sure we have one Lisp_Object queue-block slot for every non-self-representing Lisp object we allocate. Since we know that we'll have enough queue blocks for the worst GC case, we can have mark_object pull queue blocks from a free list, aborting if for some reason it ever runs out of queue blocks. (The previous paragraph guarantees we won't.) garbage_collect_1 will churn through these heap blocks and place each back on the free list after it's called mark_queued_object on every Lisp_Object in the queue block. In this way, in non-pathological cases of GC, we'll end up using the same few queue blocks over and over. That's a nice optimization, because we can MADV_DONTNEED unused queue blocks so the OS doesn't actually have to remember their contents. In this way, I think we can make the current GC model recursion-proof without drastically changing how we allocate Lisp objects. The additional memory requirements should be modest: it's basically one Lisp_Object per Lisp object allocated. II. ELABORATION The naive version of this scheme needs about 4.6MB of overhead on my current 20MB Emacs heap, but it should be possible to reduce the overhead significantly by taking advantage of the block allocation we do for conses and other types --- we can put whole blocks on the queue instead of pointers to individual block parts, so we can get away with a much smaller queue. It's also interesting to note that we don't need separate queue blocks to put a block on the queue, as we do if we want to enqueue individual Lisp_Object pointers. Instead, we can add to each block type a pointer to the next block *on the to-be-marked queue* and a bitmask yielding the positions within that block that we want to mark. For example, cons_block right now looks like this: struct cons_block { /* Place `conses' at the beginning, to ease up CONS_INDEX's job. */ struct Lisp_Cons conses[CONS_BLOCK_SIZE]; bits_word gcmarkbits[1 + CONS_BLOCK_SIZE / BITS_PER_BITS_WORD]; struct cons_block *next; }; We'd turn it into something like this: struct cons_block { /* Place `conses' at the beginning, to ease up CONS_INDEX's job. */ struct Lisp_Cons conses[CONS_BLOCK_SIZE]; bits_word gcmarkbits[1 + CONS_BLOCK_SIZE / BITS_PER_BITS_WORD]; bits_word scan_pending[1 + CONS_BLOCK_SIZE / BITS_PER_BITS_WORD]; struct cons_block *next; struct cons_block *next_scan_pending; }; When we call mark_object on a cons, we'll look up its cons_block and look up the cons in gcmarkbits. If we find the cons mark bit set, we're done. Otherwise, we look at the scan_pending bit for the cons cell. If _that's_ set, we're also done. If we find the scan_pending bit unset, however, we set it, and then look at next_scan_pending. If that's non-zero, we know the block as a whole is enqueued for scanning, and we're done. If *that's* zero, then we add the whole block to the to-be-scanned queue. We'll modify garbage_collect_1 to drain both the Lisp_Object queue I described in the last section (which we still need for big objects like buffers) *and* the queue of blocks pending scanning. When we get a cons block, we'll scan all the conses with scan_pending bits set to one, set their gcmarkbits, and remove the cons block from the queue. That same cons block might make it back onto the queue later if someone calls mark_object for one if its conses we didn't already scan, but that's okay. Scanning scan_pending should be very cheap, especially on modern CPUs with bit-prefix-scan instructions. Under this approach, the reserved-queue-block scheme would impose an overhead of somewhere around 1MB on the same heap. (I think it'd actually be a bit smaller actually.) Conses, strings, and vectors are the overwhelming majority of heap-allocated objects, and thanks to block packing, we'd get bookkeeping for them for practically free. This amount of overhead seems reasonable. I think we may end up actually using less memory that we would for recursive mark_object stack invocation. This scheme interacts well with the portable dumper too. pdumper already uses a big bit array to store mark bits; we'd just add another array for its scan_pending. We'd basically treat the entire pdumper region as one big cons_block for GC purposes. What do you think? I think this approach solves a longstanding fiddly problem with Emacs GC without too much disruption to the internals. It also paves the way for concurrent or generational GC if we ever want to implement these features. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Let's make the GC safe and iterative (Was: Re: bug#30626) 2018-03-01 23:22 ` Let's make the GC safe and iterative (Was: Re: bug#30626) Daniel Colascione @ 2018-03-01 23:29 ` Paul Eggert 2018-03-05 6:31 ` Ken Raeburn 2018-03-01 23:38 ` Let's make the GC safe and iterative Stefan Monnier 1 sibling, 1 reply; 253+ messages in thread From: Paul Eggert @ 2018-03-01 23:29 UTC (permalink / raw) To: Daniel Colascione, Emacs developers On 03/01/2018 03:22 PM, Daniel Colascione wrote: > What do you think? Thanks, I like the idea. I suggest implementing the naive version first. Although the more-elaborate versions saves virtual memory, it's not clear that it'd be an overall performance win in the typical case, so my guess is that it's better to start simple. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Let's make the GC safe and iterative (Was: Re: bug#30626) 2018-03-01 23:29 ` Paul Eggert @ 2018-03-05 6:31 ` Ken Raeburn 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman 0 siblings, 1 reply; 253+ messages in thread From: Ken Raeburn @ 2018-03-05 6:31 UTC (permalink / raw) To: Paul Eggert; +Cc: Daniel Colascione, Emacs developers On Mar 1, 2018, at 18:29, Paul Eggert <eggert@cs.ucla.edu> wrote: > On 03/01/2018 03:22 PM, Daniel Colascione wrote: >> What do you think? > > Thanks, I like the idea. I suggest implementing the naive version first. Although the more-elaborate versions saves virtual memory, it's not clear that it'd be an overall performance win in the typical case, so my guess is that it's better to start simple. The more-elaborate version looks like it’s more likely to win on locality of reference as it scans blocks sequentially. That could be significant… especially if anyone is so unfortunate as to still run Emacs on a system small enough that has to page out part of the Lisp memory. I like the second approach a bit better, but either way, getting away from using the C stack sounds like a big improvement. Ken ^ permalink raw reply [flat|nested] 253+ messages in thread
* What improvements would be truly useful? 2018-03-05 6:31 ` Ken Raeburn @ 2018-03-05 13:11 ` Richard Stallman 2018-03-05 14:02 ` John Yates ` (5 more replies) 0 siblings, 6 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-05 13:11 UTC (permalink / raw) To: Ken Raeburn; +Cc: eggert, dancol, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] An improvement in GC wouldn't be a bad thing, but it may not be worth the effort. It is likely to lead to many bugs that would be hard to fix. Once working, it would not make much difference to users. It would only permit some operations on larger problems than now. When I was working at the AI Lab, one of the older programmers told me that hackers are often eager to make improvements of this sort: which make the program better in an abstract sense, but not better for users. I took that advice to heart. Now I pass it on. Changing Emacs to handle indentation and alignment with variable-width fonts would be an important and useful change. Certain kinds of use would make sense, which currently don't. It would be a big step towards making Emacs do the job of a word processor, which is what I would like to see some day. Imagine if you could edit nicely formatted documents directly with Emacs, instead of using LibreOffice? LibreOffice is fine to use, it is free software, but it isn't Emacs. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman @ 2018-03-05 14:02 ` John Yates 2018-03-05 17:21 ` Paul Eggert 2018-03-05 16:33 ` Stefan Monnier ` (4 subsequent siblings) 5 siblings, 1 reply; 253+ messages in thread From: John Yates @ 2018-03-05 14:02 UTC (permalink / raw) To: Richard Stallman Cc: Emacs developers, Ken Raeburn, Daniel Colascione, Paul Eggert Richard, I too had an early mentor impart similar wisdom, possibly around the same that time yours did. Since then I have always tried to keep the end user experience foremost in my work. "Many bugs that would be hard to fix" is not a given. I cannot count the number times I have replaced recursion with iteration. With discipline (no other changes to the algorithm) it is a straight forward conversion. I agree that merely being able to handle large files is not a strong justification. OTOH, in spite of running on a state of the art desktop with 64GB RAM, 4GHz+ multi-core processor and high-end gamer graphics Emacs feels progressively less responsive. Any work countering that trend gets my vote. /john ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 14:02 ` John Yates @ 2018-03-05 17:21 ` Paul Eggert 0 siblings, 0 replies; 253+ messages in thread From: Paul Eggert @ 2018-03-05 17:21 UTC (permalink / raw) To: John Yates, Richard Stallman Cc: Ken Raeburn, Daniel Colascione, Emacs developers On 03/05/2018 06:02 AM, John Yates wrote: > in spite of running on a state of the art > desktop with 64GB RAM, 4GHz+ multi-core processor and high-end gamer > graphics Emacs feels progressively less responsive I'm feeling that on my older work desktop too (8 GiB RAM, 2.6 GHz quad-core, circa-2010 AMD Deneb). However, I suspect it has mostly to do with things other than GC. The main argument to improve GC is robustness, not typical-case performance. We're still installing last-minute hacks into Emacs 26 because of real-world problems here. It would be useful if we didn't have to mess with these hacks because we fixed GC to not blow the C stack. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman 2018-03-05 14:02 ` John Yates @ 2018-03-05 16:33 ` Stefan Monnier 2018-03-05 17:32 ` Rostislav Svoboda ` (3 subsequent siblings) 5 siblings, 0 replies; 253+ messages in thread From: Stefan Monnier @ 2018-03-05 16:33 UTC (permalink / raw) To: emacs-devel > An improvement in GC wouldn't be a bad thing, but it may not be worth > the effort. Making the recursion use an explicitly managed stack should be a fairly simple change, which will fix some crashes. I agree that it's probably not worth trying to be too fancy, but it's really just a bug fix. Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman 2018-03-05 14:02 ` John Yates 2018-03-05 16:33 ` Stefan Monnier @ 2018-03-05 17:32 ` Rostislav Svoboda 2018-03-05 18:04 ` Eli Zaretskii ` (2 more replies) 2018-03-05 17:57 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii ` (2 subsequent siblings) 5 siblings, 3 replies; 253+ messages in thread From: Rostislav Svoboda @ 2018-03-05 17:32 UTC (permalink / raw) To: rms; +Cc: emacs-devel@gnu.org Development, Ken Raeburn, dancol, Paul Eggert > It would be a big step towards making Emacs do the job of > a word processor, which is what I would like to see some day. > Imagine if you could edit nicely formatted documents directly > with Emacs, instead of using LibreOffice? LibreOffice is > fine to use, it is free software, but it isn't Emacs. IMO the future of GUI apps and in our case editors, lies in browser based frameworks programmable by some lisp dialect. For the moment it would be a stack based on electron, clojurescript, codemirror, etc. I know it's a bitter pill to swallow, but let's face it - do we think, our bellowed Emacs will ever be able to display anything like the examples from https://threejs.org ? Bost ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 17:32 ` Rostislav Svoboda @ 2018-03-05 18:04 ` Eli Zaretskii 2018-03-05 19:18 ` Daniel Colascione 2018-03-05 19:05 ` Aaron Ecay 2018-03-05 23:05 ` Richard Stallman 2 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-05 18:04 UTC (permalink / raw) To: Rostislav Svoboda; +Cc: eggert, raeburn, dancol, rms, emacs-devel > From: Rostislav Svoboda <rostislav.svoboda@gmail.com> > Date: Mon, 5 Mar 2018 18:32:06 +0100 > Cc: "emacs-devel@gnu.org Development" <emacs-devel@gnu.org>, > Ken Raeburn <raeburn@raeburn.org>, dancol@dancol.org, > Paul Eggert <eggert@cs.ucla.edu> > > I know it's a bitter pill to swallow, but let's face it - do we think, > our bellowed Emacs will ever be able to display anything like the > examples from https://threejs.org ? Can you display something similar in Office? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 18:04 ` Eli Zaretskii @ 2018-03-05 19:18 ` Daniel Colascione 2018-03-05 20:00 ` Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-05 19:18 UTC (permalink / raw) To: Eli Zaretskii, Rostislav Svoboda; +Cc: eggert, raeburn, rms, emacs-devel On 03/05/2018 10:04 AM, Eli Zaretskii wrote: >> From: Rostislav Svoboda <rostislav.svoboda@gmail.com> >> Date: Mon, 5 Mar 2018 18:32:06 +0100 >> Cc: "emacs-devel@gnu.org Development" <emacs-devel@gnu.org>, >> Ken Raeburn <raeburn@raeburn.org>, dancol@dancol.org, >> Paul Eggert <eggert@cs.ucla.edu> >> >> I know it's a bitter pill to swallow, but let's face it - do we think, >> our bellowed Emacs will ever be able to display anything like the >> examples from https://threejs.org ? It can already, with XEmbed --- same way Office does it, with OLE. :-) It's a nice trick, but I don't think that sort of pretty display helps anyone accomplish a task. Personally, I don't think word processing is a good focus for Emacs. There are two groups of people who want to prepare documents: those who want a WYSIWYG system and those who don't. The former group is well-served by LibreOffice, which is a free and powerful office suite. The latter group is well-served by Emacs with its extensive LaTeX integration. Instead of focusing on areas where we're weak and will realistically never catch up with projects dedicated to the task, we should focus on improving existing strengths. 1) We should be the best editor around for text and program code. There's an opportunity to do much better than the mainstream. Conventional IDE groups put a ton of brute force effort into tuning IDEs for specific coding styles in specific environments. We can be more generic and more flexible, ultimately offering more power and greater efficiency for people willing to invest time into learning the system. a) We should do a better job of integrating interesting ideas like undo-tree, ace-jump-mode, yasnippet, helm, and others into the core and enabling them by default. I don't think we need to be as conservative as we've been historically, and I think there's still a lot of room to improve the core editing mechanics. b) There are long-standing defects that are minor in the scheme of things, but that tend to create a poor impression. In particular, long-line handling is a sore point, as is support for very large files. For long lines: I haven't sufficiently studied what the necessary redisplay hacks would look like. For large files: by moving from a gap buffer to a rope representation for buffers, we can partially use memory-mapped backing storage, and even when we do need private, modifiable memory for editing, we can allocate only when we immediately need and not have to move the gap around through humongous amounts of main memory. Such a system would not only improve our support for humongous files, but would also make a 32-bit Emacs capable of editing files larger than its address space. c) We need a project system. There's been some good work in this area, but there's too much fragmentation, which hinders productive integration. For example, there's no default keybinding to jump, in C++, between an "implementation" and a "header" file, and that's because Emacs by default has no idea what either concept means and there are something like, what, a dozen(?) different ways to teach it the concept. d) We need better fontification and indentation. We don't have good language coverage, and support for more obscure languages is sometimes spotty, limited to fontifying comments, strings, and keywords. Keeping up with language development is a constant struggle, and it's easy to introduce odd bugs, infloops, and so on in ad-hoc parsing code, especially when this code needs to be simultaneously fast, incremental, and error tolerant. I'm now wondering whether the manual approach is wrong. We've been using it along with everyone else, but there might be better options these days. It's a somewhat radical idea: let's use a machine learning model to classify program tokens, then apply manual fontification and indentation rules to the resulting token classifications. We'd train the model by taking labeled program text (say, from Savannah or GitHub, run through a parser), then perturb the program text, rewarding the model for retaining token labels under various editing and truncation operations. In this way, we'd learn an approximate model for understanding even damaged program text without having to manually write a lot of code. Tons and tons of stuff in cc-mode is heuristics for dealing with damaged program text, and I think we could learn this understanding instead. The system is equivalent in power to anything we could write by hand: LSTMs and other systems are Turing-complete. This way, to add support for a new language, you'd just feed Emacs examples. I imagine you might even be able to gently correct the system when it misunderstands and improve the overall accuracy. But it's probably a crazy idea. :-) 2) Startup should be instant in all cases. Now that we have a portable dumper, we should automatically dump the results of user initialization and regenerate the dump when we detect that something's changed. This way, users perceive Emacs as a fast, modern system. I know that the daemon exists and that it's possible to optimize even a customized initialization so that it's fast even without hacks (I do), but users shouldn't have to go to the trouble of this kind of manual setup and tweaking 3) Mobile support. One of Emacs' strengths is its portability, and this portability comes with a much lower footprint than other approaches. Desktop and laptop sales have been declining for six years. There are lots of tools built on Emacs that would be useful (like gnus, org-mode, etc.), except that I can't use them on mobile, which means I end up choosing other tools entirely for these tasks. There is no reason that Emacs couldn't be a good Android citizen. A good Java<->elisp bridge would let us transparently use various system APIs. While we would probably need mobile-specific GUI code (because the plain buffer interface wouldn't be suitable for most tasks, at least without mobile-desktop convergence), all the logic and back-end glue would work on mobile as well as it works anywhere else, greatly simplifying the task of building general-purpose tools like org-mode that really ought to work anywhere. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 19:18 ` Daniel Colascione @ 2018-03-05 20:00 ` Eli Zaretskii 2018-03-05 23:05 ` Richard Stallman 2018-03-06 15:48 ` Dmitry Gutov 2 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-05 20:00 UTC (permalink / raw) To: Daniel Colascione; +Cc: emacs-devel, eggert, raeburn, rostislav.svoboda, rms > From: Daniel Colascione <dancol@dancol.org> > Date: Mon, 5 Mar 2018 11:18:29 -0800 > Cc: eggert@cs.ucla.edu, raeburn@raeburn.org, rms@gnu.org, emacs-devel@gnu.org > > For long lines: I haven't sufficiently studied what the necessary > redisplay hacks would look like. I explained the issues several times, here and elsewhere. I can explain again, if someone's interested. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 19:18 ` Daniel Colascione 2018-03-05 20:00 ` Eli Zaretskii @ 2018-03-05 23:05 ` Richard Stallman 2018-03-05 23:16 ` dancol 2018-03-06 20:01 ` Marcin Borkowski 2018-03-06 15:48 ` Dmitry Gutov 2 siblings, 2 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-05 23:05 UTC (permalink / raw) To: Daniel Colascione; +Cc: eggert, eliz, raeburn, rostislav.svoboda, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > Personally, I don't think word processing is a good focus for Emacs. I want to do my word processing in Emacs, so please stop interfering. You, personally, can work on other areas if that area doesn't interest you. The improvements you suggested for editing programs are also desirable. We want to improve what Emacs can do in editing programs. One of the improvements we need is to have a GNU language server and connect it to Emacs. The best proposal for how to make a GNU language server is to do it by building on GDB. However, Emacs is also meant for editing textual documents. To make that easier, we need more support for editing and saving formatted documents with various fonts. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 23:05 ` Richard Stallman @ 2018-03-05 23:16 ` dancol 2018-03-06 20:54 ` Richard Stallman 2018-03-06 20:01 ` Marcin Borkowski 1 sibling, 1 reply; 253+ messages in thread From: dancol @ 2018-03-05 23:16 UTC (permalink / raw) To: rms Cc: eggert, emacs-devel, raeburn, eliz, Daniel Colascione, rostislav.svoboda > [[[ To any NSA and FBI agents reading my email: please consider ]]] > [[[ whether defending the US Constitution against all enemies, ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > > Personally, I don't think word processing is a good focus for Emacs. > > I want to do my word processing in Emacs, > so please stop interfering. You, personally, can work on other > areas if that area doesn't interest you. You are advocating for your suggested improvements. I am advocating for mine. Neither of us "interfering" with the other. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 23:16 ` dancol @ 2018-03-06 20:54 ` Richard Stallman 2018-03-06 21:15 ` Daniel Colascione 2018-03-08 4:45 ` Stefan Monnier 0 siblings, 2 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-06 20:54 UTC (permalink / raw) To: dancol; +Cc: eggert, emacs-devel, raeburn, eliz, dancol, rostislav.svoboda [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > You are advocating for your suggested improvements. I am advocating for > mine. Emacs is not an independent project, and it isn't governed by its contributors. I'm the head of the GNU Project, and that includes Emacs. You, as a contributor, can advocate a certain decision, which means you present arguments why I should approve it. I don't need to advocate a decision in that sense. I leave most technical decisions up to the contributors, including you, because for most of the questions I don't have any special preference of my own. For those questions, I'm happy with whatever works, and I know the contributors can figure out what works. However, making progress on Emacs as a word processor is one of my specific goals. This is what Emacs needs to do to be useful in all the ways it should be useful. It will only take a few more features to make Emacs start to be useful as a word processor. Once we can do proper formatting of paragraphs with variable-width text, with a few kinds of alignment, and we can save these in files, we will be able to use it for writing letters and handouts, instead of LibreOffice. I am really looking forward to this. LibreOffice is free software, and it's ethical, but it isn't Emacs. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 20:54 ` Richard Stallman @ 2018-03-06 21:15 ` Daniel Colascione 2018-03-08 4:45 ` Stefan Monnier 1 sibling, 0 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-06 21:15 UTC (permalink / raw) To: rms; +Cc: eliz, eggert, raeburn, rostislav.svoboda, emacs-devel On 03/06/2018 12:54 PM, Richard Stallman wrote: > However, making progress on Emacs as a word processor is one of my > specific goals. This is what Emacs needs to do to be useful in all > the ways it should be useful. If you want to add word processing features to Emacs, I suggest implementing the necessary changes features yourself instead of suggesting that discussion of other priorities is somehow "interfering". Code wins arguments. `eval' tends not to work very well when you pass it a block of prose about how Emacs should be a word processor. > It will only take a few more features to make Emacs start to be useful > as a word processor. Once we can do proper formatting of paragraphs > with variable-width text, with a few kinds of alignment, and we can > save these in files, we will be able to use it for writing letters and > handouts, instead of LibreOffice. Sure. It'd be nice if Emacs were suitable for that task. I don't see the urgency, considering that plenty of equally free packages exist. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 20:54 ` Richard Stallman 2018-03-06 21:15 ` Daniel Colascione @ 2018-03-08 4:45 ` Stefan Monnier 2018-03-08 9:16 ` Jefferson Carpenter ` (4 more replies) 1 sibling, 5 replies; 253+ messages in thread From: Stefan Monnier @ 2018-03-08 4:45 UTC (permalink / raw) To: emacs-devel > I am really looking forward to this. LibreOffice is free software, > and it's ethical, but it isn't Emacs. IMO the essence of WYSIWYG makes it "not Emacs". I'd like to be able to usefully edit .odt documents with Emacs, but not in a WYSIWYG fashion. Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 4:45 ` Stefan Monnier @ 2018-03-08 9:16 ` Jefferson Carpenter 2018-03-08 9:17 ` Yuri Khan ` (3 subsequent siblings) 4 siblings, 0 replies; 253+ messages in thread From: Jefferson Carpenter @ 2018-03-08 9:16 UTC (permalink / raw) To: emacs-devel On 3/7/2018 10:45 PM, Stefan Monnier wrote: >> I am really looking forward to this. LibreOffice is free software, >> and it's ethical, but it isn't Emacs. > > IMO the essence of WYSIWYG makes it "not Emacs". I'd like to be able to > usefully edit .odt documents with Emacs, but not in a WYSIWYG fashion. > > > Stefan > > Agreed. I like latex-preview-pane's format of "WYSIWYG" editing. You edit the code in one buffer, and see a rendered preview in another buffer. It is not critical that the preview even be an emacs buffer - it could be another application. Jefferson ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 4:45 ` Stefan Monnier 2018-03-08 9:16 ` Jefferson Carpenter @ 2018-03-08 9:17 ` Yuri Khan 2018-03-08 13:40 ` Eli Zaretskii ` (2 subsequent siblings) 4 siblings, 0 replies; 253+ messages in thread From: Yuri Khan @ 2018-03-08 9:17 UTC (permalink / raw) To: Stefan Monnier; +Cc: Emacs developers On Thu, Mar 8, 2018 at 11:45 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > IMO the essence of WYSIWYG makes it "not Emacs". I'd like to be able to > usefully edit .odt documents with Emacs, but not in a WYSIWYG fashion. I was about to say “you sort-of can, after all, .odt is just XML in zip”. Then I did an (add-to-list 'auto-mode-alist '("\\.odt\\'" . archive-mode)) and opened the first .odt I could find, and oh $(DEITY), it’s horrible. After the first line of xml declaration, the rest of the document is one single physical line. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 4:45 ` Stefan Monnier 2018-03-08 9:16 ` Jefferson Carpenter 2018-03-08 9:17 ` Yuri Khan @ 2018-03-08 13:40 ` Eli Zaretskii 2018-03-08 20:07 ` Richard Stallman 2018-03-08 20:29 ` Marcin Borkowski 4 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-08 13:40 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Wed, 07 Mar 2018 23:45:05 -0500 > > > I am really looking forward to this. LibreOffice is free software, > > and it's ethical, but it isn't Emacs. > > IMO the essence of WYSIWYG makes it "not Emacs". I'd like to be able to > usefully edit .odt documents with Emacs, but not in a WYSIWYG fashion. Emacs being Emacs, no one is forced to use any specific Emacs feature they don't like or want. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 4:45 ` Stefan Monnier ` (2 preceding siblings ...) 2018-03-08 13:40 ` Eli Zaretskii @ 2018-03-08 20:07 ` Richard Stallman 2018-03-08 20:29 ` Marcin Borkowski 4 siblings, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-08 20:07 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > IMO the essence of WYSIWYG makes it "not Emacs". That is shocking but enigmatic; I don't get any point. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 4:45 ` Stefan Monnier ` (3 preceding siblings ...) 2018-03-08 20:07 ` Richard Stallman @ 2018-03-08 20:29 ` Marcin Borkowski 2018-03-09 4:43 ` Stefan Monnier 4 siblings, 1 reply; 253+ messages in thread From: Marcin Borkowski @ 2018-03-08 20:29 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-03-08, at 05:45, Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> I am really looking forward to this. LibreOffice is free software, >> and it's ethical, but it isn't Emacs. > > IMO the essence of WYSIWYG makes it "not Emacs". I'd like to be able to > usefully edit .odt documents with Emacs, but not in a WYSIWYG fashion. Interesting. I have a very similar sentiment, though I think it is quite irrational. Is mu4e, Org-mode, Calc, or dunnet also "not Emacs"? If not, how is it different than a word processor? I'm not mocking you, I just want to understand the sentiment we both share. Best, -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 20:29 ` Marcin Borkowski @ 2018-03-09 4:43 ` Stefan Monnier 2018-03-09 22:20 ` Richard Stallman 2018-03-11 17:02 ` Marcin Borkowski 0 siblings, 2 replies; 253+ messages in thread From: Stefan Monnier @ 2018-03-09 4:43 UTC (permalink / raw) To: Marcin Borkowski; +Cc: emacs-devel > Interesting. I have a very similar sentiment, though I think it is > quite irrational. > Is mu4e, Org-mode, Calc, or dunnet also "not Emacs"? If not, how is it > different than a word processor? I don't think I can clearly pin-point the problem, but I think the issue has to do with hiding information: WYSIWYG hides information, in the sense that there are many different documents with the same visual appearance, so the user needs to *guess* what is the underlying document's structure in order to know what his actions will really do. A typical example is the beginning/end of a bold text which is only implicitly represented by the fact that some text is bold and other isn't, but that doesn't let you easily tell whether a new word inserted between a bold work and a non-bold word will be bold or not. Of course Emacs can also hide information (as text-properties, as invisible text, as data stored in buffer-local variables, ...) but most packages follow a design where as little info as possible is hidden. Indeed, whenever I hide such information, I think it over many times because I know there's a very strong chance that users won't like it. Also when it comes to data that we edit, hiding information either means hiding it as invisible text (which tends to be fiddly, so it's used fairly sparingly), or it implies using a complex procedure to `find` and to `save` the buffer in order to translate between the file contents and the in-buffer contents. This complexity is a strong encouragement not to go down that route. Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 4:43 ` Stefan Monnier @ 2018-03-09 22:20 ` Richard Stallman 2018-03-09 22:42 ` Karl Fogel 2018-03-11 17:02 ` Marcin Borkowski 1 sibling, 1 reply; 253+ messages in thread From: Richard Stallman @ 2018-03-09 22:20 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > Of course Emacs can also hide information (as text-properties, as > invisible text, as data stored in buffer-local variables, ...) but most > packages follow a design where as little info as possible is hidden. > Indeed, whenever I hide such information, I think it over many times > because I know there's a very strong chance that users won't like it. That's a valid point, but WYSIWYG text processing is so desirable that we shouldn't rule it out because of that point. Perhaps Emacs WYSIWYG should have a mode to show the markup and a mode to hide the markup, with a character to toggle between them. Where and how to store the markup data is an independent question. It could be in invisible characters, or in text properties. Or some combination of the two. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 22:20 ` Richard Stallman @ 2018-03-09 22:42 ` Karl Fogel 0 siblings, 0 replies; 253+ messages in thread From: Karl Fogel @ 2018-03-09 22:42 UTC (permalink / raw) To: emacs-devel Richard Stallman <rms@gnu.org> writes: >Perhaps Emacs WYSIWYG should have a mode to show the markup and a mode >to hide the markup, with a character to toggle between them. For what it's worth, the venerable proprietary word processor WordPerfect had this feature (under the name "reveal codes"). The feature was widely used, too. At least, people I knew who normally did not become experts in their software tools nevertheless still still knew about and used "reveal codes" on a regular basis. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 4:43 ` Stefan Monnier 2018-03-09 22:20 ` Richard Stallman @ 2018-03-11 17:02 ` Marcin Borkowski 1 sibling, 0 replies; 253+ messages in thread From: Marcin Borkowski @ 2018-03-11 17:02 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-03-09, at 05:43, Stefan Monnier <monnier@IRO.UMontreal.CA> wrote: >> Interesting. I have a very similar sentiment, though I think it is >> quite irrational. >> Is mu4e, Org-mode, Calc, or dunnet also "not Emacs"? If not, how is it >> different than a word processor? > > I don't think I can clearly pin-point the problem, but I think the issue > has to do with hiding information: WYSIWYG hides information, in the > sense that there are many different documents with the same visual > appearance, so the user needs to *guess* what is the underlying > document's structure in order to know what his actions will really do. > A typical example is the beginning/end of a bold text which is only > implicitly represented by the fact that some text is bold and other > isn't, but that doesn't let you easily tell whether a new word inserted > between a bold work and a non-bold word will be bold or not. > > Of course Emacs can also hide information (as text-properties, as > invisible text, as data stored in buffer-local variables, ...) but most > packages follow a design where as little info as possible is hidden. > Indeed, whenever I hide such information, I think it over many times > because I know there's a very strong chance that users won't like it. > > Also when it comes to data that we edit, hiding information either means > hiding it as invisible text (which tends to be fiddly, so it's used > fairly sparingly), or it implies using a complex procedure to `find` and > to `save` the buffer in order to translate between the file contents and > the in-buffer contents. This complexity is a strong encouragement not > to go down that route. Thanks, Stefan - this is a very good point. I guess you managed to nail it. Best, -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 23:05 ` Richard Stallman 2018-03-05 23:16 ` dancol @ 2018-03-06 20:01 ` Marcin Borkowski 2018-03-06 20:32 ` Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: Marcin Borkowski @ 2018-03-06 20:01 UTC (permalink / raw) To: rms Cc: eggert, emacs-devel, raeburn, eliz, Daniel Colascione, rostislav.svoboda On 2018-03-06, at 00:05, Richard Stallman <rms@gnu.org> wrote: > [[[ To any NSA and FBI agents reading my email: please consider ]]] > [[[ whether defending the US Constitution against all enemies, ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > > Personally, I don't think word processing is a good focus for Emacs. > > I want to do my word processing in Emacs, You already can. Quite a few people do this, using Org-mode or AUCTeX. Let me quote the paper about Emacs for TUGboat I mentioned some time ago. I wrote there this: --8<---------------cut here---------------start------------->8--- Emacs, however, is used by many people to edit texts in human languages (as opposed to computer programs), and has really good support for that task. For instance, while many editors have support for movement by words, Emacs has also movement by sentences. Another feature which is a real time-saver is the series of transpose commands: for instance, transpose-chars swaps the two characters on both sides of the point. There is a whole chapter in the Emacs manual describing commands for dealing with text in human languages. --8<---------------cut here---------------end--------------->8--- One thing that might be nice wrt "word processing" would be making yanking insert spaces at the right places. If you have " ipsum" in your kill ring, and press C-y in this context: "Lorem |dolor sit amet" (where the bar means the point), you end up with "Lorem ipsumdolor sit amet" instead of "Lorem ipsum dolor sit amet". Obvious, but annoying. (I even wrote some code to fix that and I've been using it for a few weeks now, and I didn't notice any problems.) This is the power of Emacs: the ability to write small extensions, helping users with their needs. I think making that easier (e.g., by providing better documentation) is one of the best things to improve Emacs. Don't get me wrong, Emacs has excellent docs. But if you want to start extending it, you are pretty much limited to Robert Chassell's book, which is great, but way too short and elementary. (Disclaimer: I am working on a "next step" Elisp book.) Best, -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 20:01 ` Marcin Borkowski @ 2018-03-06 20:32 ` Eli Zaretskii 2018-03-06 20:41 ` Marcin Borkowski 2018-03-09 10:56 ` Phillip Lord 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 20:32 UTC (permalink / raw) To: Marcin Borkowski Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda > From: Marcin Borkowski <mbork@mbork.pl> > Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, eliz@gnu.org, raeburn@raeburn.org, rostislav.svoboda@gmail.com, emacs-devel@gnu.org > Date: Tue, 06 Mar 2018 21:01:00 +0100 > > > I want to do my word processing in Emacs, > > You already can. Quite a few people do this, using Org-mode or AUCTeX. Are you saying that either of these is a WYSIWYG word processor? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 20:32 ` Eli Zaretskii @ 2018-03-06 20:41 ` Marcin Borkowski 2018-03-07 17:13 ` Eli Zaretskii 2018-03-09 10:56 ` Phillip Lord 1 sibling, 1 reply; 253+ messages in thread From: Marcin Borkowski @ 2018-03-06 20:41 UTC (permalink / raw) To: Eli Zaretskii Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda On 2018-03-06, at 21:32, Eli Zaretskii <eliz@gnu.org> wrote: >> From: Marcin Borkowski <mbork@mbork.pl> >> Cc: Daniel Colascione <dancol@dancol.org>, eggert@cs.ucla.edu, eliz@gnu.org, raeburn@raeburn.org, rostislav.svoboda@gmail.com, emacs-devel@gnu.org >> Date: Tue, 06 Mar 2018 21:01:00 +0100 >> >> > I want to do my word processing in Emacs, >> >> You already can. Quite a few people do this, using Org-mode or AUCTeX. > > Are you saying that either of these is a WYSIWYG word processor? Did Richard mention WYSIWYG word processing or just word processing? Also, AUCTeX with pdf-tools is quite close. On a fast computer, you can run TeX-command-master and TeX-view on an idle timer. Not the same, but close. Best, -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 20:41 ` Marcin Borkowski @ 2018-03-07 17:13 ` Eli Zaretskii 2018-03-07 18:30 ` Marcin Borkowski 2018-03-07 23:00 ` Richard Stallman 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 17:13 UTC (permalink / raw) To: Marcin Borkowski Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda > From: Marcin Borkowski <mbork@mbork.pl> > Cc: rms@gnu.org, dancol@dancol.org, eggert@cs.ucla.edu, raeburn@raeburn.org, rostislav.svoboda@gmail.com, emacs-devel@gnu.org > Date: Tue, 06 Mar 2018 21:41:00 +0100 > > > >> > I want to do my word processing in Emacs, > >> > >> You already can. Quite a few people do this, using Org-mode or AUCTeX. > > > > Are you saying that either of these is a WYSIWYG word processor? > > Did Richard mention WYSIWYG word processing or just word processing? WYSIWYG, of course. Otherwise it would make no sense to talk about indentation with variable-pitch fonts and pixel-level justification. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 17:13 ` Eli Zaretskii @ 2018-03-07 18:30 ` Marcin Borkowski 2018-03-07 19:36 ` Eli Zaretskii 2018-03-07 23:00 ` Richard Stallman 1 sibling, 1 reply; 253+ messages in thread From: Marcin Borkowski @ 2018-03-07 18:30 UTC (permalink / raw) To: Eli Zaretskii Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda On 2018-03-07, at 18:13, Eli Zaretskii <eliz@gnu.org> wrote: >> From: Marcin Borkowski <mbork@mbork.pl> >> Cc: rms@gnu.org, dancol@dancol.org, eggert@cs.ucla.edu, raeburn@raeburn.org, rostislav.svoboda@gmail.com, emacs-devel@gnu.org >> Date: Tue, 06 Mar 2018 21:41:00 +0100 >> >> >> >> > I want to do my word processing in Emacs, >> >> >> >> You already can. Quite a few people do this, using Org-mode or AUCTeX. >> > >> > Are you saying that either of these is a WYSIWYG word processor? >> >> Did Richard mention WYSIWYG word processing or just word processing? > > WYSIWYG, of course. Otherwise it would make no sense to talk about > indentation with variable-pitch fonts and pixel-level justification. Have you ever seen LyX? -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 18:30 ` Marcin Borkowski @ 2018-03-07 19:36 ` Eli Zaretskii 2018-03-07 20:49 ` Marcin Borkowski 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 19:36 UTC (permalink / raw) To: Marcin Borkowski Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda > From: Marcin Borkowski <mbork@mbork.pl> > Cc: rms@gnu.org, dancol@dancol.org, eggert@cs.ucla.edu, raeburn@raeburn.org, rostislav.svoboda@gmail.com, emacs-devel@gnu.org > Date: Wed, 07 Mar 2018 19:30:07 +0100 > > >> > Are you saying that either of these is a WYSIWYG word processor? > >> > >> Did Richard mention WYSIWYG word processing or just word processing? > > > > WYSIWYG, of course. Otherwise it would make no sense to talk about > > indentation with variable-pitch fonts and pixel-level justification. > > Have you ever seen LyX? What would it add to the current discussion? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 19:36 ` Eli Zaretskii @ 2018-03-07 20:49 ` Marcin Borkowski 0 siblings, 0 replies; 253+ messages in thread From: Marcin Borkowski @ 2018-03-07 20:49 UTC (permalink / raw) To: Eli Zaretskii Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda On 2018-03-07, at 20:36, Eli Zaretskii <eliz@gnu.org> wrote: >> From: Marcin Borkowski <mbork@mbork.pl> >> Cc: rms@gnu.org, dancol@dancol.org, eggert@cs.ucla.edu, raeburn@raeburn.org, rostislav.svoboda@gmail.com, emacs-devel@gnu.org >> Date: Wed, 07 Mar 2018 19:30:07 +0100 >> >> >> > Are you saying that either of these is a WYSIWYG word processor? >> >> >> >> Did Richard mention WYSIWYG word processing or just word processing? >> > >> > WYSIWYG, of course. Otherwise it would make no sense to talk about >> > indentation with variable-pitch fonts and pixel-level justification. >> >> Have you ever seen LyX? > > What would it add to the current discussion? Next to nothing, except that variable-pitch fonts and pixel-level justification do not imply WYSIWYG. Personally, I don't care for the idea of having a word processor on top of Emacs, although I admit that it might be interesting. I think the resources to do that could be better spent elsewhere. But if someone wants to do it - I have nothing against it. I might even start to use such an application. Best, -- Marcin Borkowski http://mbork.pl ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 17:13 ` Eli Zaretskii 2018-03-07 18:30 ` Marcin Borkowski @ 2018-03-07 23:00 ` Richard Stallman 1 sibling, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-07 23:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel, raeburn, dancol, rostislav.svoboda [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > Did Richard mention WYSIWYG word processing or just word processing? > WYSIWYG, of course. Otherwise it would make no sense to talk about > indentation with variable-pitch fonts and pixel-level justification. I didn't explicitly say WYSIWYG, because I took that for granted because the other word processors I think of are WYSIWYG. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 20:32 ` Eli Zaretskii 2018-03-06 20:41 ` Marcin Borkowski @ 2018-03-09 10:56 ` Phillip Lord 2018-03-09 13:53 ` Eli Zaretskii 2018-03-09 22:20 ` Richard Stallman 1 sibling, 2 replies; 253+ messages in thread From: Phillip Lord @ 2018-03-09 10:56 UTC (permalink / raw) To: Eli Zaretskii Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda Eli Zaretskii <eliz@gnu.org> writes: >> From: Marcin Borkowski <mbork@mbork.pl> Cc: Daniel Colascione >> <dancol@dancol.org>, eggert@cs.ucla.edu, eliz@gnu.org, >> raeburn@raeburn.org, rostislav.svoboda@gmail.com, emacs-devel@gnu.org >> Date: Tue, 06 Mar 2018 21:01:00 +0100 >> >> > I want to do my word processing in Emacs, >> >> You already can. Quite a few people do this, using Org-mode or AUCTeX. > > Are you saying that either of these is a WYSIWYG word processor? No. But, then Word or LibreOffice are not WYSIWYG either. Both have extensive modal views of the underlying document (web layout, reading mode, outline view). Org-mode is essentially a structure first view of text. AUCTeX with preview-latex is roughly the same thing. So, both of them have strong aspects of modern word-processor. If Emacs were able to turn org-mode into HTML, render that HTML and then make changes to the text of that HTML, then you'd have something close to the modal views. Or something like preview-latex which uses syntax highlighting to provide the WYS aspect but allows you to turn it on and off. How easy this would be to implement, I do not know. Emacs does not have an MVC architecture -- text properties (i.e. visualization) are stored directly with the contents of a buffer, so switching views is clunky or difficult (see my own lentic.el for an example). Phil ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 10:56 ` Phillip Lord @ 2018-03-09 13:53 ` Eli Zaretskii 2018-03-10 16:02 ` Phillip Lord 2018-03-09 22:20 ` Richard Stallman 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-09 13:53 UTC (permalink / raw) To: Phillip Lord; +Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: Marcin Borkowski <mbork@mbork.pl>, eggert@cs.ucla.edu, rms@gnu.org, emacs-devel@gnu.org, raeburn@raeburn.org, dancol@dancol.org, rostislav.svoboda@gmail.com > Date: Fri, 09 Mar 2018 10:56:00 +0000 > > > Are you saying that either of these is a WYSIWYG word processor? > > No. But, then Word or LibreOffice are not WYSIWYG either. This is just a minor semantic issue: let's assume for the purposes of the current discussion that the definition of a WYSIWYG word processor is what the Office word processors do. > Org-mode is essentially a structure first view of text. AUCTeX with > preview-latex is roughly the same thing. So, both of them have strong > aspects of modern word-processor. They both provide the final view of the document only off-line, and that is the crucial difference, for the purposes of this discussion. > If Emacs were able to turn org-mode into HTML, render that HTML and > then make changes to the text of that HTML, then you'd have something > close to the modal views. Or something like preview-latex which uses > syntax highlighting to provide the WYS aspect but allows you to turn it > on and off. Emacs is capable of displaying text with different typefaces, so it isn't clear to me why would we need to go through a translator, such as Org export or LaTeX. > How easy this would be to implement, I do not know. Emacs does not have > an MVC architecture -- text properties (i.e. visualization) are stored > directly with the contents of a buffer, so switching views is clunky or > difficult (see my own lentic.el for an example). Actually, MVC is exactly the Emacs architecture. (And text properties are stored separately from the buffer contents.) I wonder what kind of misunderstanding is at work here. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 13:53 ` Eli Zaretskii @ 2018-03-10 16:02 ` Phillip Lord 2018-03-10 18:56 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Phillip Lord @ 2018-03-10 16:02 UTC (permalink / raw) To: Eli Zaretskii Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda Eli Zaretskii <eliz@gnu.org> writes: >> From: phillip.lord@russet.org.uk (Phillip Lord) >> Cc: Marcin Borkowski <mbork@mbork.pl>, eggert@cs.ucla.edu, >> rms@gnu.org, emacs-devel@gnu.org, raeburn@raeburn.org, >> dancol@dancol.org, rostislav.svoboda@gmail.com >> Date: Fri, 09 Mar 2018 10:56:00 +0000 >> >> > Are you saying that either of these is a WYSIWYG word processor? >> >> No. But, then Word or LibreOffice are not WYSIWYG either. > > This is just a minor semantic issue: let's assume for the purposes of > the current discussion that the definition of a WYSIWYG word processor > is what the Office word processors do. I think it is not. There are many different forms of word-processor out there. Emacs is already one of them, albeit for a specialist user base. >> Org-mode is essentially a structure first view of text. AUCTeX with >> preview-latex is roughly the same thing. So, both of them have strong >> aspects of modern word-processor. > > They both provide the final view of the document only off-line, and > that is the crucial difference, for the purposes of this discussion. Yes, this is most true, although the idea of the "final view" is not quite as clear as it might be. Even for latex, the end product can be more than one thing (PDF and HTML for example). For org-mode, whether the text view is less final than an HTML rendering is an open question. >> If Emacs were able to turn org-mode into HTML, render that HTML and >> then make changes to the text of that HTML, then you'd have something >> close to the modal views. Or something like preview-latex which uses >> syntax highlighting to provide the WYS aspect but allows you to turn it >> on and off. > > Emacs is capable of displaying text with different typefaces, so it > isn't clear to me why would we need to go through a translator, such > as Org export or LaTeX. Oh, because of your notion of WYS. If the "final document" is supposed to be in HTML, then having something that looks the similar, but is never ideal. >> How easy this would be to implement, I do not know. Emacs does not have >> an MVC architecture -- text properties (i.e. visualization) are stored >> directly with the contents of a buffer, so switching views is clunky or >> difficult (see my own lentic.el for an example). > > Actually, MVC is exactly the Emacs architecture. (And text properties > are stored separately from the buffer contents.) I wonder what kind > of misunderstanding is at work here. My understanding of, for indirect buffers, are that they share text and text properties. So you cannot put a different visualisation over two indirect buffers, if those visualisations use text properties, because they will interfere with each other. Perhaps it would be possible to recode indirect buffers so that this were not the case, so that only text were shared. Similarly, the text that you seen on screen is pretty much what is in the buffer. You can do things like put before or after strings in text properties. But then this will be ignored by everything other than the visualisation -- you can't search for them, for instance, because the user level functions operate over the text not the visualisation of it. And, finally, while Emacs does provide notifications of change to buffer text both before and after, they are neither guaranteed to be paired nor consistent. Nor is it apparent to the listening function when they will not be paired or consistent; which is unfortunate as mostly they are. Of course, this is not to say there is no abillity to visualise the same thing twice. You can put a buffer into two windows, with independent mark and point, selection and so forth. But the existence of these things is ephemeral. So, for example, when viewing a single buffer, split the window. Now move point in one window, and then unsplit the window. The location of mark and point in the second window has now been lost. So Emacs does not exactly have an MVC architecture -- it sort of has it. I do not think, for example, it would be straight-forward to produce something like preview-latex where you could see the inline images and equations and latex representation simultaneously and be able to edit either. Phil ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-10 16:02 ` Phillip Lord @ 2018-03-10 18:56 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 18:56 UTC (permalink / raw) To: Phillip Lord; +Cc: eggert, rms, emacs-devel, raeburn, dancol, rostislav.svoboda > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: mbork@mbork.pl, eggert@cs.ucla.edu, rms@gnu.org, emacs-devel@gnu.org, raeburn@raeburn.org, dancol@dancol.org, rostislav.svoboda@gmail.com > Date: Sat, 10 Mar 2018 16:02:14 +0000 > > >> No. But, then Word or LibreOffice are not WYSIWYG either. > > > > This is just a minor semantic issue: let's assume for the purposes of > > the current discussion that the definition of a WYSIWYG word processor > > is what the Office word processors do. > > I think it is not. Like I said, it's a matter of definition. And I just provided mine (and I think also Richard's). > My understanding of, for indirect buffers, are that they share text and > text properties. So you cannot put a different visualisation over two > indirect buffers, if those visualisations use text properties, because > they will interfere with each other. It is not possible with text properties, but it's possible with overlays, which can be window-specific. > Similarly, the text that you seen on screen is pretty much what is in > the buffer. You can do things like put before or after strings in text > properties. But then this will be ignored by everything other than the > visualisation -- you can't search for them, for instance, because the > user level functions operate over the text not the visualisation of it. Since we mostly are talking indentations and typefaces, I don't understand why would we need to use before- or after-strings in this context. > And, finally, while Emacs does provide notifications of change to buffer > text both before and after, they are neither guaranteed to be paired nor > consistent. Nor is it apparent to the listening function when they will > not be paired or consistent; which is unfortunate as mostly they are. Why is that part of the issue? > So Emacs does not exactly have an MVC architecture -- it sort of has it. I think your notion of MVC is too specialized. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 10:56 ` Phillip Lord 2018-03-09 13:53 ` Eli Zaretskii @ 2018-03-09 22:20 ` Richard Stallman 1 sibling, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-09 22:20 UTC (permalink / raw) To: Phillip Lord Cc: eggert, emacs-devel, raeburn, eliz, dancol, rostislav.svoboda [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > If Emacs were able to turn org-mode into HTML, render that HTML and > then make changes to the text of that HTML, then you'd have something > close to the modal views. I don't understand that sentence, but what I have in mind is something that would look and work roughly like LibreOffice. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 19:18 ` Daniel Colascione 2018-03-05 20:00 ` Eli Zaretskii 2018-03-05 23:05 ` Richard Stallman @ 2018-03-06 15:48 ` Dmitry Gutov 2 siblings, 0 replies; 253+ messages in thread From: Dmitry Gutov @ 2018-03-06 15:48 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii, Rostislav Svoboda Cc: eggert, emacs-devel, raeburn, rms On 3/5/18 9:18 PM, Daniel Colascione wrote: >>> I know it's a bitter pill to swallow, but let's face it - do we think, >>> our bellowed Emacs will ever be able to display anything like the >>> examples from https://threejs.org ? > > It can already, with XEmbed --- same way Office does it, with OLE. :-) > It's a nice trick, but I don't think that sort of pretty display helps > anyone accomplish a task. Using the built-in SVG support (a tad more practical feature, IMO), someone can come pretty close as well. > a) We should do a better job of integrating interesting ideas like > undo-tree, ace-jump-mode, yasnippet, helm, and others into the core and > enabling them by default. I don't think we need to be as conservative as > we've been historically, and I think there's still a lot of room to > improve the core editing mechanics. I'm all for undo-tree, but as for the rest, including a particular workflow by default might make it harder to use competing ones (i.e. it's a hard pass for me on Helm). > b) There are long-standing defects that are minor in the scheme of > things, but that tend to create a poor impression. Long lines are annoying. Large files aren't hugely important, IMO (though I've had to deal with a couple over the recent months). > c) We need a project system. project.el? It sorely lacks in contributions (ideas and even rough prototypes are welcome). > There's been some good work in this area, > but there's too much fragmentation, which hinders productive > integration. For example, there's no default keybinding to jump, in C++, > between an "implementation" and a "header" file, and that's because > Emacs by default has no idea what either concept means and there are > something like, what, a dozen(?) different ways to teach it the concept. One difficulty with that is C++ is just one type of project, so adding this kind of command to all projects seems kind of iffy. And yes, arguments for picking between dozens different ways to approach this is the kind of contribution I'm looking for. > d) We need better fontification and indentation. We don't have good > language coverage, and support for more obscure languages is sometimes > spotty, limited to fontifying comments, strings, and keywords. Keeping > up with language development is a constant struggle, and it's easy to > introduce odd bugs, infloops, and so on in ad-hoc parsing code, > especially when this code needs to be simultaneously fast, incremental, > and error tolerant. > > I'm now wondering whether the manual approach is wrong. We've been using > it along with everyone else, but there might be better options these > days. It's a somewhat radical idea: let's use a machine learning model > to classify program tokens, then apply manual fontification and > indentation rules to the resulting token classifications. We'd train the > model by taking labeled program text (say, from Savannah or GitHub, run > through a parser), then perturb the program text, rewarding the model > for retaining token labels under various editing and truncation operations. Err, we can start with fontification based on language specification like Atom/VS Code and Sublime done. They use JSON, but we don't have to. In a way, those specs are harder to read than font-lock code, though. > 3) Mobile support. One of Emacs' strengths is its portability, and this > portability comes with a much lower footprint than other approaches. > Desktop and laptop sales have been declining for six years. There are > lots of tools built on Emacs that would be useful (like gnus, org-mode, > etc.), except that I can't use them on mobile, which means I end up > choosing other tools entirely for these tasks. > > There is no reason that Emacs couldn't be a good Android citizen. A good > Java<->elisp bridge would let us transparently use various system APIs. > While we would probably need mobile-specific GUI code (because the plain > buffer interface wouldn't be suitable for most tasks, at least without > mobile-desktop convergence), all the logic and back-end glue would work > on mobile as well as it works anywhere else, greatly simplifying the > task of building general-purpose tools like org-mode that really ought > to work anywhere. I've been wondering about having Emacs on my phone for a while. It would really need a fitting UI added, though. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 17:32 ` Rostislav Svoboda 2018-03-05 18:04 ` Eli Zaretskii @ 2018-03-05 19:05 ` Aaron Ecay 2018-03-05 20:55 ` Ricardo Wurmus 2018-03-05 23:05 ` Richard Stallman 2 siblings, 1 reply; 253+ messages in thread From: Aaron Ecay @ 2018-03-05 19:05 UTC (permalink / raw) To: Rostislav Svoboda; +Cc: emacs-devel@gnu.org Development 2018ko martxoak 5an, Rostislav Svoboda-ek idatzi zuen: > [...] > I know it's a bitter pill to swallow, but let's face it - do we think, > our bellowed Emacs will ever be able to display anything like the > examples from https://threejs.org ? Thanks to the xwidgets support (info "(elisp) Xwidgets"), it is possible to embed a graphical web browser with full JS support in an emacs buffer. So itʼs possible to have the best of both worlds: emacsʼs support for text editing combined with the visualization and interactivity of modern Javascript libraries. Iʼm sure that there are ways that graphical programming (for lack of a better term) in emacs could be made better, including Richardʼs suggestions that launched this thread. But we should be proud of what we already have, rather than pessimistic. Aaron PS I donʼt know of any projects using three.js support in xwidgets specifically; it could turn out that it doesnʼt quite work (e.g. hardware-accelerated 3D or lack thereof might present an obstacle). But anyone can try it and find out, and hopefully if problems arise figure out how to fix them. -- Aaron Ecay ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 19:05 ` Aaron Ecay @ 2018-03-05 20:55 ` Ricardo Wurmus 0 siblings, 0 replies; 253+ messages in thread From: Ricardo Wurmus @ 2018-03-05 20:55 UTC (permalink / raw) To: Aaron Ecay; +Cc: Rostislav Svoboda, emacs-devel@gnu.org Development Aaron Ecay <aaronecay@gmail.com> writes: > 2018ko martxoak 5an, Rostislav Svoboda-ek idatzi zuen: >> > > [...] > >> I know it's a bitter pill to swallow, but let's face it - do we think, >> our bellowed Emacs will ever be able to display anything like the >> examples from https://threejs.org ? > > Thanks to the xwidgets support (info "(elisp) Xwidgets"), it is possible > to embed a graphical web browser with full JS support in an emacs buffer. > So itʼs possible to have the best of both worlds: emacsʼs support for > text editing combined with the visualization and interactivity of modern > Javascript libraries. Communication with the webkit widget is not easy. It certainly doesn’t feel like a first-class citizen in Emacs. It is possible to send strings containing a JavaScript programme to the webkit widget and retrieve simple strings from the widget, but there is no shared state. All values crossing over the boundary between the Elisp world and the widget need to be converted first. We have no way to compile Elisp to JavaScript strings to smoothen out the rough transition between these two worlds. (Guile supports ECMAscript and Elisp, but even in Guile Emacs the webkit widget would be a foreign body.) While it is a neat hack to embed an X widget in an Emacs buffer, I don’t think that we should be using the embedded webkit widget as a display engine. -- Ricardo GPG: BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC https://elephly.net ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 17:32 ` Rostislav Svoboda 2018-03-05 18:04 ` Eli Zaretskii 2018-03-05 19:05 ` Aaron Ecay @ 2018-03-05 23:05 ` Richard Stallman 2018-03-09 11:02 ` Phillip Lord 2 siblings, 1 reply; 253+ messages in thread From: Richard Stallman @ 2018-03-05 23:05 UTC (permalink / raw) To: Rostislav Svoboda; +Cc: emacs-devel, raeburn, dancol, eggert [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > IMO the future of GUI apps and in our case editors, lies in browser > based frameworks programmable by some lisp dialect. For the moment it > would be a stack based on electron, clojurescript, codemirror, etc. I have a feeling we are talking about totally unrelated questions. I'm talking about extending Emacs to edit more kinds of _documents_. Documents with more and different layout features, but still _documents_. A document is a self-contained file of declarative data that you can display and edit on your computer, without any sort of network connection. And if you send it to me, I can display it too and it looks the same for me as for you. It is crucial for a document to be declarative. It is not safe for an editor to run unrestricted software out of a document. That's why Emacs is careful to make sure documents can't run code. I looked at threejs.org, and it has an array of interesting images which seem to have something to do with Javascript libraries. They may be useful for other purposes, but not for an editor for documents. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 23:05 ` Richard Stallman @ 2018-03-09 11:02 ` Phillip Lord 2018-03-09 22:20 ` Richard Stallman 0 siblings, 1 reply; 253+ messages in thread From: Phillip Lord @ 2018-03-09 11:02 UTC (permalink / raw) To: Richard Stallman; +Cc: eggert, raeburn, dancol, Rostislav Svoboda, emacs-devel Richard Stallman <rms@gnu.org> writes: > [[[ To any NSA and FBI agents reading my email: please consider ]]] > [[[ whether defending the US Constitution against all enemies, ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > > IMO the future of GUI apps and in our case editors, lies in browser > > based frameworks programmable by some lisp dialect. For the moment it > > would be a stack based on electron, clojurescript, codemirror, etc. > > I have a feeling we are talking about totally unrelated questions. > I'm talking about extending Emacs to edit more kinds of _documents_. > Documents with more and different layout features, but still _documents_. > > A document is a self-contained file of declarative data that you can > display and edit on your computer, without any sort of network > connection. And if you send it to me, I can display it too > and it looks the same for me as for you. No, it really isn't. A document is a user-centric feature -- it's a piece of work that stores information in a way that it useful to the user. The self-contained file notion is a developer issue. And, document editing has moved partially (although not wholly) away from the "your computer". People edit documents in editors built entirely on the web. To show it to you, I just send the link. Following your definition, MS Word becomes a document editor and MS Word Online does not. Phil ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 11:02 ` Phillip Lord @ 2018-03-09 22:20 ` Richard Stallman 2018-03-10 20:23 ` Phillip Lord 0 siblings, 1 reply; 253+ messages in thread From: Richard Stallman @ 2018-03-09 22:20 UTC (permalink / raw) To: Phillip Lord; +Cc: eggert, raeburn, dancol, rostislav.svoboda, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > No, it really isn't. A document is a user-centric feature -- it's a > piece of work that stores information in a way that it useful to the > user. I disagree with you there. If something can't be copied to various places and looked at, I say it is not a document. It may be some other kind of thing. > The self-contained file notion is a developer issue. No, it is absolutely crucial to being able to use the document in the ways we are accustomed to use documents. > Following your definition, MS Word becomes a document editor and MS Word > Online does not. I did not state a definition of "document editor" -- it's not part of the point I want to make -- so I think that is a misunderstanding. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-09 22:20 ` Richard Stallman @ 2018-03-10 20:23 ` Phillip Lord 2018-03-11 23:26 ` Richard Stallman 0 siblings, 1 reply; 253+ messages in thread From: Phillip Lord @ 2018-03-10 20:23 UTC (permalink / raw) To: Richard Stallman; +Cc: eggert, raeburn, dancol, rostislav.svoboda, emacs-devel Richard Stallman <rms@gnu.org> writes: > [[[ To any NSA and FBI agents reading my email: please consider ]]] > [[[ whether defending the US Constitution against all enemies, ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > > No, it really isn't. A document is a user-centric feature -- it's a > > piece of work that stores information in a way that it useful to the > > user. > > I disagree with you there. If something can't be copied to various > places and looked at, I say it is not a document. It may be some > other kind of thing. > > > The self-contained file notion is a developer issue. > > No, it is absolutely crucial to being able to use the document > in the ways we are accustomed to use documents. I have to disagree with this. I mean, it was true 10 years ago, but it is not now. > > Following your definition, MS Word becomes a document editor and MS Word > > Online does not. > > I did not state a definition of "document editor" -- it's not part of the point > I want to make -- so I think that is a misunderstanding. No, I think not. Consider this scenario. I start editing some text on google docs with a collaborator; after a while we export the doc into word, share this with Dropbox, then eventually one person takes it over. Is this text really not a document till we download it? All of which gets back what I think was the point of the OP; Emacs would be a better tool if it supported the web. We've been having intense discussions about widget toolkits; what about a web-delivered Emacs? The Web and Mobile together make up the majority of computing these days. http://www.ymacs.org If you want a good example. Phil ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-10 20:23 ` Phillip Lord @ 2018-03-11 23:26 ` Richard Stallman 0 siblings, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-11 23:26 UTC (permalink / raw) To: Phillip Lord; +Cc: emacs-devel, eggert, dancol, raeburn, rostislav.svoboda [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > No, I think not. Consider this scenario. I start editing some text on > google docs with a collaborator; after a while we export the doc into > word, share this with Dropbox, then eventually one person takes it over. > Is this text really not a document till we download it? With all due respect, I think you're disputing a misunderstanding. As far as I know, what people edit with Google Docs is a document. It can be copied to a computer (though doing so requires running nonfree software) and viewed or edited there. Google Docs is a service for storing documents that is designed for editing them using nonfree software. > All of which gets back what I think was the point of the OP; Emacs would > be a better tool if it supported the web. We've been having intense > discussions about widget toolkits; what about a web-delivered Emacs? What exactly would that mean? Could you describe the scenario by giving names or letters to each of the computers involved, and saying what job each computer does? -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation (was: What improvements would be truly useful?) 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman ` (2 preceding siblings ...) 2018-03-05 17:32 ` Rostislav Svoboda @ 2018-03-05 17:57 ` Eli Zaretskii 2018-03-05 19:32 ` dancol 2018-03-05 23:05 ` Variable-width font indentation (was: What improvements would be truly useful?) Richard Stallman 2018-03-05 18:51 ` What improvements would be truly useful? Daniele Nicolodi 2018-03-08 11:44 ` Toon Claes 5 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-05 17:57 UTC (permalink / raw) To: rms; +Cc: emacs-devel, raeburn, dancol, eggert > From: Richard Stallman <rms@gnu.org> > Date: Mon, 05 Mar 2018 08:11:38 -0500 > Cc: eggert@cs.ucla.edu, dancol@dancol.org, emacs-devel@gnu.org > > Changing Emacs to handle indentation and alignment with > variable-width fonts would be an important and useful change. > Certain kinds of use would make sense, which currently don't. This has come up several times, and I think I asked at least once what does it need to entail. It would be helpful to have the answer to that, which will have to be the result of looking at the relevant Lisp code and figuring out which primitives/subroutines will need to be taught fractional column values. Emacs already knows how to align text at pixel resolution (which is easy to express in fractions of the width of the default face's font), and in fact already does so when it displays TAB characters on GUI frames. We have the 'space' display property to do the same with characters other than a TAB. So what else is needed? Can someone who is familiar with indent.el please tell? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation (was: What improvements would be truly useful?) 2018-03-05 17:57 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii @ 2018-03-05 19:32 ` dancol 2018-03-05 19:49 ` Variable-width font indentation Paul Eggert 2018-03-05 19:58 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 2018-03-05 23:05 ` Variable-width font indentation (was: What improvements would be truly useful?) Richard Stallman 1 sibling, 2 replies; 253+ messages in thread From: dancol @ 2018-03-05 19:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, raeburn, dancol, rms, eggert >> From: Richard Stallman <rms@gnu.org> >> Date: Mon, 05 Mar 2018 08:11:38 -0500 >> Cc: eggert@cs.ucla.edu, dancol@dancol.org, emacs-devel@gnu.org >> >> Changing Emacs to handle indentation and alignment with >> variable-width fonts would be an important and useful change. >> Certain kinds of use would make sense, which currently don't. > > This has come up several times, and I think I asked at least once what > does it need to entail. It would be helpful to have the answer to > that, which will have to be the result of looking at the relevant Lisp > code and figuring out which primitives/subroutines will need to be > taught fractional column values. > > Emacs already knows how to align text at pixel resolution (which is > easy to express in fractions of the width of the default face's font), > and in fact already does so when it displays TAB characters on GUI > frames. We have the 'space' display property to do the same with > characters other than a TAB. > > So what else is needed? Can someone who is familiar with indent.el > please tell? Well, say you want to align the following code: 1: void foo(int a, 2: int b) 3: { 4: ... How is any generic indentation system supposed to know that the "i" on line 2 is supposed to line up with the "i" on line 1? You'd need to communicate all indentation intent to the generic system in the form of positions relative to some anchor. (Presumably, it could cache pixel offsets per-line.) While that's doable, it's a ton of work, and I don't think it's worthwhile. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 19:32 ` dancol @ 2018-03-05 19:49 ` Paul Eggert 2018-03-06 15:15 ` Dmitry Gutov 2018-03-05 19:58 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: Paul Eggert @ 2018-03-05 19:49 UTC (permalink / raw) To: dancol, Eli Zaretskii; +Cc: raeburn, rms, emacs-devel On 03/05/2018 11:32 AM, dancol@dancol.org wrote: > 1: void foo(int a, > 2: int b) > 3: { > 4: ... > > How is any generic indentation system supposed to know that the "i" on > line 2 is supposed to line up with the "i" on line 1? It assumes the input is fixed-width, and that leading white space is intended to indent with respect to previous lines. Although it'd be some work to get Emacs to do this, I don't offhand see any algorithmic problem here. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 19:49 ` Variable-width font indentation Paul Eggert @ 2018-03-06 15:15 ` Dmitry Gutov 2018-03-06 15:34 ` Clément Pit-Claudel 2018-03-06 17:09 ` Eli Zaretskii 0 siblings, 2 replies; 253+ messages in thread From: Dmitry Gutov @ 2018-03-06 15:15 UTC (permalink / raw) To: Paul Eggert, dancol, Eli Zaretskii; +Cc: raeburn, rms, emacs-devel On 3/5/18 9:49 PM, Paul Eggert wrote: > On 03/05/2018 11:32 AM, dancol@dancol.org wrote: >> 1: void foo(int a, >> 2: int b) >> 3: { >> 4: ... >> >> How is any generic indentation system supposed to know that the "i" on >> line 2 is supposed to line up with the "i" on line 1? > > It assumes the input is fixed-width, and that leading white space is > intended to indent with respect to previous lines. Although it'd be some > work to get Emacs to do this, I don't offhand see any algorithmic > problem here. If the way whitespace at bol is rendered depends on indentation code, will the mean that while scrolling a buffer the display engine will have to call indentation code? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 15:15 ` Dmitry Gutov @ 2018-03-06 15:34 ` Clément Pit-Claudel 2018-03-06 17:09 ` Eli Zaretskii 1 sibling, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 15:34 UTC (permalink / raw) To: emacs-devel On 2018-03-06 10:15, Dmitry Gutov wrote: > On 3/5/18 9:49 PM, Paul Eggert wrote: >> On 03/05/2018 11:32 AM, dancol@dancol.org wrote: >>> 1: void foo(int a, >>> 2: int b) >>> 3: { >>> 4: ... >>> >>> How is any generic indentation system supposed to know that the "i" on >>> line 2 is supposed to line up with the "i" on line 1? >> >> It assumes the input is fixed-width, and that leading white space is intended to indent with respect to previous lines. Although it'd be some work to get Emacs to do this, I don't offhand see any algorithmic problem here. > > If the way whitespace at bol is rendered depends on indentation code, will the mean that while scrolling a buffer the display engine will have to call indentation code? In Paul's suggestion (the one I implemented), the width of whitespace at bol does not depend on indentation code. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 15:15 ` Dmitry Gutov 2018-03-06 15:34 ` Clément Pit-Claudel @ 2018-03-06 17:09 ` Eli Zaretskii 1 sibling, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 17:09 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel, eggert, dancol, raeburn, rms > Cc: raeburn@raeburn.org, rms@gnu.org, emacs-devel@gnu.org > From: Dmitry Gutov <dgutov@yandex.ru> > Date: Tue, 6 Mar 2018 17:15:29 +0200 > > If the way whitespace at bol is rendered depends on indentation code, > will the mean that while scrolling a buffer the display engine will have > to call indentation code? I very much hope not, as this would be a performance hit. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation (was: What improvements would be truly useful?) 2018-03-05 19:32 ` dancol 2018-03-05 19:49 ` Variable-width font indentation Paul Eggert @ 2018-03-05 19:58 ` Eli Zaretskii 2018-03-05 20:28 ` Variable-width font indentation Clément Pit-Claudel 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-05 19:58 UTC (permalink / raw) To: dancol; +Cc: emacs-devel, raeburn, dancol, rms, eggert > Date: Mon, 5 Mar 2018 11:32:30 -0800 > From: dancol@dancol.org > Cc: rms@gnu.org, > raeburn@raeburn.org, > eggert@cs.ucla.edu, > dancol@dancol.org, > emacs-devel@gnu.org > > Well, say you want to align the following code: > > 1: void foo(int a, > 2: int b) > 3: { > 4: ... > > How is any generic indentation system supposed to know that the "i" on > line 2 is supposed to line up with the "i" on line 1? How does it know that today, when we only support well the fixed-pitch fonts? Or are you talking about a different problem? > You'd need to communicate all indentation intent to the generic > system in the form of positions relative to some > anchor. (Presumably, it could cache pixel offsets per-line.) While > that's doable, it's a ton of work, and I don't think it's > worthwhile. Maybe I still misunderstand you, but the pixel position of a character on display is trivial to obtain, and I see no reason why we'd need to cache them. Again, the current fixed-pitch column-wise indentation machinery doesn't, AFAIK. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 19:58 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii @ 2018-03-05 20:28 ` Clément Pit-Claudel 2018-03-05 22:30 ` Paul Eggert ` (3 more replies) 0 siblings, 4 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-05 20:28 UTC (permalink / raw) To: emacs-devel; +Cc: Paul Eggert On 2018-03-05 14:58, Eli Zaretskii wrote: > How does it know that today, when we only support well the > fixed-pitch fonts? Or are you talking about a different problem? A different problem, IIUC. The problem is the following: Assume you wrote the following C code, then changed to variable-pitch: void pr () { printf ("hello, world\n"); } int main (int argc, char** argv) { pr (); return 0; } Depending on which font you use (and the width of a space in that font), the `char** argv' part will move right or left, instead of remaining aligned. The usual solution is to proceed as Paul suggested: > It assumes the input is fixed-width, and that leading white space is > intended to indent with respect to previous lines. IOW, you scale the spaces preceding `char** argv' to make the `c' of `char' line up with the `i' of int. Applying this strategy to all lines doesn't work, unfortunately: it indents the `pr ()' and `printf (' lines differently, because the `in' of `int main' and the `vo' of `void' occupy different widths. I don't know of a good solution to this problem: in general, there's not enough information to distinguish 'indentation' spaces (the two spaces before `printf (', `pr ()', and `return 0') and 'line-up' spaces (the spaces before `char ()'). I hope I'm missing something. Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 20:28 ` Variable-width font indentation Clément Pit-Claudel @ 2018-03-05 22:30 ` Paul Eggert 2018-03-05 22:53 ` Daniel Colascione 2018-03-06 1:06 ` Clément Pit-Claudel 2018-03-06 4:05 ` Herring, Davis ` (2 subsequent siblings) 3 siblings, 2 replies; 253+ messages in thread From: Paul Eggert @ 2018-03-05 22:30 UTC (permalink / raw) To: Clément Pit-Claudel, emacs-devel On 03/05/2018 12:28 PM, Clément Pit-Claudel wrote: > Applying this strategy to all lines doesn't work, unfortunately: it indents the `pr ()' and `printf (' lines differently, because the `in' of `int main' and the `vo' of `void' occupy different widths. True, but that's a feature not a defect. The code is easier to read if every region is indented individually, as opposed to using exactly the same indenting everywhere in the buffer. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 22:30 ` Paul Eggert @ 2018-03-05 22:53 ` Daniel Colascione 2018-03-06 1:06 ` Clément Pit-Claudel 1 sibling, 0 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-05 22:53 UTC (permalink / raw) To: Paul Eggert, Clément Pit-Claudel, emacs-devel On 03/05/2018 02:30 PM, Paul Eggert wrote: > On 03/05/2018 12:28 PM, Clément Pit-Claudel wrote: >> Applying this strategy to all lines doesn't work, unfortunately: it >> indents the `pr ()' and `printf (' lines differently, because the `in' >> of `int main' and the `vo' of `void' occupy different widths. > > True, but that's a feature not a defect. The code is easier to read if > every region is indented individually, as opposed to using exactly the > same indenting everywhere in the buffer. In non-lineup styles (e.g., the Linux kernel), different blocks with the same notional indentation actually having different offsets from the left margin would be very unusual. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 22:30 ` Paul Eggert 2018-03-05 22:53 ` Daniel Colascione @ 2018-03-06 1:06 ` Clément Pit-Claudel 2018-03-06 1:30 ` Paul Eggert 1 sibling, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 1:06 UTC (permalink / raw) To: Paul Eggert, emacs-devel On 2018-03-05 17:30, Paul Eggert wrote: > On 03/05/2018 12:28 PM, Clément Pit-Claudel wrote: >> Applying this strategy to all lines doesn't work, unfortunately: it >> indents the `pr ()' and `printf (' lines differently, because the >> `in' of `int main' and the `vo' of `void' occupy different widths. > > True, but that's a feature not a defect. The code is easier to read > if every region is indented individually, as opposed to using exactly > the same indenting everywhere in the buffer. Hmm. I hadn't thought of this :) But I'm not entirely convinced yet. Consider this snippet: def x(): with open("A") as f: while y: print(y.v()) or this one in elisp: (when x (if y t (unless p (cl-loop for x in y collect x)))) In variable-pitch mode, each new indentation level has a slightly-different width, instead of a regular progression of 4 spaces (in Python) and 2 spaces (in Elisp) at each level. Beyond this, there's the problem of inline line-up spaces. For an example, consider this, from xdisp.c, which shows "line-up" spaces in full glory: +--------------+ redisplay +----------------+ | Lisp machine |---------------->| Redisplay code |<--+ +--------------+ (xdisp.c) +----------------+ | ^ | | +----------------------------------+ | Block input to prevent this when | called asynchronously! | | note_mouse_highlight (asynchronous) | | X mouse events -----+ | expose_frame (asynchronous) | | X expose events -----+ The same problem pops up with org-mode tables, etc. Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 1:06 ` Clément Pit-Claudel @ 2018-03-06 1:30 ` Paul Eggert 2018-03-06 1:40 ` Clément Pit-Claudel ` (2 more replies) 0 siblings, 3 replies; 253+ messages in thread From: Paul Eggert @ 2018-03-06 1:30 UTC (permalink / raw) To: Clément Pit-Claudel, emacs-devel On 03/05/2018 05:06 PM, Clément Pit-Claudel wrote: > In variable-pitch mode, each new indentation level has a slightly-different width, instead of a regular progression of 4 spaces (in Python) and 2 spaces (in Elisp) at each level. That's fine. Although it's only a small thing, to me it's even a small plus, as having every indent level be the same number of pixels unnaturally focuses the reader on a distracting regularity that is not intrinsic to the code. > Beyond this, there's the problem of inline line-up spaces. Yes, for ASCII art I doubt whether any simple automated heuristic would work unaided. ASCII art is typically ugly and hard-to-read even in a fixed-width font, so it's not much of a loss if it's rendered poorly. If there's really a need for it I suppose we could let users hint to Emacs to switch to a fixed-width font just for the art; that'd be good enough. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 1:30 ` Paul Eggert @ 2018-03-06 1:40 ` Clément Pit-Claudel 2018-03-06 2:04 ` Paul Eggert ` (2 more replies) 2018-03-06 16:16 ` Eli Zaretskii 2018-03-06 20:52 ` Richard Stallman 2 siblings, 3 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 1:40 UTC (permalink / raw) To: Paul Eggert, emacs-devel On 2018-03-05 20:30, Paul Eggert wrote: > On 03/05/2018 05:06 PM, Clément Pit-Claudel wrote: >> In variable-pitch mode, each new indentation level has a >> slightly-different width, instead of a regular progression of 4 >> spaces (in Python) and 2 spaces (in Elisp) at each level. > > That's fine. Although it's only a small thing, to me it's even a > small plus, as having every indent level be the same number of pixels > unnaturally focuses the reader on a distracting regularity that is > not intrinsic to the code. I've been playing with this a bit more; until now, I'd mostly stopped at my previous objection. The following code gives a preview of what the algorithm that we've been discussing produces: (defun ~/variable-pitch-indent () (interactive) (save-excursion (let ((spine "") (face `(:foreground ,(face-attribute 'default :background nil)))) (goto-char (point-min)) (while (not (eobp)) (back-to-indentation) (unless (eolp) (let* ((indentation-amount (current-column)) (spine-cut (min (length spine) indentation-amount)) (spine-prefix (substring spine 0 spine-cut)) (spine-padding (make-string (- indentation-amount spine-cut) ?\s)) (spine-end (buffer-substring (point) (point-at-eol)))) (setq spine (with-temp-buffer ;; HACK: expand spaces (setq-local tab-width 8) (insert spine-prefix spine-padding spine-end) (untabify (point-min) (point-max)) (buffer-string))) (put-text-property (point-at-bol) (point) 'display (propertize (concat spine-prefix spine-padding) 'face face)))) (forward-line 1))))) I've tested it on two files: src/termcap.c and lisp/dabbrev.el. To try it out, open one of these files in emacs -Q, then run M-x ~/variable-pitch-indent, and then M-x variable-pitch-mode. I do agree that it doesn't look too bad, and presumably a C implementation of the algorithm above would be very fast, since it could build the "spine" above during redisplay. Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 1:40 ` Clément Pit-Claudel @ 2018-03-06 2:04 ` Paul Eggert 2018-03-06 3:36 ` Clément Pit-Claudel 2018-03-06 5:48 ` Daniel Colascione 2018-03-06 16:36 ` Eli Zaretskii 2018-03-07 22:13 ` Clément Pit-Claudel 2 siblings, 2 replies; 253+ messages in thread From: Paul Eggert @ 2018-03-06 2:04 UTC (permalink / raw) To: Clément Pit-Claudel, emacs-devel On 03/05/2018 05:40 PM, Clément Pit-Claudel wrote: > I've tested it on two files: src/termcap.c and lisp/dabbrev.el. To try it out, open one of these files in emacs -Q, then run M-x ~/variable-pitch-indent, and then M-x variable-pitch-mode. > > I do agree that it doesn't look too bad, and presumably a C implementation of the algorithm above would be very fast, since it could build the "spine" above during redisplay. Thanks, that was fast! Yes, it should work fast. I saw one easily-fixable minor glitch (on my screen lisp/dabbr.el line 533 had the wrong indent, presumably since the "user-error" on the previous line was in a fatter-than usual font). The biggest trickier minor glitch was that indenting of #if and #else subparts were annoyingly different because the "#" violates the usual indentation rule. Personally I've always thought that we should indent "#" like anything else -- the only reason we don't is that it didn't work with K&R C and so we got used to bad style -- but even if we stick with the bad "#if" indenting it still looks pretty reasonable. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 2:04 ` Paul Eggert @ 2018-03-06 3:36 ` Clément Pit-Claudel 2018-03-06 16:47 ` Eli Zaretskii 2018-03-06 5:48 ` Daniel Colascione 1 sibling, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 3:36 UTC (permalink / raw) To: Paul Eggert, emacs-devel On 2018-03-05 21:04, Paul Eggert wrote: > On 03/05/2018 05:40 PM, Clément Pit-Claudel wrote: >> I've tested it on two files: src/termcap.c and lisp/dabbrev.el. To try it out, open one of these files in emacs -Q, then run M-x ~/variable-pitch-indent, and then M-x variable-pitch-mode. >> >> I do agree that it doesn't look too bad, and presumably a C implementation of the algorithm above would be very fast, since it could build the "spine" above during redisplay. > > Thanks, that was fast! Yes, it should work fast. > > I saw one easily-fixable minor glitch (on my screen lisp/dabbr.el line 533 had the wrong indent, presumably since the "user-error" on the previous line was in a fatter-than usual font). Yes, that's due to the implementation trick that I used, which doesn't preserve faces on the "spine", the string used for indentation. The biggest trickier minor glitch was that indenting of #if and #else subparts were annoyingly different because the "#" violates the usual indentation rule. Personally I've always thought that we should indent "#" like anything else -- the only reason we don't is that it didn't work with K&R C and so we got used to bad style -- but even if we stick with the bad "#if" indenting it still looks pretty reasonable. Indeed. It does look fairly OK, actually — much better than I expected it to be. I guess the next step would be to make a minor mode to apply this variable-pitch indentation on the fly and see how well it works in real life. Some difficulties: * Changing a line will cause all lines below it to get reindented; this will make redisplay costly, and I'm not sure how good it'll look — and we won't be able to tell until we get a C implementation, since an ELisp implementation likely won't update indentation for following lines on the fly. * I'm not aware of a way to get a specified space whose width equals that of a particular string, without measuring the string beforehand. Is there a way? Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 3:36 ` Clément Pit-Claudel @ 2018-03-06 16:47 ` Eli Zaretskii 2018-03-06 19:50 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 16:47 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Mon, 5 Mar 2018 22:36:55 -0500 > > * I'm not aware of a way to get a specified space whose width equals that of a particular string, without measuring the string beforehand. Is there a way? What do you mean by "measuring the string"? Calculating its width? In your implementation you used 'length', which is definitely not TRT, especially with variable-width fonts. I think you can find something to help you out in shr.el. One other possibility is to use font-get-glyphs, but I'm not sure it will help in this case. And I still think that for programming modes, what we need is to substitute tab-width and column by suitably computed number of pixels, perhaps derived from the width of some character. Other than that, the indentation code should "just work", as long as it uses :align-to to get to a given pixel coordinate. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:47 ` Eli Zaretskii @ 2018-03-06 19:50 ` Clément Pit-Claudel 0 siblings, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 19:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-06 11:47, Eli Zaretskii wrote: > What do you mean by "measuring the string"? Calculating its width? Correct. > In your implementation you used 'length', which is definitely not TRT, > especially with variable-width fonts. I think you misread the implementation :) But I'm not sure which part caused confusion, so I'm not sure what to explain. > And I still think that for programming modes, what we need is to > substitute tab-width and column by suitably computed number of pixels, > perhaps derived from the width of some character. Other than that, > the indentation code should "just work", as long as it uses :align-to > to get to a given pixel coordinate. I don't understand this part :/ ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 2:04 ` Paul Eggert 2018-03-06 3:36 ` Clément Pit-Claudel @ 2018-03-06 5:48 ` Daniel Colascione 2018-03-06 13:18 ` Clément Pit-Claudel 1 sibling, 1 reply; 253+ messages in thread From: Daniel Colascione @ 2018-03-06 5:48 UTC (permalink / raw) To: Paul Eggert, Clément Pit-Claudel, emacs-devel On 03/05/2018 06:04 PM, Paul Eggert wrote: > On 03/05/2018 05:40 PM, Clément Pit-Claudel wrote: >> I've tested it on two files: src/termcap.c and lisp/dabbrev.el. To >> try it out, open one of these files in emacs -Q, then run M-x >> ~/variable-pitch-indent, and then M-x variable-pitch-mode. >> >> I do agree that it doesn't look too bad, and presumably a C >> implementation of the algorithm above would be very fast, since it >> could build the "spine" above during redisplay. > > Thanks, that was fast! Yes, it should work fast. > > I saw one easily-fixable minor glitch (on my screen lisp/dabbr.el line > 533 had the wrong indent, presumably since the "user-error" on the > previous line was in a fatter-than usual font). Right. Given sufficiently divergent character widgets, it'd be possible to trick the eye into thinking two blocks of code at semantically different indentation levels are in fact at different levels, or vice versa. IMHO, that's dangerous. I'd rather whitelist modes where the indentation machinery can reliably provide robust alignment-versus-indentation information. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 5:48 ` Daniel Colascione @ 2018-03-06 13:18 ` Clément Pit-Claudel 0 siblings, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 13:18 UTC (permalink / raw) To: Daniel Colascione, Paul Eggert, emacs-devel On 2018-03-06 00:48, Daniel Colascione wrote: > I'd rather whitelist modes where the indentation machinery can > reliably provide robust alignment-versus-indentation information. Do you think that'll be enough? What do we do when we open a file that's already indented in a way that doesn't match what our own indentation function would do? Or do you mean that we need a new "indentation analyzer" for each new mode that tags spaces as "alignment" spaces vs "indentation" spaces? One more tricky case, from playing with this a bit more: in OCaml, it's not entirely uncommon to see this: match o with | None -> 0 (* Note the extra spaces to line up the arrows *) | Some x -> x + 1 Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 1:40 ` Clément Pit-Claudel 2018-03-06 2:04 ` Paul Eggert @ 2018-03-06 16:36 ` Eli Zaretskii 2018-03-06 20:11 ` Clément Pit-Claudel 2018-03-07 22:13 ` Clément Pit-Claudel 2 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 16:36 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Mon, 5 Mar 2018 20:40:14 -0500 > > The following code gives a preview of what the algorithm that we've been discussing produces: Thanks, but I still don't see why we couldn't simply "adjust" the width of white space using the 'space' display property. Your implementation has a few issues. First, if you move the cursor vertically at column zero, do you see "ghost" characters displayed at cursor position? Hiding characters by displaying them with foreground color identical to the background color has its limits ;-) Also, with this implementation, the braces in the 'if' and 'else' blocks no longer align. E.g., try to indent this snippet: foo () { if (something) { do (anything); } else { do (something-else); } } I think this misalignment will be annoying. > I do agree that it doesn't look too bad, and presumably a C implementation of the algorithm above would be very fast, since it could build the "spine" above during redisplay. Indenting during redisplay is a bad idea, because it will disable almost every redisplay optimization. I actually don't understand why you worry about performance: the function you wrote is the morel equivalent of C-\, and that one is not fast with the current implementation. We never modify indentation of non-current lines anyway, we expect the user to type TAB or some electric character to reindent a line, and we expect them to use C-\ to reindent more than one line. Automatic adjustment of indentation might be a good feature, but it would be a separate feature. In any case, I'd suggest to reindent via buffer-modification hooks, not as part of redisplay. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:36 ` Eli Zaretskii @ 2018-03-06 20:11 ` Clément Pit-Claudel 2018-03-06 20:40 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 20:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-06 11:36, Eli Zaretskii wrote: >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> Date: Mon, 5 Mar >> 2018 20:40:14 -0500 >> >> The following code gives a preview of what the algorithm that we've >> been discussing produces: > > Thanks, but I still don't see why we couldn't simply "adjust" the > width of white space using the 'space' display property. Because "I'm not aware of a way to get a specified space whose width equals that of a particular string, without measuring the string beforehand. Is there a way?" :) IOW, I'm all for it, but I don't know how. > Your implementation has a few issues. First, if you move the cursor > vertically at column zero, do you see "ghost" characters displayed > at cursor position? Hiding characters by displaying them with > foreground color identical to the background color has its limits > ;-) That's a feature :) (Just to be clear: that was the easy way to get a feel for what the algorithm that Paul and I were discussing would produce; I'd have used space properties if I had known a way to get a space of the same with as these ghost characters). And there are many other issues, of course: we don't want to apply the display property to more than one stretch of space, and the code doesn't deal properly with tabs vs spaces, etc. > Also, with this implementation, the braces in the 'if' and 'else' > blocks no longer align. E.g., try to indent this snippet: > > foo () { if (something) { do (anything); } else { do > (something-else); } } > > I think this misalignment will be annoying. Indeed, this was discussed in this thread; Paul thinks it's not an issue; I'm not convinced (I tend to agree with you) :) >> I do agree that it doesn't look too bad, and presumably a C >> implementation of the algorithm above would be very fast, since it >> could build the "spine" above during redisplay. > > Indenting during redisplay is a bad idea, because it will disable > almost every redisplay optimization. I think we're using "indenting" to mean different things. (Just to be clear: the process I'm describing doesn't call indent-line-function, nor any of the indentation machinery) > I actually don't understand why you worry about performance: the > function you wrote is the morel equivalent of C-\ C-\ is toggle-input-method on my machine; is that what you meant? > , and that one is not fast with the current implementation. We never > modify indentation of non-current lines anyway, we expect the user to > type TAB or some electric character to reindent a line, and we expect > them to use C-\ to reindent more than one line. Automatic adjustment > of indentation might be a good feature, but it would be a separate > feature. I never meant to adjust indentation (that is, to change the contents of the buffer): just to display existing leading spaces differently based on the contents of previous line. > In any case, I'd suggest to reindent via buffer-modification hooks, > not as part of redisplay. Right, and that's why I worry about performance. Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 20:11 ` Clément Pit-Claudel @ 2018-03-06 20:40 ` Eli Zaretskii 2018-03-07 13:15 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 20:40 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Tue, 6 Mar 2018 15:11:29 -0500 > > > Thanks, but I still don't see why we couldn't simply "adjust" the > > width of white space using the 'space' display property. > > Because "I'm not aware of a way to get a specified space whose width equals that of a particular string, without measuring the string beforehand. Is there a way?" :) The "string" you refer to is already in the buffer on display, right? If so, you can simply use the likes of posn-at-point to measure portions of text in pixel units. Then translate that into floating-point "column" numbers by dividing by width of some suitable character (it could be SPC, but that is a bad idea with some fonts, so maybe something else, like 'e'). > I'd have used space properties if I had known a way to get a space of the same with as these ghost characters). See above. And there's font-get-glyphs. > And there are many other issues, of course: we don't want to apply the display property to more than one stretch of space, and the code doesn't deal properly with tabs vs spaces, etc. Please elaborate, because I don't understand those issues well enough to see if and how they can be resolved. > >> I do agree that it doesn't look too bad, and presumably a C > >> implementation of the algorithm above would be very fast, since it > >> could build the "spine" above during redisplay. > > > > Indenting during redisplay is a bad idea, because it will disable > > almost every redisplay optimization. > > I think we're using "indenting" to mean different things. (Just to be clear: the process I'm describing doesn't call indent-line-function, nor any of the indentation machinery) Then what _do_ you mean by "building the spine during redisplay"? > > I actually don't understand why you worry about performance: the > > function you wrote is the morel equivalent of C-\ > > C-\ is toggle-input-method on my machine; is that what you meant? Sorry, I meant M-C-\, of course. > > , and that one is not fast with the current implementation. We never > > modify indentation of non-current lines anyway, we expect the user to > > type TAB or some electric character to reindent a line, and we expect > > them to use C-\ to reindent more than one line. Automatic adjustment > > of indentation might be a good feature, but it would be a separate > > feature. > > I never meant to adjust indentation (that is, to change the contents of the buffer): just to display existing leading spaces differently based on the contents of previous line. We never do that with the existing indentation machinery, either. > > In any case, I'd suggest to reindent via buffer-modification hooks, > > not as part of redisplay. > > Right, and that's why I worry about performance. Then don't automatically reindent, let the user initiate that. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 20:40 ` Eli Zaretskii @ 2018-03-07 13:15 ` Clément Pit-Claudel 2018-03-07 18:26 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-07 13:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-06 15:40, Eli Zaretskii wrote: >> Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Tue, 6 Mar 2018 15:11:29 -0500 >> >>> Thanks, but I still don't see why we couldn't simply "adjust" the >>> width of white space using the 'space' display property. >> >> Because "I'm not aware of a way to get a specified space whose width equals that of a particular string, without measuring the string beforehand. Is there a way?" :) > > The "string" you refer to is already in the buffer on display, right? > If so, you can simply use the likes of posn-at-point to measure > portions of text in pixel units. Yes and no: it might be offscreen. But posn-at-point is a useful suggestion, thanks :) > Then translate that into > floating-point "column" numbers by dividing by width of some suitable > character (it could be SPC, but that is a bad idea with some fonts, so > maybe something else, like 'e'). I don't think I need that part. >> I'd have used space properties if I had known a way to get a space of the same with as these ghost characters). > > See above. And there's font-get-glyphs. Thanks, I'll look into this. >> And there are many other issues, of course: we don't want to apply the display property to more than one stretch of space, and the code doesn't deal properly with tabs vs spaces, etc. > > Please elaborate, because I don't understand those issues well enough > to see if and how they can be resolved. That code was just a rough draft, so it's plenty of corner cases that I didn't think about yet. That's all :) >>>> I do agree that it doesn't look too bad, and presumably a C >>>> implementation of the algorithm above would be very fast, since it >>>> could build the "spine" above during redisplay. >>> >>> Indenting during redisplay is a bad idea, because it will disable >>> almost every redisplay optimization. >> >> I think we're using "indenting" to mean different things. (Just to be clear: the process I'm describing doesn't call indent-line-function, nor any of the indentation machinery) > > Then what _do_ you mean by "building the spine during redisplay"? I meant build a prefix string (which the code I sent called the "spine") to use instead of leading spaces. The ghost characters that you noticed are the value of the spine on that line. >>> I actually don't understand why you worry about performance: the >>> function you wrote is the morel equivalent of C-\ >> >> C-\ is toggle-input-method on my machine; is that what you meant? > > Sorry, I meant M-C-\, of course. Ah, yes, I see. That's not what the code I offered does at all, I think. >>> , and that one is not fast with the current implementation. We never >>> modify indentation of non-current lines anyway, we expect the user to >>> type TAB or some electric character to reindent a line, and we expect >>> them to use C-\ to reindent more than one line. Automatic adjustment >>> of indentation might be a good feature, but it would be a separate >>> feature. >> >> I never meant to adjust indentation (that is, to change the contents of the buffer): just to display existing leading spaces differently based on the contents of previous line. > > We never do that with the existing indentation machinery, either. Wait, never do what? >>> In any case, I'd suggest to reindent via buffer-modification hooks, >>> not as part of redisplay. >> >> Right, and that's why I worry about performance. > > Then don't automatically reindent, let the user initiate that. The feature I'm offering is like font-locking, not like reindenting: it changes the display of existing buffer elements in a way that doesn't modify the underlying text. Given this, it makes more sense to me to run it automatically (rather than on demand) Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 13:15 ` Clément Pit-Claudel @ 2018-03-07 18:26 ` Eli Zaretskii 2018-03-09 16:07 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 18:26 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 7 Mar 2018 08:15:39 -0500 > > > The "string" you refer to is already in the buffer on display, right? > > If so, you can simply use the likes of posn-at-point to measure > > portions of text in pixel units. > > Yes and no: it might be offscreen. Then the text you need to indent below it is also off-screen, and you don't need to re-indent it, right? > > Then what _do_ you mean by "building the spine during redisplay"? > > I meant build a prefix string (which the code I sent called the "spine") to use instead of leading spaces. What would be the advantage of building such a string at redisplay time? Consing a short string is very fast, and has the advantage of being done only when needed (by contrast, display code is many times invoked for reasons utterly unrelated to actually displaying stuff). > >> I never meant to adjust indentation (that is, to change the contents of the buffer): just to display existing leading spaces differently based on the contents of previous line. > > > > We never do that with the existing indentation machinery, either. > > Wait, never do what? What you say in the sentence I quoted: display existing leading spaces differently based on the contents of previous line. > >>> In any case, I'd suggest to reindent via buffer-modification hooks, > >>> not as part of redisplay. > >> > >> Right, and that's why I worry about performance. > > > > Then don't automatically reindent, let the user initiate that. > > The feature I'm offering is like font-locking, not like reindenting: it changes the display of existing buffer elements in a way that doesn't modify the underlying text. Given this, it makes more sense to me to run it automatically (rather than on demand) "Automatically" doesn't necessarily mean "like font-lock". I think we should know better than get ourselves once again into an adventure like font-lock, which even today, with JIT and all the years of experience and improvements, is still a headache, if not a PITA. If there's no other way to do something that's really necessary, fine; but we should avoid such features as much as possible. For example, in this case, I'm beginning to think that we should render SPC characters similarly to what we do with TABs: produce a stretch glyph of a suitably computed width, and perhaps introduce a variable space-width (like tab-width) to help Lisp programs with controlling that. Note that 'space' display property supports values that are symbols, in which case it uses the symbol's value -- this allows Lisp programs to change the value of a buffer-local binding of the symbol, and have the indentation change at the next redisplay cycle (a.k.a. "immediately"). Doesn't that provide a better way for controlling indentation than font-lock style scanning of the visible portion of the buffer "just in time"? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 18:26 ` Eli Zaretskii @ 2018-03-09 16:07 ` Clément Pit-Claudel 0 siblings, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-09 16:07 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-07 13:26, Eli Zaretskii wrote: > Note that 'space' display property supports values > that are symbols, in which case it uses the symbol's value -- this > allows Lisp programs to change the value of a buffer-local binding of > the symbol, and have the indentation change at the next redisplay > cycle (a.k.a. "immediately"). Doesn't that provide a better way for > controlling indentation than font-lock style scanning of the visible > portion of the buffer "just in time"? Sorry, I missed this email before. Yes, this sounds pretty good, and I understand the reticence to depending on font-lock. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 1:40 ` Clément Pit-Claudel 2018-03-06 2:04 ` Paul Eggert 2018-03-06 16:36 ` Eli Zaretskii @ 2018-03-07 22:13 ` Clément Pit-Claudel 2018-03-08 13:21 ` Eli Zaretskii 2 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-07 22:13 UTC (permalink / raw) To: Paul Eggert, emacs-devel On 2018-03-05 20:40, Clément Pit-Claudel wrote: > On 2018-03-05 20:30, Paul Eggert wrote: >> On 03/05/2018 05:06 PM, Clément Pit-Claudel wrote: >>> In variable-pitch mode, each new indentation level has a >>> slightly-different width, instead of a regular progression of 4 >>> spaces (in Python) and 2 spaces (in Elisp) at each level. >> >> That's fine. Although it's only a small thing, to me it's even a >> small plus, as having every indent level be the same number of pixels >> unnaturally focuses the reader on a distracting regularity that is >> not intrinsic to the code. > > I've been playing with this a bit more; until now, I'd mostly stopped at my previous objection. > > The following code gives a preview of what the algorithm that we've been discussing produces: [...] This version is a bit faster, and it uses 'display (space …) instead of ghost strings: (defun ~/variable-pitch-indent () (interactive) (save-excursion (let ((spine []) (prev-bol nil) (prev-eol nil)) (goto-char (point-min)) (while (not (eobp)) (let ((bol (point))) (back-to-indentation) (unless (eolp) (let* ((indentation-amount (current-column)) (trunc-spine-to (min (length spine) indentation-amount))) (setq spine (seq-subseq spine 0 trunc-spine-to)) ;; Extend spine based on previous line (when (and prev-bol (< (length spine) indentation-amount)) (let ((beg (+ prev-bol (length spine))) (end (min prev-eol (+ prev-bol indentation-amount)))) (setq spine (vconcat spine (~/measure-px-widths beg end))))) (setq prev-bol bol prev-eol (point-at-eol)))) (dotimes (idx (min (length spine) (- (point) bol))) (let ((w (aref spine idx))) (put-text-property (+ bol idx) (+ bol idx 1) 'display `(space :width (,w))))) (forward-line 1)))))) … but it doesn't work with tabs. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 22:13 ` Clément Pit-Claudel @ 2018-03-08 13:21 ` Eli Zaretskii 2018-03-08 14:05 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-08 13:21 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 7 Mar 2018 17:13:09 -0500 > > This version is a bit faster, and it uses 'display (space …) instead of ghost strings: > > (defun ~/variable-pitch-indent () > (interactive) > (save-excursion > (let ((spine []) > (prev-bol nil) > (prev-eol nil)) > (goto-char (point-min)) > (while (not (eobp)) > (let ((bol (point))) > (back-to-indentation) > (unless (eolp) > (let* ((indentation-amount (current-column)) > (trunc-spine-to (min (length spine) indentation-amount))) > (setq spine (seq-subseq spine 0 trunc-spine-to)) > ;; Extend spine based on previous line > (when (and prev-bol (< (length spine) indentation-amount)) > (let ((beg (+ prev-bol (length spine))) > (end (min prev-eol (+ prev-bol indentation-amount)))) > (setq spine (vconcat spine (~/measure-px-widths beg end))))) > (setq prev-bol bol prev-eol (point-at-eol)))) > (dotimes (idx (min (length spine) (- (point) bol))) > (let ((w (aref spine idx))) > (put-text-property (+ bol idx) (+ bol idx 1) > 'display `(space :width (,w))))) > (forward-line 1)))))) It seems you forgot to post ~/measure-px-widths. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 13:21 ` Eli Zaretskii @ 2018-03-08 14:05 ` Clément Pit-Claudel 0 siblings, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-08 14:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-08 08:21, Eli Zaretskii wrote: >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Wed, 7 Mar 2018 17:13:09 -0500 >> >> This version is a bit faster, and it uses 'display (space …) instead of ghost strings: >> ... > > It seems you forgot to post ~/measure-px-widths. Indeed, apologies :/ (defun ~/measure-px-widths (beg end) (let ((widths nil)) (while (< beg end) (push (car (window-text-pixel-size nil beg (1+ beg))) widths) (cl-incf beg)) (nreverse widths))) (defun ~/variable-pitch-indent () (interactive) (save-excursion (let ((spine []) (prev-bol nil) (prev-eol nil)) (goto-char (point-min)) (while (not (eobp)) (let ((bol (point))) (back-to-indentation) (unless (eolp) (let* ((indentation-amount (current-column)) (trunc-spine-to (min (length spine) indentation-amount))) (setq spine (seq-subseq spine 0 trunc-spine-to)) ;; Extend spine based on previous line (when (and prev-bol (< (length spine) indentation-amount)) (let ((beg (+ prev-bol (length spine))) (end (min prev-eol (+ prev-bol indentation-amount)))) (setq spine (vconcat spine (~/measure-px-widths beg end))))) (setq prev-bol bol prev-eol (point-at-eol)))) (dotimes (idx (min (length spine) (- (point) bol))) (let ((w (aref spine idx))) (put-text-property (+ bol idx) (+ bol idx 1) 'display `(space :width (,w))))) (forward-line 1)))))) ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 1:30 ` Paul Eggert 2018-03-06 1:40 ` Clément Pit-Claudel @ 2018-03-06 16:16 ` Eli Zaretskii 2018-03-06 16:38 ` Daniel Colascione 2018-03-06 20:52 ` Richard Stallman 2 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 16:16 UTC (permalink / raw) To: Paul Eggert; +Cc: cpitclaudel, emacs-devel > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Mon, 5 Mar 2018 17:30:24 -0800 > > Yes, for ASCII art I doubt whether any simple automated heuristic would > work unaided. ASCII art is typically ugly and hard-to-read even in a > fixed-width font, so it's not much of a loss if it's rendered poorly. If > there's really a need for it I suppose we could let users hint to Emacs > to switch to a fixed-width font just for the art; that'd be good enough. We could have an interactive alignment feature, whereby the user could move a character at pixel resolution, until it aligns to the user's liking. The implementation would modify the :align-to attribute of the display property we put on whitespace before that character. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:16 ` Eli Zaretskii @ 2018-03-06 16:38 ` Daniel Colascione 2018-03-06 17:49 ` Eli Zaretskii 2018-03-06 18:53 ` Sam Steingold 0 siblings, 2 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-06 16:38 UTC (permalink / raw) To: Eli Zaretskii, Paul Eggert; +Cc: cpitclaudel, emacs-devel On 03/06/2018 08:16 AM, Eli Zaretskii wrote: >> From: Paul Eggert <eggert@cs.ucla.edu> >> Date: Mon, 5 Mar 2018 17:30:24 -0800 >> >> Yes, for ASCII art I doubt whether any simple automated heuristic would >> work unaided. ASCII art is typically ugly and hard-to-read even in a >> fixed-width font, so it's not much of a loss if it's rendered poorly. If >> there's really a need for it I suppose we could let users hint to Emacs >> to switch to a fixed-width font just for the art; that'd be good enough. > > We could have an interactive alignment feature, whereby the user could > move a character at pixel resolution, until it aligns to the user's > liking. The implementation would modify the :align-to attribute of > the display property we put on whitespace before that character. How would you serialize the result? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:38 ` Daniel Colascione @ 2018-03-06 17:49 ` Eli Zaretskii 2018-03-06 17:55 ` dancol 2018-03-06 18:53 ` Sam Steingold 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 17:49 UTC (permalink / raw) To: Daniel Colascione; +Cc: cpitclaudel, eggert, emacs-devel > Cc: cpitclaudel@gmail.com, emacs-devel@gnu.org > From: Daniel Colascione <dancol@dancol.org> > Date: Tue, 6 Mar 2018 08:38:28 -0800 > > > We could have an interactive alignment feature, whereby the user could > > move a character at pixel resolution, until it aligns to the user's > > liking. The implementation would modify the :align-to attribute of > > the display property we put on whitespace before that character. > > How would you serialize the result? You mean, save it to a disk file? I think we should insert the number of blanks to align stuff with fixed-pitch font, so that it looks well with those fonts. If we want to preserve the display properties across sessions, we could use enriched-text-mode, I think. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 17:49 ` Eli Zaretskii @ 2018-03-06 17:55 ` dancol 2018-03-06 20:18 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: dancol @ 2018-03-06 17:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cpitclaudel, Daniel Colascione, emacs-devel, eggert >> Cc: cpitclaudel@gmail.com, emacs-devel@gnu.org >> From: Daniel Colascione <dancol@dancol.org> >> Date: Tue, 6 Mar 2018 08:38:28 -0800 >> >> > We could have an interactive alignment feature, whereby the user could >> > move a character at pixel resolution, until it aligns to the user's >> > liking. The implementation would modify the :align-to attribute of >> > the display property we put on whitespace before that character. >> >> How would you serialize the result? > > You mean, save it to a disk file? I think we should insert the number > of blanks to align stuff with fixed-pitch font, so that it looks well > with those fonts. If we want to preserve the display properties > across sessions, we could use enriched-text-mode, I think. I don't think there's any clean way to embed this alignment information in arbitrary program text though. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 17:55 ` dancol @ 2018-03-06 20:18 ` Eli Zaretskii 2018-03-06 20:20 ` Daniel Colascione 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 20:18 UTC (permalink / raw) To: dancol; +Cc: cpitclaudel, eggert, emacs-devel > Date: Tue, 6 Mar 2018 09:55:16 -0800 > From: dancol@dancol.org > Cc: "Daniel Colascione" <dancol@dancol.org>, > eggert@cs.ucla.edu, > cpitclaudel@gmail.com, > emacs-devel@gnu.org > > > You mean, save it to a disk file? I think we should insert the number > > of blanks to align stuff with fixed-pitch font, so that it looks well > > with those fonts. If we want to preserve the display properties > > across sessions, we could use enriched-text-mode, I think. > > I don't think there's any clean way to embed this alignment information in > arbitrary program text though. No, it would be necessary to reconstruct it. But any solution that uses text properties will have the same problem. And I don't quite see how we can align text rendered with variable-pitch font without something like that. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 20:18 ` Eli Zaretskii @ 2018-03-06 20:20 ` Daniel Colascione 0 siblings, 0 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-06 20:20 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cpitclaudel, eggert, emacs-devel On 03/06/2018 12:18 PM, Eli Zaretskii wrote: >> Date: Tue, 6 Mar 2018 09:55:16 -0800 >> From: dancol@dancol.org >> Cc: "Daniel Colascione" <dancol@dancol.org>, >> eggert@cs.ucla.edu, >> cpitclaudel@gmail.com, >> emacs-devel@gnu.org >> >>> You mean, save it to a disk file? I think we should insert the number >>> of blanks to align stuff with fixed-pitch font, so that it looks well >>> with those fonts. If we want to preserve the display properties >>> across sessions, we could use enriched-text-mode, I think. >> >> I don't think there's any clean way to embed this alignment information in >> arbitrary program text though. > > No, it would be necessary to reconstruct it. But any solution that > uses text properties will have the same problem. And I don't quite > see how we can align text rendered with variable-pitch font without > something like that. Right. The leading-indentation case is *barely* feasible, if you imagine that modes can accurately indent all lines automatically. I don't see a path toward internal alignment, since there's no algorithmic way to disambiguate spacing. The closest thing would be something like align-regexp, and even this facility requires manual intervention. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:38 ` Daniel Colascione 2018-03-06 17:49 ` Eli Zaretskii @ 2018-03-06 18:53 ` Sam Steingold 2018-03-06 22:43 ` Ricardo Wurmus 2018-03-07 17:12 ` Eli Zaretskii 1 sibling, 2 replies; 253+ messages in thread From: Sam Steingold @ 2018-03-06 18:53 UTC (permalink / raw) To: emacs-devel > * Daniel Colascione <qnapby@qnapby.bet> [2018-03-06 08:38:28 -0800]: > >> ... > > How would you serialize the result? This is actually the question that bothers me too. I think we need to separate "visual" indentation for word processing from "semantic" indentation for coding. The former should be serialized to something like HTML or LaTeX, and the latter to plain text as it is done now. IOW, I think the path to word processing in Emacs lies in html-mode improvements. Thanks. -- Sam Steingold (http://sds.podval.org/) on darwin Ns 10.3.1561 http://steingoldpsychology.com http://www.childpsy.net http://mideasttruth.com http://no2bds.org http://americancensorship.org https://ffii.org Our business is run on trust. We trust you will pay in advance. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 18:53 ` Sam Steingold @ 2018-03-06 22:43 ` Ricardo Wurmus 2018-03-07 17:12 ` Eli Zaretskii 1 sibling, 0 replies; 253+ messages in thread From: Ricardo Wurmus @ 2018-03-06 22:43 UTC (permalink / raw) To: sds; +Cc: emacs-devel Sam Steingold <sds@gnu.org> writes: >> * Daniel Colascione <qnapby@qnapby.bet> [2018-03-06 08:38:28 -0800]: >> >>> ... >> >> How would you serialize the result? > > This is actually the question that bothers me too. > I think we need to separate "visual" indentation for word processing > from "semantic" indentation for coding. > The former should be serialized to something like HTML or LaTeX, > and the latter to plain text as it is done now. Or to XML, which is used by other word processors, and which has a neat S-expression representation (sxml). -- Ricardo GPG: BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC https://elephly.net ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 18:53 ` Sam Steingold 2018-03-06 22:43 ` Ricardo Wurmus @ 2018-03-07 17:12 ` Eli Zaretskii 2018-03-07 19:38 ` Daniel Colascione 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 17:12 UTC (permalink / raw) To: sds; +Cc: emacs-devel > From: Sam Steingold <sds@gnu.org> > Date: Tue, 06 Mar 2018 13:53:54 -0500 > > > * Daniel Colascione <qnapby@qnapby.bet> [2018-03-06 08:38:28 -0800]: > > > >> ... > > > > How would you serialize the result? > > This is actually the question that bothers me too. > I think we need to separate "visual" indentation for word processing > from "semantic" indentation for coding. > The former should be serialized to something like HTML or LaTeX, > and the latter to plain text as it is done now. Take a look at enriched.el (and etc/enriched.txt as the demonstration of its capabilities): we already have the capability for serializing this, had it for many years. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 17:12 ` Eli Zaretskii @ 2018-03-07 19:38 ` Daniel Colascione 2018-03-07 20:11 ` Eli Zaretskii 2018-03-07 23:01 ` Richard Stallman 0 siblings, 2 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-07 19:38 UTC (permalink / raw) To: Eli Zaretskii, sds; +Cc: emacs-devel On 03/07/2018 09:12 AM, Eli Zaretskii wrote: >> From: Sam Steingold <sds@gnu.org> >> Date: Tue, 06 Mar 2018 13:53:54 -0500 >> >>> * Daniel Colascione <qnapby@qnapby.bet> [2018-03-06 08:38:28 -0800]: >>> >>>> ... >>> >>> How would you serialize the result? >> >> This is actually the question that bothers me too. >> I think we need to separate "visual" indentation for word processing >> from "semantic" indentation for coding. >> The former should be serialized to something like HTML or LaTeX, >> and the latter to plain text as it is done now. > > Take a look at enriched.el (and etc/enriched.txt as the demonstration > of its capabilities): we already have the capability for serializing > this, had it for many years. That's fine so long as you have a file you want to edit _only_ with Emacs. Files that need to be understood by other tools would need information about indentation adjustment included in some compatible way (maybe a comment), but since other tools would know nothing of this information, it would go out of date. Requiring that people edit a source file only with Emacs is not realistic. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 19:38 ` Daniel Colascione @ 2018-03-07 20:11 ` Eli Zaretskii 2018-03-07 23:01 ` Richard Stallman 1 sibling, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 20:11 UTC (permalink / raw) To: Daniel Colascione; +Cc: sds, emacs-devel > Cc: emacs-devel@gnu.org > From: Daniel Colascione <dancol@dancol.org> > Date: Wed, 7 Mar 2018 11:38:47 -0800 > > > Take a look at enriched.el (and etc/enriched.txt as the demonstration > > of its capabilities): we already have the capability for serializing > > this, had it for many years. > > That's fine so long as you have a file you want to edit _only_ with > Emacs. Files that need to be understood by other tools would need > information about indentation adjustment included in some compatible way > (maybe a comment), but since other tools would know nothing of this > information, it would go out of date. Requiring that people edit a > source file only with Emacs is not realistic. Same thing happens with files produced by Office, no? Why do we require Emacs to do something different? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 19:38 ` Daniel Colascione 2018-03-07 20:11 ` Eli Zaretskii @ 2018-03-07 23:01 ` Richard Stallman 2018-03-08 12:33 ` Robert Pluim 1 sibling, 1 reply; 253+ messages in thread From: Richard Stallman @ 2018-03-07 23:01 UTC (permalink / raw) To: Daniel Colascione; +Cc: eliz, sds, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > Take a look at enriched.el (and etc/enriched.txt as the demonstration > > of its capabilities): we already have the capability for serializing > > this, had it for many years. > That's fine so long as you have a file you want to edit _only_ with > Emacs. Files that need to be understood by other tools would need > information about indentation adjustment included in some compatible way > (maybe a comment), but since other tools would know nothing of this > information, it would go out of date. Requiring that people edit a > source file only with Emacs is not realistic. I agree. One of the features we will want is to make Emacs able to read and write ODT format and RTF, even if at first it can only handle subsets of their features. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 23:01 ` Richard Stallman @ 2018-03-08 12:33 ` Robert Pluim 2018-03-08 13:50 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Robert Pluim @ 2018-03-08 12:33 UTC (permalink / raw) To: Richard Stallman; +Cc: sds, eliz, Daniel Colascione, emacs-devel Richard Stallman <rms@gnu.org> writes: > [[[ To any NSA and FBI agents reading my email: please consider ]]] > [[[ whether defending the US Constitution against all enemies, ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > > > Take a look at enriched.el (and etc/enriched.txt as the demonstration > > > of its capabilities): we already have the capability for serializing > > > this, had it for many years. > > > That's fine so long as you have a file you want to edit _only_ with > > Emacs. Files that need to be understood by other tools would need > > information about indentation adjustment included in some compatible way > > (maybe a comment), but since other tools would know nothing of this > > information, it would go out of date. Requiring that people edit a > > source file only with Emacs is not realistic. > > I agree. One of the features we will want > is to make Emacs able to read and write ODT format and RTF, > even if at first it can only handle subsets of their features. I'm still not clear on the goals here, and this makes things even less clear. As others have mentioned, LibreOffice exists, so why does Emacs need to be able to read and write ODT? [1] Robert Footnotes: [1] Note that you can already indirectly write to ODT if you start with org and use an exporter ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 12:33 ` Robert Pluim @ 2018-03-08 13:50 ` Eli Zaretskii 2018-03-08 15:15 ` Robert Pluim 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-08 13:50 UTC (permalink / raw) To: Robert Pluim; +Cc: emacs-devel > From: Robert Pluim <rpluim@gmail.com> > Cc: Daniel Colascione <dancol@dancol.org>, eliz@gnu.org, sds@gnu.org, emacs-devel@gnu.org > Date: Thu, 08 Mar 2018 13:33:01 +0100 > > > > (maybe a comment), but since other tools would know nothing of this > > > information, it would go out of date. Requiring that people edit a > > > source file only with Emacs is not realistic. > > > > I agree. One of the features we will want > > is to make Emacs able to read and write ODT format and RTF, > > even if at first it can only handle subsets of their features. > > I'm still not clear on the goals here, and this makes things even less > clear. As others have mentioned, LibreOffice exists, so why does Emacs > need to be able to read and write ODT? [1] So that we could exchange documents with users of Office. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 13:50 ` Eli Zaretskii @ 2018-03-08 15:15 ` Robert Pluim 0 siblings, 0 replies; 253+ messages in thread From: Robert Pluim @ 2018-03-08 15:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Robert Pluim <rpluim@gmail.com> >> Cc: Daniel Colascione <dancol@dancol.org>, eliz@gnu.org, sds@gnu.org, emacs-devel@gnu.org >> Date: Thu, 08 Mar 2018 13:33:01 +0100 >> >> > > (maybe a comment), but since other tools would know nothing of this >> > > information, it would go out of date. Requiring that people edit a >> > > source file only with Emacs is not realistic. >> > >> > I agree. One of the features we will want >> > is to make Emacs able to read and write ODT format and RTF, >> > even if at first it can only handle subsets of their features. >> >> I'm still not clear on the goals here, and this makes things even less >> clear. As others have mentioned, LibreOffice exists, so why does Emacs >> need to be able to read and write ODT? [1] > > So that we could exchange documents with users of Office. OK. I personally have no such goal (at least not with Emacs involved), and I can't understand why people would want to, but everyone gets to scratch their own itch. Robert ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 1:30 ` Paul Eggert 2018-03-06 1:40 ` Clément Pit-Claudel 2018-03-06 16:16 ` Eli Zaretskii @ 2018-03-06 20:52 ` Richard Stallman 2 siblings, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-06 20:52 UTC (permalink / raw) To: Paul Eggert; +Cc: cpitclaudel, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] I don't see a reason to use variable-width fonts except when they provide an improvement. For ASCII art, a fixed-width font is best. I don't see a reason to use variable-width fonts for code, but if people like that, I'm in favor of supporting it. The place where variable-width fonts, and multiple fonts of different width, are really important is for editing documents with formatted text. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 20:28 ` Variable-width font indentation Clément Pit-Claudel 2018-03-05 22:30 ` Paul Eggert @ 2018-03-06 4:05 ` Herring, Davis 2018-03-06 13:33 ` Clément Pit-Claudel 2018-03-06 16:11 ` Eli Zaretskii 2018-03-06 16:35 ` Stefan Monnier 3 siblings, 1 reply; 253+ messages in thread From: Herring, Davis @ 2018-03-06 4:05 UTC (permalink / raw) To: Clément Pit-Claudel, emacs-devel@gnu.org; +Cc: Paul Eggert > I don't know of a good solution to this problem: in general, > there's not enough information to distinguish 'indentation' > spaces (the two spaces before `printf (', `pr ()', and `return 0') > and 'line-up' spaces (the spaces before `char ()'). This is of course an argument in favor of "smart tabs" <https://www.emacswiki.org/emacs/SmartTabs>: you make each tab occupy some user-specified width, and _then_ count one character per space to do alignment. That doesn't help if those tabs aren't present, although heuristics to detect certain exact numbers of spaces, comparing to the previous lines and looking for enclosing delimiters, might close enough of the gap between "treat all spaces as ASCII art alignment" and the ideal. Davis ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 4:05 ` Herring, Davis @ 2018-03-06 13:33 ` Clément Pit-Claudel 2018-03-06 14:18 ` Herring, Davis 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 13:33 UTC (permalink / raw) To: Herring, Davis, emacs-devel@gnu.org; +Cc: Paul Eggert On 2018-03-05 23:05, Herring, Davis wrote: >> I don't know of a good solution to this problem: in general, >> there's not enough information to distinguish 'indentation' >> spaces (the two spaces before `printf (', `pr ()', and `return 0') >> and 'line-up' spaces (the spaces before `char ()'). > > This is of course an argument in favor of "smart tabs" <https://www.emacswiki.org/emacs/SmartTabs> No, not really: smart tabs aren't enough AFAICT. Take the following example: match opt with | [] -> [] | x :: t -> x :: f t You'd want to scale the spaces according to the line *below*, not ebove, and even then you'd have to account for the fact that 'x ' isn't as wide as '[]'. Smart Tabs are also not very good for languages like ELisp with variable indentation depths. If anything, I think this is more of an argument in favor of elastic tabs (http://nickgravgaard.com/elastic-tabstops/). Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 13:33 ` Clément Pit-Claudel @ 2018-03-06 14:18 ` Herring, Davis 2018-03-06 15:02 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Herring, Davis @ 2018-03-06 14:18 UTC (permalink / raw) To: Clément Pit-Claudel, emacs-devel@gnu.org; +Cc: Paul Eggert > match opt with > | [] -> [] > | x :: t -> x :: f t > > You'd want to scale the spaces according to the line *below*, not ebove, As per your other message, that's a problem regardless of tab handling. Yet more heuristics suggest themselves (in this case, looking for text shared between two adjacent lines to guide the alignment), but of course those are becoming a mess. > and even then you'd have to account for the fact that 'x ' isn't as wide as '[]'. Maybe I misunderstand -- how is this a problem? If the number of spaces is correct, it identifies the correct character to match against. > Smart Tabs are also not very good for languages like ELisp with variable indentation depths. Which cases are hard? I just see several places where you would use only spaces (_): (progn >-(foo) >-(bar)) (and _(foo) _(bar)) (and (foo) _____(bar)) > If anything, I think this is more of an argument in favor of > elastic tabs (http://nickgravgaard.com/elastic-tabstops/). Those are certainly interesting, but they have their own ambiguities (e.g., int>-x>-= 1, >-y>-=2; doTheFoo();>-// it's true doTheBar();>-// so far where there should not be a "column block" 4 lines tall). They also of course do not play well with existing rendering (monospace or otherwise). Davis ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 14:18 ` Herring, Davis @ 2018-03-06 15:02 ` Clément Pit-Claudel 0 siblings, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 15:02 UTC (permalink / raw) To: Herring, Davis, emacs-devel@gnu.org; +Cc: Paul Eggert On 2018-03-06 09:18, Herring, Davis wrote: > Maybe I misunderstand -- how is this a problem? If the number of spaces is correct, it identifies the correct character to match against. It's a problem if you scale each space to match the width of the character above it (or below it, in this case). If you instead align to a particular position, you run into the issue of deciding which space to stretch (strech all spaces in the range evenly? stretch a single one? what about cases where the spaces need to be shrunk?) > (progn > >-(foo) > >-(bar)) > > (and > _(foo) > _(bar)) I have a lot of trouble reading these examples, as the '>' get converted to reply markers by my email client; but looking at the source, I think I understand. Question: why do you indent the body of a 'progn' differently from an 'and'? I was thinking of cases like 'if', for example: (if test true-case false-case) Where do you use tabs? > > int>-x>-= 1, > >-y>-=2; > doTheFoo();>-// it's true > doTheBar();>-// so far I don't think these are ambiguities (as in, the spec is clear on what should happen here); but indeed this doesn't render ideally; you'd write it like this instead: int x = 1, y = 2; doTheFoo(); // it's true doTheBar(); // so far (I personally don't like the concept very much, because it doesn't let you distinguish between a 0-width indentation marker and a non-zero width indentation marker). That is, it forces you to writ this: int f( int argc; char** argv) instead of int f(int argc; int argv) Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 20:28 ` Variable-width font indentation Clément Pit-Claudel 2018-03-05 22:30 ` Paul Eggert 2018-03-06 4:05 ` Herring, Davis @ 2018-03-06 16:11 ` Eli Zaretskii 2018-03-06 19:59 ` Clément Pit-Claudel 2018-03-06 16:35 ` Stefan Monnier 3 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 16:11 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Mon, 5 Mar 2018 15:28:05 -0500 > Cc: Paul Eggert <eggert@cs.ucla.edu> > > On 2018-03-05 14:58, Eli Zaretskii wrote: > > How does it know that today, when we only support well the > > fixed-pitch fonts? Or are you talking about a different problem? > > A different problem, IIUC. The problem is the following: > > Assume you wrote the following C code, then changed to variable-pitch: > > void pr () { > printf ("hello, world\n"); > } > > int main (int argc, > char** argv) { > pr (); > return 0; > } > > Depending on which font you use (and the width of a space in that font), the `char** argv' part will move right or left, instead of remaining aligned. The usual solution is to proceed as Paul suggested: > > > It assumes the input is fixed-width, and that leading white space is > > intended to indent with respect to previous lines. > > IOW, you scale the spaces preceding `char** argv' to make the `c' of `char' line up with the `i' of int. I think I'm still missing something, because I don't understand why we need to invent/use a strategy different from what we do now in code indentation. All we need to do to extend the existing machinery to variable-pitch fonts is (1) to replace current-column with a function that returns floats instead of integers (or teach current-column do that given some optional argument), and (b) place a 'space' display property on the leading whitespace with an :align-to attribute computed to align the first non-white character at the "column number" returned as result of (a) above. All the rest is already in place, right? Also note that Richard was specifically talking about text modes, not about programming modes. Indentation in text modes has a slightly different goal. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:11 ` Eli Zaretskii @ 2018-03-06 19:59 ` Clément Pit-Claudel 2018-03-06 20:31 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 19:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-06 11:11, Eli Zaretskii wrote: > I think I'm still missing something, because I don't understand why we > need to invent/use a strategy different from what we do now in code > indentation. [...] All the rest is already in place, > right? I think I know where the misunderstanding is coming from. We're thinking of two unrelated things: * Paul and I have been discussing an language-agnostic heuristic to preserve alignment when changing from monospace to variable-pitch faces. This intends to preserve the original indentation of the code, by inferring what it would have been if the logic originally used to indent the document had been aware of variable-pitch faces. * You're describing a language-specific way to get a nice-looking variable-pitch rendering of a document; your way is to reindent the document, essentially. Does this make sense? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 19:59 ` Clément Pit-Claudel @ 2018-03-06 20:31 ` Eli Zaretskii 2018-03-06 21:15 ` Paul Eggert 2018-03-06 21:47 ` Clément Pit-Claudel 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 20:31 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Tue, 6 Mar 2018 14:59:21 -0500 > > * Paul and I have been discussing an language-agnostic heuristic to preserve alignment when changing from monospace to variable-pitch faces. This intends to preserve the original indentation of the code, by inferring what it would have been if the logic originally used to indent the document had been aware of variable-pitch faces. I don't see a need for such a feature, sorry. We have indentation already; its only problem is that it doesn't work well with variable pitch fonts. That's what we need to try to fix, if we care about the capability of displaying program code with such fonts. > * You're describing a language-specific way to get a nice-looking variable-pitch rendering of a document; your way is to reindent the document, essentially. I was describing a way of teaching the existing indentation code handle variable-pitch fonts. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 20:31 ` Eli Zaretskii @ 2018-03-06 21:15 ` Paul Eggert 2018-03-06 21:47 ` Clément Pit-Claudel 1 sibling, 0 replies; 253+ messages in thread From: Paul Eggert @ 2018-03-06 21:15 UTC (permalink / raw) To: Eli Zaretskii, Clément Pit-Claudel; +Cc: emacs-devel On 03/06/2018 12:31 PM, Eli Zaretskii wrote: > We have indentation > already; its only problem is that it doesn't work well with variable > pitch fonts. As I understood it, Clément wrote a quick-and-dirty algorithm to simulate better indentation with variable-width fonts. That is, it wasn't intended to be something that should go into Emacs, only as a way to see what the the user would see if we changed Emacs's display of indentation to be along the suggested lines. Unless I'm misunderstanding, his work provided a simple proof-of-concept that a relatively-inexpensive way of improving indentation would significantly improve display with variable-width fonts. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 20:31 ` Eli Zaretskii 2018-03-06 21:15 ` Paul Eggert @ 2018-03-06 21:47 ` Clément Pit-Claudel 2018-03-07 17:22 ` Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 21:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-06 15:31, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Tue, 6 Mar 2018 14:59:21 -0500 >> >> * Paul and I have been discussing an language-agnostic heuristic to preserve alignment when changing from monospace to variable-pitch faces. This intends to preserve the original indentation of the code, by inferring what it would have been if the logic originally used to indent the document had been aware of variable-pitch faces. > > I don't see a need for such a feature, sorry. We have indentation > already; its only problem is that it doesn't work well with variable > pitch fonts. That's what we need to try to fix, if we care about the > capability of displaying program code with such fonts. I'm thoroughly confused: doesn't the algorithm that Paul proposed, and that I show an implementation of, do exactly that? Do you want to get the indentation code involved because the heuristic isn't perfect? >> * You're describing a language-specific way to get a nice-looking variable-pitch rendering of a document; your way is to reindent the document, essentially. > > I was describing a way of teaching the existing indentation code > handle variable-pitch fonts. Right, which is where we differ: the solution Paul and I have been thinking is designed not to rely on exiting indentation facilities. In your world, concretely, what happens when I open xdisp.c and press M-x variable-pitch-mode? Does everything look misaligned until I M-x indent-region the whole file? What about a file from a different project that uses a different indenting convention? Thanks, Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 21:47 ` Clément Pit-Claudel @ 2018-03-07 17:22 ` Eli Zaretskii 2018-03-07 18:27 ` Clément Pit-Claudel 2018-03-08 4:50 ` Stefan Monnier 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 17:22 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Tue, 6 Mar 2018 16:47:51 -0500 > > > I don't see a need for such a feature, sorry. We have indentation > > already; its only problem is that it doesn't work well with variable > > pitch fonts. That's what we need to try to fix, if we care about the > > capability of displaying program code with such fonts. > > I'm thoroughly confused: doesn't the algorithm that Paul proposed, and that I show an implementation of, do exactly that? Not AFAIU, no. It is an implementation of a different indentation method. I don't see why we should want to go that way, since there's nothing wrong with the existing algorithm, except for handling of variable-pitch fonts. > Do you want to get the indentation code involved because the heuristic isn't perfect? More like because the existing indentation algorithms are okay, and I see no need to change them to something else. > In your world, concretely, what happens when I open xdisp.c and press M-x variable-pitch-mode? Does everything look misaligned until I M-x indent-region the whole file? Yes. It isn't different from what happens when you change tab-width. > What about a file from a different project that uses a different indenting convention? Not sure how that is relevant. A different indentation convention will look differently, of course. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 17:22 ` Eli Zaretskii @ 2018-03-07 18:27 ` Clément Pit-Claudel 2018-03-07 20:09 ` Eli Zaretskii 2018-03-08 4:50 ` Stefan Monnier 1 sibling, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-07 18:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-07 12:22, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Tue, 6 Mar 2018 16:47:51 -0500 >> >>> I don't see a need for such a feature, sorry. We have indentation >>> already; its only problem is that it doesn't work well with variable >>> pitch fonts. That's what we need to try to fix, if we care about the >>> capability of displaying program code with such fonts. >> >> I'm thoroughly confused: doesn't the algorithm that Paul proposed, and that I show an implementation of, do exactly that? > > Not AFAIU, no. It is an implementation of a different indentation > method. I don't see why we should want to go that way, since there's > nothing wrong with the existing algorithm, except for handling of > variable-pitch fonts. Can you clarify what you call an indentation method? I think that's the source of my confusion. I wouldn't call what I wrote an indentation method. Maybe I'm not understanding you because of that? >> Do you want to get the indentation code involved because the heuristic isn't perfect? > > More like because the existing indentation algorithms are okay, and I > see no need to change them to something else. Neither do I, and indeed I'm not proposing to change existing indentation algorithms :) >> In your world, concretely, what happens when I open xdisp.c and press M-x variable-pitch-mode? Does everything look misaligned until I M-x indent-region the whole file? > > Yes. It isn't different from what happens when you change tab-width. But changing tab-width doesn't change the contents of the buffer, whereas what you're advocating for does, right? >> What about a file from a different project that uses a different indenting convention? > > Not sure how that is relevant. A different indentation convention > will look differently, of course. This is relevant because the method that Paul originally proposed (which I'm not even advocating for — I'm not even sure yet whether it's good or bad) does not require changing the buffer or the actual number of spaces present on each line in the buffer. Maybe I just don't understand what you're advocating for. AFAIU, you're suggesting that we should teach indentation methods about variable-pitch fonts, so that they indent text to a particular pixel offset instead of a particular column. Is that correct? If it is correct, then it solves a problem that's different from the one I was thinking in, which is to display existing code with a variable pitch font, without the indentation function. Some questions on the solution you propose: * What happens in major modes that don't provide indentation support? * What happens in indentation-sensitive languages (Python, F#, Haskell, etc)? * What happens in comments? * Do I need to call M-x indent-region every time I switch between variable-pitch and fixed-pitch? * If I close and reopen a file in variable-pitch mode, do I need to re-run M-x indent-region? * In variable-pitch mode, what gets saved to disk after I run M-x indent-region? Thanks, Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 18:27 ` Clément Pit-Claudel @ 2018-03-07 20:09 ` Eli Zaretskii 2018-03-07 20:32 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 20:09 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 7 Mar 2018 13:27:35 -0500 > > > Not AFAIU, no. It is an implementation of a different indentation > > method. I don't see why we should want to go that way, since there's > > nothing wrong with the existing algorithm, except for handling of > > variable-pitch fonts. > > Can you clarify what you call an indentation method? I think that's the source of my confusion. > I wouldn't call what I wrote an indentation method. Maybe I'm not understanding you because of that? I feel that we are somehow bogged down in a miscommunication from which I see no way out... An "indentation method" is a method used to determine the indentation of a line and to insert whitespace in order to achieve that indentation. > >> In your world, concretely, what happens when I open xdisp.c and press M-x variable-pitch-mode? Does everything look misaligned until I M-x indent-region the whole file? > > > > Yes. It isn't different from what happens when you change tab-width. > > But changing tab-width doesn't change the contents of the buffer, whereas what you're advocating for does, right? No, it doesn't. I'm advocating a way of changing the width of whitespace characters on display to account for variable-pitch font, not any change in the buffer. > Maybe I just don't understand what you're advocating for. AFAIU, you're suggesting that we should teach indentation methods about variable-pitch fonts, so that they indent text to a particular pixel offset instead of a particular column. Is that correct? Yes, correct. > If it is correct, then it solves a problem that's different from the one I was thinking in, which is to display existing code with a variable pitch font, without the indentation function. We cannot possibly DTRT with indentation without an indentation function. > * What happens in major modes that don't provide indentation support? The same as what happens today: the default functions are invoked. > * What happens in indentation-sensitive languages (Python, F#, Haskell, etc)? Same as today (the buffer contents will not change from what it is today). > * What happens in comments? Nothing special. > * Do I need to call M-x indent-region every time I switch between variable-pitch and fixed-pitch? Not necessarily, not if the idea of controlling the SPC width is workable. If it is, then the mode will simply set the value of two buffer-local variables, calculating them from the font in use. > * If I close and reopen a file in variable-pitch mode, do I need to re-run M-x indent-region? See above. > * In variable-pitch mode, what gets saved to disk after I run M-x indent-region? Same as what we have now. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 20:09 ` Eli Zaretskii @ 2018-03-07 20:32 ` Clément Pit-Claudel 2018-03-08 15:39 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-07 20:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-07 15:09, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Wed, 7 Mar 2018 13:27:35 -0500 >> >>> Not AFAIU, no. It is an implementation of a different indentation >>> method. I don't see why we should want to go that way, since there's >>> nothing wrong with the existing algorithm, except for handling of >>> variable-pitch fonts. >> >> Can you clarify what you call an indentation method? I think that's the source of my confusion. >> I wouldn't call what I wrote an indentation method. Maybe I'm not understanding you because of that? > > I feel that we are somehow bogged down in a miscommunication from > which I see no way out... I think we're making progress, actually :) At least, I'm understanding things better. > An "indentation method" is a method used to determine the indentation > of a line and to insert whitespace in order to achieve that > indentation. Understood. Then what I'm offering isn't an indentation method: it doesn't insert whitespace. But what I'm offering is indeed an imperfect heuristic to determine the indentation of a line. >> But changing tab-width doesn't change the contents of the buffer, whereas what you're advocating for does, right? > > No, it doesn't. I'm advocating a way of changing the width of > whitespace characters on display to account for variable-pitch font, > not any change in the buffer. OK, understood. So for example if I have this snippet: 01234567 -------- 0 |x = (y + 1 | z) …then on line 1 the indentation function would put display properties on each of the 5 spaces leading to `z` to align it with the `y`. Correct? That's also what I do, only I compute the width of the spaces without calling the indentation function. >> If it is correct, then it solves a problem that's different from the one I was thinking in, which is to display existing code with a variable pitch font, without the indentation function. > > We cannot possibly DTRT with indentation without an indentation > function. Well, no, we can't DTRT every time without an indentation function. But we can do fairly good, or at least it looks like that to me given the snippet I posted earlier. (But note that I said the same thing at first, responding to Paul that his technique couldn't work.) >> * What happens in major modes that don't provide indentation support? > > The same as what happens today: the default functions are invoked. I don't understand this part. Concretely, what will the snippet above look like if it's shown in a prog-mode buffer, in a variable-pitch font? Will the indentation just be off? >> * What happens in indentation-sensitive languages (Python, F#, Haskell, etc)? > > Same as today (the buffer contents will not change from what it is > today). I meant to ask what the code would look like, not what the buffer contents would change to. >> * What happens in comments? > > Nothing special. Same question: what do the contents look like (what text properties do you apply on leading spaces in comments?) For example, if I have this in a C buffer: /* FIXME: - long text here - more text */ what will this look like in variable-pitch mode? >> * Do I need to call M-x indent-region every time I switch between variable-pitch and fixed-pitch? > > Not necessarily, not if the idea of controlling the SPC width is > workable. If it is, then the mode will simply set the value of two > buffer-local variables, calculating them from the font in use. That I don't understand. Which two values are you thinking of? As another concrete example, consider this snippet: (do-stuff a b c) won't you need to recompute the width of each leading space every time you change fonts? >> * If I close and reopen a file in variable-pitch mode, do I need to re-run M-x indent-region? I don't understand this part either: ow will you determine how to scale each space without calling the indentation function? >> * In variable-pitch mode, what gets saved to disk after I run M-x indent-region? > > Same as what we have now. OK. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 20:32 ` Clément Pit-Claudel @ 2018-03-08 15:39 ` Eli Zaretskii 2018-03-08 16:30 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-08 15:39 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 7 Mar 2018 15:32:53 -0500 > > >> But changing tab-width doesn't change the contents of the buffer, whereas what you're advocating for does, right? > > > > No, it doesn't. I'm advocating a way of changing the width of > > whitespace characters on display to account for variable-pitch font, > > not any change in the buffer. > > OK, understood. So for example if I have this snippet: > > 01234567 > -------- > 0 |x = (y + > 1 | z) > > …then on line 1 the indentation function would put display properties on each of the 5 spaces leading to `z` to align it with the `y`. Correct? Not necessarily display properties, maybe some (most? all?) of the effect could be achieved by modifying the display width of a space and a tab according to some buffer-local variable, by the display code itself, similarly to how we render tab characters now. > >> * What happens in major modes that don't provide indentation support? > > > > The same as what happens today: the default functions are invoked. > > I don't understand this part. Concretely, what will the snippet above look like if it's shown in a prog-mode buffer, in a variable-pitch font? Will the indentation just be off? When a major mode doesn't provide an indentation function, indent.el uses the default function, so I'm not sure what problem you see here. > >> * What happens in indentation-sensitive languages (Python, F#, Haskell, etc)? > > > > Same as today (the buffer contents will not change from what it is > > today). > > I meant to ask what the code would look like, not what the buffer contents would change to. Hopefully, the buffer will look like users of those languages expect it to look. > >> * What happens in comments? > > > > Nothing special. > > Same question: what do the contents look like (what text properties do you apply on leading spaces in comments?) I hope we will be able to manage without display properties at all. > For example, if I have this in a C buffer: > > /* FIXME: > - long > text > here > - more text */ > > what will this look like in variable-pitch mode? Hopefully, very similar, although we won't be able to guarantee column-wise alignment for arbitrary text. But leading whitespace will certainly be aligned, something that is not universally true today. > >> * Do I need to call M-x indent-region every time I switch between variable-pitch and fixed-pitch? > > > > Not necessarily, not if the idea of controlling the SPC width is > > workable. If it is, then the mode will simply set the value of two > > buffer-local variables, calculating them from the font in use. > > That I don't understand. Which two values are you thinking of? tab-width and (the hypothetical) space-width. Actually, only the latter, since tab-width must be its integral multiple. > As another concrete example, consider this snippet: > > (do-stuff a > b > c) > > won't you need to recompute the width of each leading space every time you change fonts? Hopefully, no. At least not for approximate alignment. > >> * If I close and reopen a file in variable-pitch mode, do I need to re-run M-x indent-region? > > I don't understand this part either: ow will you determine how to scale each space without calling the indentation function? Hopefully, by calculating some representative metrics of the font. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 15:39 ` Eli Zaretskii @ 2018-03-08 16:30 ` Clément Pit-Claudel 2018-03-08 19:07 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-08 16:30 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-08 10:39, Eli Zaretskii wrote: >> From: Clément Pit-Claudel <cpitclaudel@gmail.com>buffer. >> >> OK, understood. So for example if I have this snippet: >> >> 01234567 >> -------- >> 0 |x = (y + >> 1 | z) >> >> …then on line 1 the indentation function would put display properties on each of the 5 spaces leading to `z` to align it with the `y`. Correct? > > Not necessarily display properties, maybe some (most? all?) of the > effect could be achieved by modifying the display width of a space and > a tab according to some buffer-local variable, by the display code > itself, similarly to how we render tab characters now. Hmm, interesting. How would that work? For example, if I have these two snippets: i = (y + z) w = (y + z) with monospace fonts 'i' and 'w' have the same width, but with variable-pitch fonts they don't and if you assign a constant width to each space the 'y' and 'z' will line up in at most one of the two examples, right? >>>> * What happens in major modes that don't provide indentation support? >>> >>> The same as what happens today: the default functions are invoked. >> >> I don't understand this part. Concretely, what will the snippet above look like if it's shown in a prog-mode buffer, in a variable-pitch font? Will the indentation just be off? > > When a major mode doesn't provide an indentation function, indent.el > uses the default function, so I'm not sure what problem you see here. I don't know what the default function is, or how it could help us determine proper alignment :/ I thought from earlier emails that you'd use existing indentation functions to determine proper indentation. >> For example, if I have this in a C buffer: >> >> /* FIXME: >> - long >> text >> here >> - more text */ >> >> what will this look like in variable-pitch mode? > > Hopefully, very similar, although we won't be able to guarantee > column-wise alignment for arbitrary text. But leading whitespace will > certainly be aligned, something that is not universally true today. Ah, that I understand :) I've been using the following for that purpose for a long time: (font-lock-add-keywords nil `(("^[[:space:]]+" 0 '(face fixed-pitch) append)) 'append) >>>> * Do I need to call M-x indent-region every time I switch between variable-pitch and fixed-pitch? >>> >>> Not necessarily, not if the idea of controlling the SPC width is >>> workable. If it is, then the mode will simply set the value of two >>> buffer-local variables, calculating them from the font in use. >> >> That I don't understand. Which two values are you thinking of? > > tab-width and (the hypothetical) space-width. Actually, only the > latter, since tab-width must be its integral multiple. OK, I see. This won't help with cases like the following, right? int main(int argv, char** argc) >> As another concrete example, consider this snippet: >> >> (do-stuff a >> b >> c) >> >> won't you need to recompute the width of each leading space every time you change fonts? > > Hopefully, no. At least not for approximate alignment. OK. I don't understand how that part works yet. The solution you propose doesn't get alignment right if I have the following ELisp code, right? (progn (wwwwwwww a b c) (iiiiiiii a b c)) >>>> * If I close and reopen a file in variable-pitch mode, do I need to re-run M-x indent-region? >> >> I don't understand this part either: ow will you determine how to scale each space without calling the indentation function? > > Hopefully, by calculating some representative metrics of the font. OK. I think I follow you at this point, although now I'm not sure anymore what role indentation functions will play. A few emails ago you mentioned teaching indentation functions about variable-pitch, but the solution you're offering now doesn't seem to require that anymore, does it? Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 16:30 ` Clément Pit-Claudel @ 2018-03-08 19:07 ` Eli Zaretskii 2018-03-08 19:55 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-08 19:07 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Thu, 8 Mar 2018 11:30:51 -0500 > > > Not necessarily display properties, maybe some (most? all?) of the > > effect could be achieved by modifying the display width of a space and > > a tab according to some buffer-local variable, by the display code > > itself, similarly to how we render tab characters now. > > Hmm, interesting. How would that work? For example, if I have these two snippets: > > i = (y + > z) > > w = (y + > z) > > with monospace fonts 'i' and 'w' have the same width, but with variable-pitch fonts they don't and if you assign a constant width to each space the 'y' and 'z' will line up in at most one of the two examples, right? Maybe we could find a middle ground, whereby each one of the examples will approximately align. If that can be done, and the result is acceptable, then the problem of recording the text properties in the file and/or reindenting when the file is revisited goes away. > >>>> * What happens in major modes that don't provide indentation support? > >>> > >>> The same as what happens today: the default functions are invoked. > >> > >> I don't understand this part. Concretely, what will the snippet above look like if it's shown in a prog-mode buffer, in a variable-pitch font? Will the indentation just be off? > > > > When a major mode doesn't provide an indentation function, indent.el > > uses the default function, so I'm not sure what problem you see here. > > I don't know what the default function is, or how it could help us determine proper alignment :/ Looking in indent.el, my reading of the code is that the default function is indent-rigidly. > I've been using the following for that purpose for a long time: > > (font-lock-add-keywords nil `(("^[[:space:]]+" 0 '(face fixed-pitch) append)) 'append) Is it really needed? With most font back-ends, a tab is displayed as a stretch glyph whose width is an integral multiple of the width of the space glyph for the same font. So they should align even without the fixed-pitch font trick. > >>> Not necessarily, not if the idea of controlling the SPC width is > >>> workable. If it is, then the mode will simply set the value of two > >>> buffer-local variables, calculating them from the font in use. > >> > >> That I don't understand. Which two values are you thinking of? > > > > tab-width and (the hypothetical) space-width. Actually, only the > > latter, since tab-width must be its integral multiple. > > OK, I see. This won't help with cases like the following, right? > > int main(int argv, > char** argc) It might get reasonably close, though. Maybe this will be good enough. > OK. I think I follow you at this point, although now I'm not sure anymore what role indentation functions will play. A few emails ago you mentioned teaching indentation functions about variable-pitch, but the solution you're offering now doesn't seem to require that anymore, does it? That's more relevant for text-derived modes, where indentation levels are rigid and not determined by previous lines. There we could do a better job, I hope. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 19:07 ` Eli Zaretskii @ 2018-03-08 19:55 ` Clément Pit-Claudel 2018-03-09 8:30 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-08 19:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-08 14:07, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Thu, 8 Mar 2018 11:30:51 -0500 >> >>> Not necessarily display properties, maybe some (most? all?) of the >>> effect could be achieved by modifying the display width of a space and >>> a tab according to some buffer-local variable, by the display code >>> itself, similarly to how we render tab characters now. >> >> Hmm, interesting. How would that work? For example, if I have these two snippets: >> >> i = (y + >> z) >> >> w = (y + >> z) >> >> with monospace fonts 'i' and 'w' have the same width, but with variable-pitch fonts they don't and if you assign a constant width to each space the 'y' and 'z' will line up in at most one of the two examples, right? > > Maybe we could find a middle ground, whereby each one of the examples > will approximately align. If that can be done, and the result is > acceptable, then the problem of recording the text properties in the > file and/or reindenting when the file is revisited goes away. Maybe :) I don't know how good it would look, in practice, but it's easy to experiment. Paul's algorithm is not too bad in that sense: these two examples align pixel-perfectly. >> I've been using the following for that purpose for a long time: >> >> (font-lock-add-keywords nil `(("^[[:space:]]+" 0 '(face fixed-pitch) append)) 'append) > > Is it really needed? With most font back-ends, a tab is displayed as > a stretch glyph whose width is an integral multiple of the width of > the space glyph for the same font. So they should align even without > the fixed-pitch font trick. Hmm, indeed. So which problems did you have in mind when you said the following? > But leading whitespace will certainly be aligned, something that is > not universally true today. >> OK, I see. This won't help with cases like the following, right? >> >> int main(int argv, >> char** argc) > > It might get reasonably close, though. Maybe this will be good > enough. OK >> OK. I think I follow you at this point, although now I'm not sure anymore what role indentation functions will play. A few emails ago you mentioned teaching indentation functions about variable-pitch, but the solution you're offering now doesn't seem to require that anymore, does it? > > That's more relevant for text-derived modes, where indentation levels > are rigid and not determined by previous lines. There we could do a > better job, I hope. OK. I tend to think of indentation even in text modes as being somewhat previous-lines dependent (wrapped paragraphs align relative to bullet points, for example), but I agree that it isn't as much as in programming modes. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 19:55 ` Clément Pit-Claudel @ 2018-03-09 8:30 ` Eli Zaretskii 2018-03-09 17:52 ` Paul Eggert 2018-03-09 19:48 ` Clément Pit-Claudel 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-09 8:30 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Thu, 8 Mar 2018 14:55:20 -0500 > > > Maybe we could find a middle ground, whereby each one of the examples > > will approximately align. If that can be done, and the result is > > acceptable, then the problem of recording the text properties in the > > file and/or reindenting when the file is revisited goes away. > > Maybe :) I don't know how good it would look, in practice, but it's easy to experiment. > Paul's algorithm is not too bad in that sense: these two examples align pixel-perfectly. Yes, but as I said, I don't think that approach is appropriate for code indentation, because leading whitespace in code blocks _must_ always align, IMO. IOW, that approach seems to favor alignment of multi-line code sequences to alignment of indented blocks, and I think programming modes should have the opposite preference. > > Is it really needed? With most font back-ends, a tab is displayed as > > a stretch glyph whose width is an integral multiple of the width of > > the space glyph for the same font. So they should align even without > > the fixed-pitch font trick. > > Hmm, indeed. So which problems did you have in mind when you said the following? > > > But leading whitespace will certainly be aligned, something that is > > not universally true today. At least the w32 font back-end doesn't fulfill that requirement, because it calculates the font's space width differently (due to practical problems related to the MS-Windows APIs). Not sure about ns. > > That's more relevant for text-derived modes, where indentation levels > > are rigid and not determined by previous lines. There we could do a > > better job, I hope. > > OK. I tend to think of indentation even in text modes as being somewhat previous-lines dependent (wrapped paragraphs align relative to bullet points, for example), but I agree that it isn't as much as in programming modes. IME, indentation of text in word processors I use does not depend on previous lines at all. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 8:30 ` Eli Zaretskii @ 2018-03-09 17:52 ` Paul Eggert 2018-03-09 18:35 ` Eli Zaretskii 2018-03-09 19:48 ` Clément Pit-Claudel 1 sibling, 1 reply; 253+ messages in thread From: Paul Eggert @ 2018-03-09 17:52 UTC (permalink / raw) To: Eli Zaretskii, Clément Pit-Claudel; +Cc: emacs-devel On 03/09/2018 12:30 AM, Eli Zaretskii wrote: > I don't think that approach is appropriate for > code indentation, because leading whitespace in code blocks_must_ > always align, IMO. I don't quite follow this objection, since the prototype does align leading whitespace in code blocks. That is, in any particular block of code consisting of lines prefaced by equivalent white space, the approach displays the block with equally-indented lines, so the leading whitespace does align. If the objection is that different blocks of code are indented differently (e.g., an if-part might be indented slightly differently from the corresponding then-part), then I agree that might irritate some users. However, the irritation is quite small to me, and I imagine it wouldn't bother other users much either, in the sense that they'll be willing to put up with this minor irritation in order to get the benefits that the algorithm has elsewhere. So it still sounds like a reasonable thing to support, if a user wants to use it. Of course other display algorithms are possible, but I haven't seen any other improvement proposed for variable-pitch fonts that is nearly as simple and easy to understand. Simplicity is a virtue here. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 17:52 ` Paul Eggert @ 2018-03-09 18:35 ` Eli Zaretskii 2018-03-09 20:16 ` Paul Eggert 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-09 18:35 UTC (permalink / raw) To: Paul Eggert; +Cc: cpitclaudel, emacs-devel > Cc: emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Fri, 9 Mar 2018 09:52:28 -0800 > > If the objection is that different blocks of code are indented > differently (e.g., an if-part might be indented slightly differently > from the corresponding then-part), then I agree that might irritate some > users. However, the irritation is quite small to me, and I imagine it > wouldn't bother other users much either Well, it bothers me a lot, to the degree that I don't think it could fly. > Of course other display algorithms are possible, but I haven't seen any > other improvement proposed for variable-pitch fonts that is nearly as > simple and easy to understand. Simplicity is a virtue here. Simplicity is a virtue if it gets the job done. This particular suggestion doesn't, IMO. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 18:35 ` Eli Zaretskii @ 2018-03-09 20:16 ` Paul Eggert 2018-03-09 21:19 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Paul Eggert @ 2018-03-09 20:16 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cpitclaudel, emacs-devel On 03/09/2018 10:35 AM, Eli Zaretskii wrote: > it bothers me a lot, to the degree that I don't think it could > fly I've tried it and it flies for me, and it doesn't appear that I'm alone in this opinion. Although it's not perfect, it's significantly better than what Emacs does now for variable-pitch fonts. So I'm in favor of having this feature available as a user option. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 20:16 ` Paul Eggert @ 2018-03-09 21:19 ` Eli Zaretskii 2018-03-09 21:55 ` Paul Eggert 2018-03-10 0:09 ` James Cloos 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-09 21:19 UTC (permalink / raw) To: Paul Eggert; +Cc: cpitclaudel, emacs-devel > Cc: cpitclaudel@gmail.com, emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Fri, 9 Mar 2018 12:16:54 -0800 > > On 03/09/2018 10:35 AM, Eli Zaretskii wrote: > > it bothers me a lot, to the degree that I don't think it could > > fly > > I've tried it and it flies for me, and it doesn't appear that I'm alone > in this opinion. I'm not alone in my opinion, either. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 21:19 ` Eli Zaretskii @ 2018-03-09 21:55 ` Paul Eggert 2018-03-10 0:09 ` James Cloos 1 sibling, 0 replies; 253+ messages in thread From: Paul Eggert @ 2018-03-09 21:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cpitclaudel, emacs-devel Eli Zaretskii wrote: >> I've tried it and it flies for me, and it doesn't appear that I'm alone >> in this opinion. > I'm not alone in my opinion, either. I've heard other opinions that the approach is not to their taste. But I haven't heard anyone else say that the approach should not be available, even as a user option. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 21:19 ` Eli Zaretskii 2018-03-09 21:55 ` Paul Eggert @ 2018-03-10 0:09 ` James Cloos 2018-03-10 8:20 ` Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: James Cloos @ 2018-03-10 0:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cpitclaudel, Paul Eggert, emacs-devel I've long thought that a good start is to show the initial whitespace in fixed width. That doesn't cover aligning things like the right column of *-boxes, but is a good start and has low-complexity. -JimC -- James Cloos <cloos@jhcloos.com> OpenPGP: 0x997A9F17ED7DAEA6 ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 0:09 ` James Cloos @ 2018-03-10 8:20 ` Eli Zaretskii 2018-03-10 19:48 ` James Cloos 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 8:20 UTC (permalink / raw) To: James Cloos; +Cc: cpitclaudel, eggert, emacs-devel > From: James Cloos <cloos@jhcloos.com> > Cc: Paul Eggert <eggert@cs.ucla.edu>, cpitclaudel@gmail.com, emacs-devel@gnu.org > Date: Fri, 09 Mar 2018 19:09:23 -0500 > > I've long thought that a good start is to show the initial whitespace in > fixed width. > > That doesn't cover aligning things like the right column of *-boxes, but > is a good start and has low-complexity. I'm curious: why do you think this would be a good start? AFAIU, it will cause misalignment with any font/font size other than the one where it fits the actual size of the font (assuming that font is fixed-pitch), so how can it be a step in the right direction? I think initial whitespace should rather change its size to match the size of the font---then it will produce nicely indented display with any font. Or maybe I misunderstand what you mean by "fixed width". You did mean fixed width in pixels, yes? If not, then what did you mean? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 8:20 ` Eli Zaretskii @ 2018-03-10 19:48 ` James Cloos 2018-03-10 20:00 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: James Cloos @ 2018-03-10 19:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cpitclaudel, eggert, emacs-devel >>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes: EZ> Or maybe I misunderstand what you mean by "fixed width". You did mean EZ> fixed width in pixels, yes? If not, then what did you mean? Yes. By fixed-width I mean the font the buffer would use were variable- pitch-mode not in effect. -JimC -- James Cloos <cloos@jhcloos.com> OpenPGP: 0x997A9F17ED7DAEA6 ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 19:48 ` James Cloos @ 2018-03-10 20:00 ` Eli Zaretskii 2018-03-10 22:18 ` James Cloos 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 20:00 UTC (permalink / raw) To: James Cloos; +Cc: cpitclaudel, eggert, emacs-devel > From: James Cloos <cloos@jhcloos.com> > Cc: eggert@cs.ucla.edu, cpitclaudel@gmail.com, emacs-devel@gnu.org > Date: Sat, 10 Mar 2018 14:48:33 -0500 > > >>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes: > > EZ> Or maybe I misunderstand what you mean by "fixed width". You did mean > EZ> fixed width in pixels, yes? If not, then what did you mean? > > Yes. By fixed-width I mean the font the buffer would use were variable- > pitch-mode not in effect. Then I really don't understand why you think it's a good start. I think it's a step in the wrong direction, because it will make things worse than they are now: what we have now makes sure the initial whitespace changes in sync on all lines of the buffer, so that the first non-whitespace characters on each line stay aligned. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 20:00 ` Eli Zaretskii @ 2018-03-10 22:18 ` James Cloos 2018-03-11 3:43 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: James Cloos @ 2018-03-10 22:18 UTC (permalink / raw) To: Eli Zaretskii; +Cc: cpitclaudel, eggert, emacs-devel >>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes: EZ> Then I really don't understand why you think it's a good start. I EZ> think it's a step in the wrong direction, because it will make things EZ> worse than they are now: what we have now makes sure the initial EZ> whitespace changes in sync on all lines of the buffer, so that the EZ> first non-whitespace characters on each line stay aligned. I have not re-compiled in a while, nor did I read the whole thread. Perhaps things have progressed since the version I currently have. Consistent and not-too-small indenting is important. Basing indents on the width of the fixed pitch space and tab stops on a multiple of that would help, compared to what the version I have does. -JimC -- James Cloos <cloos@jhcloos.com> OpenPGP: 0x997A9F17ED7DAEA6 ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 22:18 ` James Cloos @ 2018-03-11 3:43 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-11 3:43 UTC (permalink / raw) To: James Cloos; +Cc: cpitclaudel, eggert, emacs-devel > From: James Cloos <cloos@jhcloos.com> > Cc: eggert@cs.ucla.edu, cpitclaudel@gmail.com, emacs-devel@gnu.org > Date: Sat, 10 Mar 2018 17:18:12 -0500 > > >>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes: > > EZ> Then I really don't understand why you think it's a good start. I > EZ> think it's a step in the wrong direction, because it will make things > EZ> worse than they are now: what we have now makes sure the initial > EZ> whitespace changes in sync on all lines of the buffer, so that the > EZ> first non-whitespace characters on each line stay aligned. > > I have not re-compiled in a while, nor did I read the whole thread. > Perhaps things have progressed since the version I currently have. > > Consistent and not-too-small indenting is important. Basing indents on > the width of the fixed pitch space and tab stops on a multiple of that > would help, compared to what the version I have does. I don't think anything's happened in this regard lately. A tab was always rendered on GUI frames as a stretch whose width is an integral multiple of the space width of the font. Except in the Windows port, the space width is actually the width of the font glyph that displays the space character. So I'm not sure I understand what problems you describe. Can you provide a concrete example where the behavior you describe produces bad results? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 8:30 ` Eli Zaretskii 2018-03-09 17:52 ` Paul Eggert @ 2018-03-09 19:48 ` Clément Pit-Claudel 2018-03-09 21:18 ` Eli Zaretskii 2018-03-10 4:27 ` Yuri Khan 1 sibling, 2 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-09 19:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-09 03:30, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Thu, 8 Mar 2018 14:55:20 -0500 >> >>> Maybe we could find a middle ground, whereby each one of the examples >>> will approximately align. If that can be done, and the result is >>> acceptable, then the problem of recording the text properties in the >>> file and/or reindenting when the file is revisited goes away. >> >> Maybe :) I don't know how good it would look, in practice, but it's easy to experiment. >> Paul's algorithm is not too bad in that sense: these two examples align pixel-perfectly. > > Yes, but as I said, I don't think that approach is appropriate for > code indentation, because leading whitespace in code blocks _must_ > always align, IMO. IOW, that approach seems to favor alignment of > multi-line code sequences to alignment of indented blocks, and I think > programming modes should have the opposite preference. Indeed :) I was mostly of the same opinion, but I find the actual results pretty OK. >>> That's more relevant for text-derived modes, where indentation levels >>> are rigid and not determined by previous lines. There we could do a >>> better job, I hope. >> >> OK. I tend to think of indentation even in text modes as being somewhat previous-lines dependent (wrapped paragraphs align relative to bullet points, for example), but I agree that it isn't as much as in programming modes. > > IME, indentation of text in word processors I use does not depend on > previous lines at all. Except in lists, right? For example it's not uncommon to wrap like this: * Some long text here that wraps around: i. Point 1 … continued ii. Point 2 … continued iii. Point 3 … continued Clément ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 19:48 ` Clément Pit-Claudel @ 2018-03-09 21:18 ` Eli Zaretskii 2018-03-09 22:54 ` Clément Pit-Claudel 2018-03-10 4:27 ` Yuri Khan 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-09 21:18 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Fri, 9 Mar 2018 14:48:33 -0500 > > > IME, indentation of text in word processors I use does not depend on > > previous lines at all. > > Except in lists, right? No, in lists as well. > For example it's not uncommon to wrap like this: > > * Some long text here > that wraps around: > > i. Point 1 > … continued > ii. Point 2 > … continued > iii. Point 3 > … continued What I meant was that if you, for example, enlarge the font, the indentation doesn't get larger in pixels. (I'm not sure we should follow that extreme example, but it does drive the point home, I think.) ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 21:18 ` Eli Zaretskii @ 2018-03-09 22:54 ` Clément Pit-Claudel 2018-03-10 8:04 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-09 22:54 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel On 2018-03-09 16:18, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Fri, 9 Mar 2018 14:48:33 -0500 >> >>> IME, indentation of text in word processors I use does not depend on >>> previous lines at all. >> >> Except in lists, right? > > No, in lists as well. I don't understand: in the example below, the widths of the bullets and the numbers (i, ii, …) affects the indentation of the following lines, right? In any case, I agree it's a fairly limited issue. I don't think it matters much. >> For example it's not uncommon to wrap like this: >> >> * Some long text here >> that wraps around: >> >> i. Point 1 >> … continued >> ii. Point 2 >> … continued >> iii. Point 3 >> … continued > > What I meant was that if you, for example, enlarge the font, the > indentation doesn't get larger in pixels. (I'm not sure we should > follow that extreme example, but it does drive the point home, I > think.) ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 22:54 ` Clément Pit-Claudel @ 2018-03-10 8:04 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 8:04 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: eggert, emacs-devel > Cc: emacs-devel@gnu.org, eggert@cs.ucla.edu > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Fri, 9 Mar 2018 17:54:11 -0500 > > >>> IME, indentation of text in word processors I use does not depend on > >>> previous lines at all. > >> > >> Except in lists, right? > > > > No, in lists as well. > > I don't understand: in the example below, the widths of the bullets and the numbers (i, ii, …) affects the indentation of the following lines, right? No, it doesn't. It surprised me to see that in MS Word, but the evidence is clear. Not sure we should follow suit, but it does tell us how far this could be taken. > In any case, I agree it's a fairly limited issue. I don't think it matters much. Agreed. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 19:48 ` Clément Pit-Claudel 2018-03-09 21:18 ` Eli Zaretskii @ 2018-03-10 4:27 ` Yuri Khan 2018-03-10 8:39 ` Eli Zaretskii 2018-03-10 13:49 ` Clément Pit-Claudel 1 sibling, 2 replies; 253+ messages in thread From: Yuri Khan @ 2018-03-10 4:27 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: Eli Zaretskii, Paul Eggert, Emacs developers On Sat, Mar 10, 2018 at 2:48 AM, Clément Pit-Claudel <cpitclaudel@gmail.com> wrote: > Except in lists, right? For example it's not uncommon to wrap like this: > > * Some long text here > that wraps around: > > i. Point 1 > … continued > ii. Point 2 > … continued > iii. Point 3 > … continued The way word processors implement this is: 1. Specify a left margin of, say, 0.5in. This makes each line start at that offset. 2. Specify a first line indentation of, say, -0.25in. This way the list marker starts at 0.25in, immediately followed by the rest of the first line. Each subsequent line starts at the left margin 0.5in. 3. To make the item text of the first line align with the rest of the paragraph, put a tabulation between the marker and the item text. Align that tabulation at 0.5in. The way HTML+CSS implement this is (roughly): 1. Specify a left margin for the whole list, say, 0.5in. 2. Treat list markers as special absolutely positioned elements. Put them at, say, (-0.25in across, +0in down) from the start of list item. (Absolutely positioned elements do not affect the layout of the surrounding text, so list item text is aligned normally.) In both cases, if the list marker becomes really long and no longer fits its allotted space of 0.25in, there will be display artifacts. In Word-alikes, the item text will start at the *next* tab stop. In HTML+CSS, item text will visually overlap the marker. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 4:27 ` Yuri Khan @ 2018-03-10 8:39 ` Eli Zaretskii 2018-03-10 11:42 ` Yuri Khan 2018-03-10 13:49 ` Clément Pit-Claudel 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 8:39 UTC (permalink / raw) To: Yuri Khan; +Cc: cpitclaudel, eggert, emacs-devel > From: Yuri Khan <yuri.v.khan@gmail.com> > Date: Sat, 10 Mar 2018 11:27:39 +0700 > Cc: Eli Zaretskii <eliz@gnu.org>, Paul Eggert <eggert@cs.ucla.edu>, > Emacs developers <emacs-devel@gnu.org> > > In both cases, if the list marker becomes really long and no longer > fits its allotted space of 0.25in, there will be display artifacts. In > Word-alikes, the item text will start at the *next* tab stop. My point was that the _subsequent_ lines still stay at the same 0.5" offset, no matter what happens on the first line. Which may or may not make sense, but it's good to know what "prior art" is in this case. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 8:39 ` Eli Zaretskii @ 2018-03-10 11:42 ` Yuri Khan 2018-03-10 14:28 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Yuri Khan @ 2018-03-10 11:42 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Clément Pit-Claudel, Paul Eggert, Emacs developers On Sat, Mar 10, 2018 at 3:39 PM, Eli Zaretskii <eliz@gnu.org> wrote: >> In both cases, if the list marker becomes really long and no longer >> fits its allotted space of 0.25in, there will be display artifacts. In >> Word-alikes, the item text will start at the *next* tab stop. > > My point was that the _subsequent_ lines still stay at the same 0.5" > offset, no matter what happens on the first line. Which may or may > not make sense, but it's good to know what "prior art" is in this > case. Yes. I’m actually confirming your claim that indentation of subsequent lines is not affected by the width of the marker. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 11:42 ` Yuri Khan @ 2018-03-10 14:28 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 14:28 UTC (permalink / raw) To: Yuri Khan; +Cc: cpitclaudel, eggert, emacs-devel > From: Yuri Khan <yuri.v.khan@gmail.com> > Date: Sat, 10 Mar 2018 18:42:57 +0700 > Cc: Clément Pit-Claudel <cpitclaudel@gmail.com>, > Paul Eggert <eggert@cs.ucla.edu>, Emacs developers <emacs-devel@gnu.org> > > > My point was that the _subsequent_ lines still stay at the same 0.5" > > offset, no matter what happens on the first line. Which may or may > > not make sense, but it's good to know what "prior art" is in this > > case. > > Yes. I’m actually confirming your claim that indentation of subsequent > lines is not affected by the width of the marker. Ah, okay. Thanks. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-10 4:27 ` Yuri Khan 2018-03-10 8:39 ` Eli Zaretskii @ 2018-03-10 13:49 ` Clément Pit-Claudel 1 sibling, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-10 13:49 UTC (permalink / raw) To: Yuri Khan; +Cc: Eli Zaretskii, Paul Eggert, Emacs developers On 2018-03-09 23:27, Yuri Khan wrote: > 1. Specify a left margin of, say, 0.5in. This makes each line start at > that offset. Of course; I didn't realize we were talking about teaching Emacs to do this kind of advanced positioning (I thought we were still discussing pure text documents) ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-07 17:22 ` Eli Zaretskii 2018-03-07 18:27 ` Clément Pit-Claudel @ 2018-03-08 4:50 ` Stefan Monnier 2018-03-08 13:44 ` Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: Stefan Monnier @ 2018-03-08 4:50 UTC (permalink / raw) To: emacs-devel >> In your world, concretely, what happens when I open xdisp.c and press M-x >> variable-pitch-mode? Does everything look misaligned until I M-x >> indent-region the whole file? > Yes. It isn't different from what happens when you change tab-width. It's different in one important way: - it's considered normal to impose that everyone who looks/edits this file needs to have tad-width set to a particular value (8, traditionally). - it's not considered normal to impose that everyone who looks/edits this file needs to use the same *font*. Also, you can easily circumvent the tag-width issue by not using TABs in your file, whereas it's hard to have a file whose appearance is not affected by the choice of font. Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 4:50 ` Stefan Monnier @ 2018-03-08 13:44 ` Eli Zaretskii 2018-03-08 22:03 ` Paul Eggert 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-08 13:44 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Wed, 07 Mar 2018 23:50:45 -0500 > > >> In your world, concretely, what happens when I open xdisp.c and press M-x > >> variable-pitch-mode? Does everything look misaligned until I M-x > >> indent-region the whole file? > > Yes. It isn't different from what happens when you change tab-width. > > It's different in one important way: > - it's considered normal to impose that everyone who looks/edits this > file needs to have tad-width set to a particular value (8, > traditionally). > - it's not considered normal to impose that everyone who looks/edits > this file needs to use the same *font*. The above doesn't force any particular font, just a fixed-pitch one, a limitation we already have today. So we will be no worse. > Also, you can easily circumvent the tag-width issue by not using TABs in > your file, whereas it's hard to have a file whose appearance is not > affected by the choice of font. Yes, using variable-pitch fonts in code where indentation is important has its disadvantages, and always will. Any solution will have the same issues, just under different use cases and situations. That's why this is not the main use case where we should support variable-pitch fonts well, the main use case is in text-related modes, where in many/most cases the indentation is rigid or changes proportionally with the width of some canonical character. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 13:44 ` Eli Zaretskii @ 2018-03-08 22:03 ` Paul Eggert 2018-03-09 8:34 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Paul Eggert @ 2018-03-08 22:03 UTC (permalink / raw) To: Eli Zaretskii, Stefan Monnier; +Cc: emacs-devel On 03/08/2018 05:44 AM, Eli Zaretskii wrote: > Yes, using variable-pitch fonts in code where indentation is important > has its disadvantages, and always will. Any solution will have the > same issues, just under different use cases and situations. That's > why this is not the main use case Although it has disadvantages, it shouldn't be that hard to do it better than Emacs does it now (along the lines that Clément prototyped), and if Emacs had these improvements the benefits of variable-pitch fonts would outweigh the costs in many practical programming applications. Programming in variable-width fonts makes more-efficient use of valuable screen real estate, so it's worth doing when it works reasonably well, as it often would if Emacs supported it better. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-08 22:03 ` Paul Eggert @ 2018-03-09 8:34 ` Eli Zaretskii 2018-03-09 16:05 ` Clément Pit-Claudel 2018-03-10 7:42 ` Variable-width font indentation Stephen Leake 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-09 8:34 UTC (permalink / raw) To: Paul Eggert; +Cc: monnier, emacs-devel > Cc: emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Thu, 8 Mar 2018 14:03:21 -0800 > > On 03/08/2018 05:44 AM, Eli Zaretskii wrote: > > Yes, using variable-pitch fonts in code where indentation is important > > has its disadvantages, and always will. Any solution will have the > > same issues, just under different use cases and situations. That's > > why this is not the main use case > > Although it has disadvantages, it shouldn't be that hard to do it better > than Emacs does it now (along the lines that Clément prototyped), and if > Emacs had these improvements the benefits of variable-pitch fonts would > outweigh the costs in many practical programming applications. I agree (although I don't think we should use the basic idea of calculating the indentation that the prototype used). > Programming in variable-width fonts makes more-efficient use of valuable > screen real estate, so it's worth doing when it works reasonably well, > as it often would if Emacs supported it better. Agreed. Do people think adding a per-buffer space-width variable would be a good step in this direction? It should be easy to add, I think. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 8:34 ` Eli Zaretskii @ 2018-03-09 16:05 ` Clément Pit-Claudel 2018-03-09 16:21 ` Eli Zaretskii 2018-03-10 7:42 ` Variable-width font indentation Stephen Leake 1 sibling, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-09 16:05 UTC (permalink / raw) To: emacs-devel On 2018-03-09 03:34, Eli Zaretskii wrote: > Do people think adding a per-buffer space-width variable would be a > good step in this direction? It should be easy to add, I think. It does sound convenient. Will it apply only to leading whitespace, or also to inter-word whitespace? Also, do we need it on the C side? It sounds fairly easy to achieve with existing tools like font-lock + display properties. Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 16:05 ` Clément Pit-Claudel @ 2018-03-09 16:21 ` Eli Zaretskii 2018-03-10 8:12 ` Variable-width font alignment Stephen Leake 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-09 16:21 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Fri, 9 Mar 2018 11:05:13 -0500 > > On 2018-03-09 03:34, Eli Zaretskii wrote: > > Do people think adding a per-buffer space-width variable would be a > > good step in this direction? It should be easy to add, I think. > > It does sound convenient. Will it apply only to leading whitespace, or also to inter-word whitespace? I'd say it should apply everywhere. It would be confusing to have SPC take a different number of pixels depending on where it is. > Also, do we need it on the C side? It sounds fairly easy to achieve with existing tools like font-lock + display properties. Display properties have the disadvantage that they cannot be easily saved. Basically, having this in the display code is convenient for the same reason the TAB display is handled in C. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font alignment 2018-03-09 16:21 ` Eli Zaretskii @ 2018-03-10 8:12 ` Stephen Leake 2018-03-10 8:56 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Stephen Leake @ 2018-03-10 8:12 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Fri, 9 Mar 2018 11:05:13 -0500 >> >> On 2018-03-09 03:34, Eli Zaretskii wrote: >> > Do people think adding a per-buffer space-width variable would be a >> > good step in this direction? It should be easy to add, I think. >> >> It does sound convenient. Will it apply only to leading whitespace, >> or also to inter-word whitespace? > > I'd say it should apply everywhere. It would be confusing to have SPC > take a different number of pixels depending on where it is. Right. Unless we need something else to fix the intra-line align function - ie align '=>' in Trace => Verbosity > 1, Put_Parse_Table => Verbosity > 0, Ignore_Unused_Tokens => Verbosity > 1, Ignore_Unknown_Conflicts => Verbosity > 1); It seems to me that implementing this in a variable width font requires some sort of align-region-local tab setting, which is a change to current align algorithms (which just insert spaces). I use this feature extensively in Ada code, so I would not switch to variable width font without it. One step in align.el `align-areas' computes an `align-column'. In variable-pitch-mode, we could convert that into a tab setting by computing the pixel column of that character column in the line with the least whitespace/longest text ("Ignore_Unknown_Conflicts =>" above). I could try doing this. What is the best approach to implementing an align-region-local tab setting? -- -- Stephe ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font alignment 2018-03-10 8:12 ` Variable-width font alignment Stephen Leake @ 2018-03-10 8:56 ` Eli Zaretskii 2018-03-10 17:30 ` Stephen Leake 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 8:56 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Sat, 10 Mar 2018 02:12:57 -0600 > > Trace => Verbosity > 1, > Put_Parse_Table => Verbosity > 0, > Ignore_Unused_Tokens => Verbosity > 1, > Ignore_Unknown_Conflicts => Verbosity > 1); > > It seems to me that implementing this in a variable width font requires some > sort of align-region-local tab setting, which is a change to current align > algorithms (which just insert spaces). Whatever we do to adapt indentation to variable-pitch fonts, we _must_ still begin by inserting spaces so that the same text looks aligned with fixed-pitch fonts. Otherwise, we will be unable to let other people view our code/documents in other editors which use fixed-pitch fonts, or even in Emacs with fixed-pitch fonts. The features that align text when variable-pitch fonts are in use must work _on_top_ of the "basic" alignment that just uses spaces and tabs as we do today. > One step in align.el `align-areas' computes an `align-column'. In > variable-pitch-mode, we could convert that into a tab setting by > computing the pixel column of that character column in the line with the > least whitespace/longest text ("Ignore_Unknown_Conflicts =>" above). > > I could try doing this. What is the best approach to implementing an > align-region-local tab setting? Any local change in whitespace width would need to use 'display' text properties, such as '(space :width (N))'. The problem with that is that you cannot easily record this when you save the file, so these properties will have to be recomputed anew each time the file is visited. Which will take us down the path of font-lock and JIT lock, something that I'd like to avoid. We could also record that in a separate file, but I'm not sure such meta-data approach will be acceptable. Another idea would be to modify align-areas such that it attempts to find an align-column that will align given text without changing the width of space and tab, by looking for some kind of LCD for the widths of the text strings involved in this. Not sure if this is workable, though. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font alignment 2018-03-10 8:56 ` Eli Zaretskii @ 2018-03-10 17:30 ` Stephen Leake 2018-03-10 19:02 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Stephen Leake @ 2018-03-10 17:30 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Stephen Leake <stephen_leake@stephe-leake.org> >> Date: Sat, 10 Mar 2018 02:12:57 -0600 >> >> Trace => Verbosity > 1, >> Put_Parse_Table => Verbosity > 0, >> Ignore_Unused_Tokens => Verbosity > 1, >> Ignore_Unknown_Conflicts => Verbosity > 1); >> >> It seems to me that implementing this in a variable width font requires some >> sort of align-region-local tab setting, which is a change to current align >> algorithms (which just insert spaces). > > Whatever we do to adapt indentation to variable-pitch fonts, we _must_ > still begin by inserting spaces so that the same text looks aligned > with fixed-pitch fonts. Otherwise, we will be unable to let other > people view our code/documents in other editors which use fixed-pitch > fonts, or even in Emacs with fixed-pitch fonts. > > The features that align text when variable-pitch fonts are in use must > work _on_top_ of the "basic" alignment that just uses spaces and tabs > as we do today. Right. >> One step in align.el `align-areas' computes an `align-column'. In >> variable-pitch-mode, we could convert that into a tab setting by >> computing the pixel column of that character column in the line with the >> least whitespace/longest text ("Ignore_Unknown_Conflicts =>" above). >> >> I could try doing this. What is the best approach to implementing an >> align-region-local tab setting? > > Any local change in whitespace width would need to use 'display' text > properties, such as '(space :width (N))'. Ok; that doesn't need an explicit tab. > The problem with that is that you cannot easily record this when you > save the file, so these properties will have to be recomputed anew > each time the file is visited. Right. For example, that happens now in info files; formatting is applied to the links via text properties. > Which will take us down the path of font-lock and JIT lock, something > that I'd like to avoid. That's how align.el works now. We could modify it to only set the text properties if the fixed-width spaces are correct, or when in a read-only buffer, or in variable-pitch-mode. On the other hand, the ada-mode currently in GELPA computes indentation and faces from a parse of the source text. It works very well, as long as the source is syntactically correct. I'm working on implementing error recovery in the parser; it works fairly well at the moment, and I'm still improving it. It should be possible to compute alignments from the parse as well; that would elminate some of the minor bugs in current ada-mode alignment. That would still require a parse when visiting the file. > We could also record that in a separate file, but I'm not sure such > meta-data approach will be acceptable. Computing the align properties from the source has to be fast enough to be acceptable while editing (as align.el is now), so it will be acceptable on visiting. -- -- Stephe ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font alignment 2018-03-10 17:30 ` Stephen Leake @ 2018-03-10 19:02 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-10 19:02 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Sat, 10 Mar 2018 11:30:53 -0600 > > Computing the align properties from the source has to be fast enough to > be acceptable while editing (as align.el is now), so it will be > acceptable on visiting. Yes, if this is feasible. Will it be fast enough to handle large sources files, such as xdisp.c, for example? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-09 8:34 ` Eli Zaretskii 2018-03-09 16:05 ` Clément Pit-Claudel @ 2018-03-10 7:42 ` Stephen Leake 1 sibling, 0 replies; 253+ messages in thread From: Stephen Leake @ 2018-03-10 7:42 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Paul Eggert <eggert@cs.ucla.edu> > >> Programming in variable-width fonts makes more-efficient use of valuable >> screen real estate, so it's worth doing when it works reasonably well, >> as it often would if Emacs supported it better. > > Agreed. > > Do people think adding a per-buffer space-width variable would be a > good step in this direction? It should be easy to add, I think. +1 -- -- Stephe ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 20:28 ` Variable-width font indentation Clément Pit-Claudel ` (2 preceding siblings ...) 2018-03-06 16:11 ` Eli Zaretskii @ 2018-03-06 16:35 ` Stefan Monnier 2018-03-06 19:59 ` Clément Pit-Claudel 3 siblings, 1 reply; 253+ messages in thread From: Stefan Monnier @ 2018-03-06 16:35 UTC (permalink / raw) To: emacs-devel > I don't know of a good solution to this problem: in general, there's not > enough information to distinguish 'indentation' spaces (the two spaces > before `printf (', `pr ()', and `return 0') and 'line-up' spaces (the spaces > before `char ()'). Indeed, you'd need to ask the indenter for the why this particular was chosen (where the answer will usually be of the form "indentation = OFFSET + column_of_position POS"). Of course, the additional problem is that the indenter is not necessarily Emacs's indent-line-function. Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:35 ` Stefan Monnier @ 2018-03-06 19:59 ` Clément Pit-Claudel 0 siblings, 0 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-03-06 19:59 UTC (permalink / raw) To: emacs-devel On 2018-03-06 11:35, Stefan Monnier wrote: > Of course, the additional problem is that the indenter is not > necessarily Emacs's indent-line-function. Exactly ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation (was: What improvements would be truly useful?) 2018-03-05 17:57 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 2018-03-05 19:32 ` dancol @ 2018-03-05 23:05 ` Richard Stallman 2018-03-06 16:04 ` Variable-width font indentation Stefan Monnier 2018-03-06 16:14 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 1 sibling, 2 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-05 23:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, raeburn, dancol, eggert [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > This has come up several times, and I think I asked at least once what > does it need to entail. It means, for one thing, that M-q can fill text with a smooth right margin. Has that been implemented yet? -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-05 23:05 ` Variable-width font indentation (was: What improvements would be truly useful?) Richard Stallman @ 2018-03-06 16:04 ` Stefan Monnier 2018-03-06 17:43 ` Eli Zaretskii 2018-03-06 20:55 ` Richard Stallman 2018-03-06 16:14 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 1 sibling, 2 replies; 253+ messages in thread From: Stefan Monnier @ 2018-03-06 16:04 UTC (permalink / raw) To: emacs-devel > > This has come up several times, and I think I asked at least once what > > does it need to entail. > It means, for one thing, that M-q can fill text with a smooth > right margin. > Has that been implemented yet? AFAIK `shr` does that, yes. Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:04 ` Variable-width font indentation Stefan Monnier @ 2018-03-06 17:43 ` Eli Zaretskii 2018-03-06 18:14 ` Stefan Monnier 2018-03-06 20:56 ` Richard Stallman 2018-03-06 20:55 ` Richard Stallman 1 sibling, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 17:43 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Tue, 06 Mar 2018 11:04:41 -0500 > > > > This has come up several times, and I think I asked at least once what > > > does it need to entail. > > It means, for one thing, that M-q can fill text with a smooth > > right margin. > > Has that been implemented yet? > > AFAIK `shr` does that, yes. No, AFAIK it doesn't. What it does is modify the fill algorithm to measure the actual width of text, without assuming fixed-pitch font. But it doesn't produce smooth right margin by inserting stretch glyphs. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 17:43 ` Eli Zaretskii @ 2018-03-06 18:14 ` Stefan Monnier 2018-03-06 20:56 ` Richard Stallman 1 sibling, 0 replies; 253+ messages in thread From: Stefan Monnier @ 2018-03-06 18:14 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > No, AFAIK it doesn't. What it does is modify the fill algorithm to > measure the actual width of text, without assuming fixed-pitch font. > But it doesn't produce smooth right margin by inserting stretch > glyphs. Don't know if it does do it or not, indeed, but AFAIU the algorithm it uses does give it the pixel info needed to do full-justification. Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 17:43 ` Eli Zaretskii 2018-03-06 18:14 ` Stefan Monnier @ 2018-03-06 20:56 ` Richard Stallman 1 sibling, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-06 20:56 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > No, AFAIK it doesn't. What it does is modify the fill algorithm to > measure the actual width of text, without assuming fixed-pitch font. > But it doesn't produce smooth right margin by inserting stretch > glyphs. Given that this part has already been implemented, we should make M-q do it too. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 16:04 ` Variable-width font indentation Stefan Monnier 2018-03-06 17:43 ` Eli Zaretskii @ 2018-03-06 20:55 ` Richard Stallman 2018-03-07 7:05 ` Yuri Khan 1 sibling, 1 reply; 253+ messages in thread From: Richard Stallman @ 2018-03-06 20:55 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > It means, for one thing, that M-q can fill text with a smooth > > right margin. > > Has that been implemented yet? > AFAIK `shr` does that, yes. I don't think it does THIS job. shr is a facility that renders HTML. I'm talking about using M-q to do filling that looks good with variable-width fonts. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation 2018-03-06 20:55 ` Richard Stallman @ 2018-03-07 7:05 ` Yuri Khan 0 siblings, 0 replies; 253+ messages in thread From: Yuri Khan @ 2018-03-07 7:05 UTC (permalink / raw) To: rms; +Cc: Stefan Monnier, Emacs developers On Wed, Mar 7, 2018 at 3:55 AM, Richard Stallman <rms@gnu.org> wrote: > shr is a facility that renders HTML. > I'm talking about using M-q to do filling > that looks good with variable-width fonts. For word processing purposes, you should not need manual or semi-automated filling such as M-q provides. Proper word processing operates two level of abstraction higher. Level +0: you directly affect where words end up using spaces and line feeds. This is the level that M-q works on. Level +1: you specify a paper size for the document or a sections, and, for each paragraph, a left margin, a right margin, a font, and a paragraph alignment (left, center, right, or justified). The layout engine automatically chops the paragraph into lines for display and print purposes according to these settings. Level +2: you do not specify individual formatting settings on each paragraph; instead, you specify a paragraph style that specifies all these things. (Like Emacs faces provide a level of indirection for face attributes.) So: you don’t fill a paragraph with a left margin of 30 spaces and a right margin at position 72. You designate the paragraph as Addressee, and the Addressee style specifies a left margin of 50% paper width and inherits its right margin of 1 inch from the Default style. All of which is, of course, achievable with HTML + CSS (or a moral equivalent). WYSIWYG editing for that is possible but 20 years of observation show that users of WYSIWYG systems tend to produce (at best) level +1 documents rather than +2. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation (was: What improvements would be truly useful?) 2018-03-05 23:05 ` Variable-width font indentation (was: What improvements would be truly useful?) Richard Stallman 2018-03-06 16:04 ` Variable-width font indentation Stefan Monnier @ 2018-03-06 16:14 ` Eli Zaretskii 2018-03-06 20:55 ` Richard Stallman 1 sibling, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 16:14 UTC (permalink / raw) To: rms; +Cc: emacs-devel, raeburn, dancol, eggert > From: Richard Stallman <rms@gnu.org> > CC: raeburn@raeburn.org, eggert@cs.ucla.edu, dancol@dancol.org, > emacs-devel@gnu.org > Date: Mon, 05 Mar 2018 18:05:11 -0500 > > It means, for one thing, that M-q can fill text with a smooth > right margin. > > Has that been implemented yet? No, not yet. But unless I'm missing something, doing that would be relatively simple: we need a variant of justify-current-line which will (a) compute the number of blanks as a float number, and (b) add a 'display' property to each blank with an :align-to attribute computed (in pixels) to produce the smooth right margin. Patches to that effect are welcome. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Variable-width font indentation (was: What improvements would be truly useful?) 2018-03-06 16:14 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii @ 2018-03-06 20:55 ` Richard Stallman 0 siblings, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-06 20:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, raeburn, dancol, eggert [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > It means, for one thing, that M-q can fill text with a smooth > > right margin. > > > > Has that been implemented yet? > No, not yet. But unless I'm missing something, doing that would be > relatively simple: we need a variant of justify-current-line which > will (a) compute the number of blanks as a float number, and (b) add a > 'display' property to each blank with an :align-to attribute computed > (in pixels) to produce the smooth right margin. If it is that easy, it means that we already have done more of this job than I thought we did. That would be good news. Would someone please implement this? Whenever the buffer has characters of different widths, it ought to fill them with attention to their widths. Once this is done, we can see what word-processing feature to add next. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman ` (3 preceding siblings ...) 2018-03-05 17:57 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii @ 2018-03-05 18:51 ` Daniele Nicolodi 2018-03-05 19:22 ` Eli Zaretskii ` (2 more replies) 2018-03-08 11:44 ` Toon Claes 5 siblings, 3 replies; 253+ messages in thread From: Daniele Nicolodi @ 2018-03-05 18:51 UTC (permalink / raw) To: emacs-devel On 3/5/18 6:11 AM, Richard Stallman wrote: > [[[ To any NSA and FBI agents reading my email: please consider ]]] > [[[ whether defending the US Constitution against all enemies, ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > An improvement in GC wouldn't be a bad thing, but it may not be worth > the effort. It is likely to lead to many bugs that would be hard to > fix. Once working, it would not make much difference to users. > It would only permit some operations on larger problems than now. > > When I was working at the AI Lab, one of the older programmers told me > that hackers are often eager to make improvements of this sort: which > make the program better in an abstract sense, but not better for > users. I took that advice to heart. Now I pass it on. > > Changing Emacs to handle indentation and alignment with > variable-width fonts would be an important and useful change. > Certain kinds of use would make sense, which currently don't. > > It would be a big step towards making Emacs do the job of > a word processor, which is what I would like to see some day. > Imagine if you could edit nicely formatted documents directly > with Emacs, instead of using LibreOffice? LibreOffice is > fine to use, it is free software, but it isn't Emacs. Richard, with all the due respect for your role in starting the Emacs project and the Free software movement, I don't think that dismissing contributions to Emacs on the base of their relative usefulness to implementing new features that you think are important, does any good to Emacs. Hackers work on Emacs because they like it, and scratch their own itch. I don't think that anyone is in the position to suggest how they should be spending their time. Even more so if (as far as I know) there is no agreed upon roadmap for the project. I think that what will help to keep Emacs relevant in the long run is modernizing its structure and code base, moving away from the baroque architecture that developed as a result of its very long history (and some less than optimally future proof design decisions). Personally, I find that better support for display with variable width fonts will not improve my use of Emacs. What would improve my user experience would be improvements to the display engine that will allow a better document viewing capabilities in something like pdf-tools (like continuous scrolling). The only effective (and not detrimental to the project) way to steer hacker attentions to features you find important is to pay them for their work. With your popularity it should not be impossible to rise enough money to do so. Cheers, Dan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 18:51 ` What improvements would be truly useful? Daniele Nicolodi @ 2018-03-05 19:22 ` Eli Zaretskii 2018-03-06 6:32 ` Daniele Nicolodi 2018-03-06 7:48 ` Yuri Khan 2018-03-05 21:15 ` Juri Linkov 2018-03-05 22:09 ` What improvements would be truly useful? John Wiegley 2 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-05 19:22 UTC (permalink / raw) To: Daniele Nicolodi; +Cc: emacs-devel > From: Daniele Nicolodi <daniele@grinta.net> > Date: Mon, 5 Mar 2018 11:51:09 -0700 > > I think that what will help to keep Emacs relevant in the long run is > modernizing its structure and code base, moving away from the baroque > architecture that developed as a result of its very long history (and > some less than optimally future proof design decisions). What exactly are you talking about here? AFAIK, the Emacs architecture didn't change since its inception, so its long history has no relevance here. But maybe I'm missing something or misunderstanding what you intended to convey. > What would improve my user experience would be improvements to the > display engine that will allow a better document viewing > capabilities in something like pdf-tools (like continuous > scrolling). AFAIU, that's already possible from the display engine POV, what's missing is application-level Lisp code that would take advantage of the infrastructure. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 19:22 ` Eli Zaretskii @ 2018-03-06 6:32 ` Daniele Nicolodi 2018-03-06 16:52 ` Eli Zaretskii 2018-03-06 7:48 ` Yuri Khan 1 sibling, 1 reply; 253+ messages in thread From: Daniele Nicolodi @ 2018-03-06 6:32 UTC (permalink / raw) To: emacs-devel On 05/03/2018 12:22, Eli Zaretskii wrote: >> From: Daniele Nicolodi <daniele@grinta.net> >> Date: Mon, 5 Mar 2018 11:51:09 -0700 >> >> I think that what will help to keep Emacs relevant in the long run is >> modernizing its structure and code base, moving away from the baroque >> architecture that developed as a result of its very long history (and >> some less than optimally future proof design decisions). > > What exactly are you talking about here? AFAIK, the Emacs > architecture didn't change since its inception, so its long history > has no relevance here. But maybe I'm missing something or > misunderstanding what you intended to convey. I'm far from being familiar with the Emacs codebase thus I may be reporting something that it is not completely true, however: Emacs was born as a console only application, the graphical user interface seems to be duct taped on. Also, GTK support seems a bit of an hack that requires layering violations (reaching down to the X primitives) to work. Being GTK the only modern toolkit supported on Linux (as far as I know) and the only way to get nartive Wayland support, some radical cleanup in that area would probably be a good thing. >> What would improve my user experience would be improvements to the >> display engine that will allow a better document viewing >> capabilities in something like pdf-tools (like continuous >> scrolling). > > AFAIU, that's already possible from the display engine POV, what's > missing is application-level Lisp code that would take advantage of > the infrastructure. Reading the pdf-tools bug report on the matter, I had the impression that implementing this was not possible because of some Emacs limitations. I'm happy if that's not the case. I'll go and investigate more. Cheers, Dan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 6:32 ` Daniele Nicolodi @ 2018-03-06 16:52 ` Eli Zaretskii 2018-03-06 17:01 ` Daniel Colascione 2018-03-07 5:45 ` Daniele Nicolodi 0 siblings, 2 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 16:52 UTC (permalink / raw) To: Daniele Nicolodi; +Cc: emacs-devel > From: Daniele Nicolodi <daniele@grinta.net> > Date: Mon, 5 Mar 2018 23:32:28 -0700 > > I'm far from being familiar with the Emacs codebase thus I may be > reporting something that it is not completely true, however: Emacs was > born as a console only application, the graphical user interface seems > to be duct taped on. I object to the "duct taped" derogation, and invite you to study the relevant code before you form your opinions. Besides, Emacs still supports text-mode terminals, and moreover, supports text-mode and GUI frames in the same session (a very important feature), so some degree of compatibility to a console is still a requirement. > Also, GTK support seems a bit of an hack that > requires layering violations (reaching down to the X primitives) to > work. Being GTK the only modern toolkit supported on Linux (as far as I > know) and the only way to get nartive Wayland support, some radical > cleanup in that area would probably be a good thing. It's true that GTK support was added in a not very clean way, but I don't think we can throw away support for the other toolkits just yet, because they are still being used. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 16:52 ` Eli Zaretskii @ 2018-03-06 17:01 ` Daniel Colascione 2018-03-07 5:45 ` Daniele Nicolodi 1 sibling, 0 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-06 17:01 UTC (permalink / raw) To: Eli Zaretskii, Daniele Nicolodi; +Cc: emacs-devel On 03/06/2018 08:52 AM, Eli Zaretskii wrote: >> From: Daniele Nicolodi <daniele@grinta.net> >> Date: Mon, 5 Mar 2018 23:32:28 -0700 >> >> I'm far from being familiar with the Emacs codebase thus I may be >> reporting something that it is not completely true, however: Emacs was >> born as a console only application, the graphical user interface seems >> to be duct taped on. > > I object to the "duct taped" derogation, and invite you to study the > relevant code before you form your opinions. Besides, Emacs still > supports text-mode terminals, and moreover, supports text-mode and GUI > frames in the same session (a very important feature), so some degree > of compatibility to a console is still a requirement. > >> Also, GTK support seems a bit of an hack that >> requires layering violations (reaching down to the X primitives) to >> work. Being GTK the only modern toolkit supported on Linux (as far as I >> know) and the only way to get nartive Wayland support, some radical >> cleanup in that area would probably be a good thing. > > It's true that GTK support was added in a not very clean way, but I > don't think we can throw away support for the other toolkits just yet, > because they are still being used. Eli is right. The current approach is fine, however it got there. Eventually, we'll have to support Wayland, but I disagree that "radical cleanups" will necessarily be needed. As I wrote a while ago, the right way forward is a pure GTK+ (as opposed to a mixed X11/GTK+) back-end, letting GTK+ handle running on Wayland, and this kind of window system could be most accommodated in the existing model. It'll end up looking a lot like the NS port. More radical, I think, would be multiple-window-system support. For that, more abstraction in the frame rendering will be required. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 16:52 ` Eli Zaretskii 2018-03-06 17:01 ` Daniel Colascione @ 2018-03-07 5:45 ` Daniele Nicolodi 2018-03-07 17:45 ` Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: Daniele Nicolodi @ 2018-03-07 5:45 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel On 06/03/2018 09:52, Eli Zaretskii wrote: >> From: Daniele Nicolodi <daniele@grinta.net> >> Date: Mon, 5 Mar 2018 23:32:28 -0700 >> >> I'm far from being familiar with the Emacs codebase thus I may be >> reporting something that it is not completely true, however: Emacs was >> born as a console only application, the graphical user interface seems >> to be duct taped on. > > I object to the "duct taped" derogation, and invite you to study the > relevant code before you form your opinions. Besides, Emacs still > supports text-mode terminals, and moreover, supports text-mode and GUI > frames in the same session (a very important feature), so some degree > of compatibility to a console is still a requirement. I didn't intend "duct taped" as derogatory. I meant to say that it has been added in a way that works and is effective, but it is not elegant or nice to look at. I'm an experimental physicist and all complex experiments have some literal duct tape solution that makes them work, that was often supposed to be a quick fix to get things going, and that ends to survive generations of PhD students. >> Also, GTK support seems a bit of an hack that >> requires layering violations (reaching down to the X primitives) to >> work. Being GTK the only modern toolkit supported on Linux (as far as I >> know) and the only way to get nartive Wayland support, some radical >> cleanup in that area would probably be a good thing. > > It's true that GTK support was added in a not very clean way, but I > don't think we can throw away support for the other toolkits just yet, > because they are still being used. I don't think that cleaning up the GTK support requires removing support for any other toolkit, and I'm far from suggesting something like that. Cheers, Dan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 5:45 ` Daniele Nicolodi @ 2018-03-07 17:45 ` Eli Zaretskii 2018-03-07 17:49 ` Daniele Nicolodi 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 17:45 UTC (permalink / raw) To: Daniele Nicolodi; +Cc: emacs-devel > Cc: emacs-devel@gnu.org > From: Daniele Nicolodi <daniele@grinta.net> > Date: Tue, 6 Mar 2018 22:45:25 -0700 > > >> Also, GTK support seems a bit of an hack that > >> requires layering violations (reaching down to the X primitives) to > >> work. Being GTK the only modern toolkit supported on Linux (as far as I > >> know) and the only way to get nartive Wayland support, some radical > >> cleanup in that area would probably be a good thing. > > > > It's true that GTK support was added in a not very clean way, but I > > don't think we can throw away support for the other toolkits just yet, > > because they are still being used. > > I don't think that cleaning up the GTK support requires removing support > for any other toolkit, and I'm far from suggesting something like that. Then how should we understand your suggestion for "radical cleanup", right after asserting that GTK is the only modern toolkit supported by GNU/Linux? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 17:45 ` Eli Zaretskii @ 2018-03-07 17:49 ` Daniele Nicolodi 2018-03-07 18:06 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Daniele Nicolodi @ 2018-03-07 17:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel On 3/7/18 10:45 AM, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org >> From: Daniele Nicolodi <daniele@grinta.net> >> Date: Tue, 6 Mar 2018 22:45:25 -0700 >> >>>> Also, GTK support seems a bit of an hack that >>>> requires layering violations (reaching down to the X primitives) to >>>> work. Being GTK the only modern toolkit supported on Linux (as far as I >>>> know) and the only way to get nartive Wayland support, some radical >>>> cleanup in that area would probably be a good thing. >>> >>> It's true that GTK support was added in a not very clean way, but I >>> don't think we can throw away support for the other toolkits just yet, >>> because they are still being used. >> >> I don't think that cleaning up the GTK support requires removing support >> for any other toolkit, and I'm far from suggesting something like that. > > Then how should we understand your suggestion for "radical cleanup", > right after asserting that GTK is the only modern toolkit supported by > GNU/Linux? Radical cleanup of the GTK integration. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 17:49 ` Daniele Nicolodi @ 2018-03-07 18:06 ` Eli Zaretskii 2018-03-07 21:45 ` Philipp Stephani 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-07 18:06 UTC (permalink / raw) To: Daniele Nicolodi; +Cc: emacs-devel > Cc: emacs-devel@gnu.org > From: Daniele Nicolodi <daniele@grinta.net> > Date: Wed, 7 Mar 2018 10:49:39 -0700 > > > Then how should we understand your suggestion for "radical cleanup", > > right after asserting that GTK is the only modern toolkit supported by > > GNU/Linux? > > Radical cleanup of the GTK integration. If you have ideas for how to achieve that, I'd be interested to hear them. Thanks. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 18:06 ` Eli Zaretskii @ 2018-03-07 21:45 ` Philipp Stephani 2018-03-08 13:20 ` Eli Zaretskii 0 siblings, 1 reply; 253+ messages in thread From: Philipp Stephani @ 2018-03-07 21:45 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Daniele Nicolodi, emacs-devel [-- Attachment #1: Type: text/plain, Size: 729 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Mi., 7. März 2018 um 19:06 Uhr: > > Cc: emacs-devel@gnu.org > > From: Daniele Nicolodi <daniele@grinta.net> > > Date: Wed, 7 Mar 2018 10:49:39 -0700 > > > > > Then how should we understand your suggestion for "radical cleanup", > > > right after asserting that GTK is the only modern toolkit supported by > > > GNU/Linux? > > > > Radical cleanup of the GTK integration. > > If you have ideas for how to achieve that, I'd be interested to hear > them. > By adding a gtkterm.c, that does the same as w32term.c, just for GTK, without referring to X.org in any way? The cleanup would then consist in removing all GTK functionality from xterm.c once gtkterm.c is stable. [-- Attachment #2: Type: text/html, Size: 1188 bytes --] ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-07 21:45 ` Philipp Stephani @ 2018-03-08 13:20 ` Eli Zaretskii 2018-03-08 16:24 ` Alan Third 0 siblings, 1 reply; 253+ messages in thread From: Eli Zaretskii @ 2018-03-08 13:20 UTC (permalink / raw) To: Philipp Stephani; +Cc: daniele, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Wed, 07 Mar 2018 21:45:46 +0000 > Cc: Daniele Nicolodi <daniele@grinta.net>, emacs-devel@gnu.org > > If you have ideas for how to achieve that, I'd be interested to hear > them. > > By adding a gtkterm.c, that does the same as w32term.c, just for GTK, without referring to X.org in any way? > The cleanup would then consist in removing all GTK functionality from xterm.c once gtkterm.c is stable. (I guess you meant removing GTK-related portions of xfns.c as well?) If you look at these two files, you will see that the GTK-specific snippets in them are a few and far between. Most of the code is generic. So I think making separate gtkterm.c/gtkfns.c will risk duplicating a lot of code, something we already have with w32 and ns ports, and such duplication is undesirable. But maybe I'm missing something. My understanding of this sub-thread was that the idea was to separate GTK _architecturally_, not just making it yet another display back-end. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 13:20 ` Eli Zaretskii @ 2018-03-08 16:24 ` Alan Third 2018-03-08 18:02 ` Daniel Colascione 0 siblings, 1 reply; 253+ messages in thread From: Alan Third @ 2018-03-08 16:24 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Philipp Stephani, daniele, emacs-devel On Thu, Mar 08, 2018 at 03:20:58PM +0200, Eli Zaretskii wrote: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Wed, 07 Mar 2018 21:45:46 +0000 > > Cc: Daniele Nicolodi <daniele@grinta.net>, emacs-devel@gnu.org > > > > By adding a gtkterm.c, that does the same as w32term.c, just for GTK, without referring to X.org in any way? > > The cleanup would then consist in removing all GTK functionality from xterm.c once gtkterm.c is stable. > > (I guess you meant removing GTK-related portions of xfns.c as well?) > > If you look at these two files, you will see that the GTK-specific > snippets in them are a few and far between. Most of the code is > generic. That’s part of the problem with how Emacs deals with GTK, it does many things the X way rather than the GTK way. For example, mouse and keyboard events are dealt with using X code, but GTK provides it’s own APIs for dealing with them. I thought implementing touch events would be easy because GTK already does all the heavy lifting, but Emacs doesn’t use GTK for events. I strongly suspect a Wayland compatible GTK Emacs would have to remove a lot of (all?) X code and replace it with GTK code. > My understanding of this sub-thread was that the idea was to separate > GTK _architecturally_, not just making it yet another display > back-end. I don’t think I understand the difference. -- Alan Third ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 16:24 ` Alan Third @ 2018-03-08 18:02 ` Daniel Colascione 0 siblings, 0 replies; 253+ messages in thread From: Daniel Colascione @ 2018-03-08 18:02 UTC (permalink / raw) To: Alan Third, Eli Zaretskii; +Cc: Philipp Stephani, daniele, emacs-devel On 03/08/2018 08:24 AM, Alan Third wrote: > On Thu, Mar 08, 2018 at 03:20:58PM +0200, Eli Zaretskii wrote: >>> From: Philipp Stephani <p.stephani2@gmail.com> >>> Date: Wed, 07 Mar 2018 21:45:46 +0000 >>> Cc: Daniele Nicolodi <daniele@grinta.net>, emacs-devel@gnu.org >>> >>> By adding a gtkterm.c, that does the same as w32term.c, just for GTK, without referring to X.org in any way? >>> The cleanup would then consist in removing all GTK functionality from xterm.c once gtkterm.c is stable. >> >> (I guess you meant removing GTK-related portions of xfns.c as well?) >> >> If you look at these two files, you will see that the GTK-specific >> snippets in them are a few and far between. Most of the code is >> generic. > > That’s part of the problem with how Emacs deals with GTK, it does many > things the X way rather than the GTK way. > > For example, mouse and keyboard events are dealt with using X code, > but GTK provides it’s own APIs for dealing with them. I thought > implementing touch events would be easy because GTK already does all > the heavy lifting, but Emacs doesn’t use GTK for events. > > I strongly suspect a Wayland compatible GTK Emacs would have to remove > a lot of (all?) X code and replace it with GTK code. > >> My understanding of this sub-thread was that the idea was to separate >> GTK _architecturally_, not just making it yet another display >> back-end. > > I don’t think I understand the difference. Emacs can be compiled with support for many different window systems, such as X11, MS-Windows, and Cocoa/NS. Currently, having chosen the X11 window system, you can go on to choose which toolkit you want to use: Motif, GTK2, GTK3, Lucid, and so on. The proposal is to promote GTK support from an X11 toolkit to a top-level window system, excising, in the process, the GTK display back-end of any mention of X11. I think it's an excellent project and one important to the future maintainability of the project. As much as it saddens* me to say so, X11 is dying, while GTK will continue to be a decent abstraction that will hit the happy, conventional path of GNU/Linux input and display infrastructure. Emacs X11 integration being unusual and dubiously legal has caused compatibility problems in the past, particularly with systems like NX. As part of this effort, I'd love to see more abstraction in the window system selection. All the xterm.c functions that we carefully replicate in every window system really should be a table of frame-specific function pointers, and we should be able to compile a single Emacs binary with support for all window systems enabled simultaneously. * IMHO, Wayland should be been a series of new X protocol extensions, not a greenfield project. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 19:22 ` Eli Zaretskii 2018-03-06 6:32 ` Daniele Nicolodi @ 2018-03-06 7:48 ` Yuri Khan 2018-03-06 17:08 ` Eli Zaretskii 1 sibling, 1 reply; 253+ messages in thread From: Yuri Khan @ 2018-03-06 7:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Daniele Nicolodi, Emacs developers On Tue, Mar 6, 2018 at 2:22 AM, Eli Zaretskii <eliz@gnu.org> wrote: >> I think that what will help to keep Emacs relevant in the long run is >> modernizing its structure and code base, moving away from the baroque >> architecture that developed as a result of its very long history (and >> some less than optimally future proof design decisions). > > What exactly are you talking about here? AFAIK, the Emacs > architecture didn't change since its inception, so its long history > has no relevance here. But maybe I'm missing something or > misunderstanding what you intended to convey. One architectural decision that I would call baroque is the input model. In Emacs, the input model is that of the character terminal: the input is a sequence of characters. The repertoire of Unicode characters is extended with special values for function and editing keys, and for keys modified with Ctrl, Super, Hyper, and Shift where necessary (and Meta is represented as an ESC prefix), but still it is a sequence of characters without explicit ties to the keys. Even mouse clicks are processed as a special kind of characters. This is inevitable when running in a terminal emulator where the underlying abstraction works this way, but in a GUI build this leads to inability to distinguish, for example, the ‘.’ character as coming from the bottom-row right ring finger in US English layout, or from the bottom-row right pinky in Russian layout, or from the decimal separator key on the keypad. Bindings such as M-{ are unnecessarily hard for international users whose keyboard layout does not have a { character at all or puts it into third or fourth level. Another example was described in Daniel Colascione’s article/rant “Buttery Smooth Emacs”. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-06 7:48 ` Yuri Khan @ 2018-03-06 17:08 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 17:08 UTC (permalink / raw) To: Yuri Khan; +Cc: daniele, emacs-devel > From: Yuri Khan <yuri.v.khan@gmail.com> > Date: Tue, 6 Mar 2018 14:48:39 +0700 > Cc: Daniele Nicolodi <daniele@grinta.net>, Emacs developers <emacs-devel@gnu.org> > > One architectural decision that I would call baroque is the input model. Then we have different interpretations of what "architecture" means in this context. To me, architecture of a program such as Emacs is its model-view-controller structure, the single-threaded operation, etc. Input model is a lower-level design and implementation layer. > In Emacs, the input model is that of the character terminal: the input > is a sequence of characters. The repertoire of Unicode characters is > extended with special values for function and editing keys, and for > keys modified with Ctrl, Super, Hyper, and Shift where necessary (and > Meta is represented as an ESC prefix), but still it is a sequence of > characters without explicit ties to the keys. Even mouse clicks are > processed as a special kind of characters. Unless I misunderstand what you mean by "character", the above is simply not true. In Emacs, input is a stream of events. Several kinds of events are supported, see enum event_kind in termhooks.h. Only some of them are characters, most are not. The relevant variable in keyboard.c is frequently called 'c', so one could think it's a character, but in fact it is a Lisp object, and can be anything. In particular, a mouse click doesn't look at all like a character, it is actually a cons cell. > This is inevitable when running in a terminal emulator where the > underlying abstraction works this way, but in a GUI build this leads > to inability to distinguish, for example, the ‘.’ character as coming > from the bottom-row right ring finger in US English layout, or from > the bottom-row right pinky in Russian layout, or from the decimal > separator key on the keypad. That is a different issue, unrelated to what kind of input events are recognized and how they are represented. Emacs does support function keys on X and other GUI environments, so it could potentially support any abstraction for keys, if the underlying GUI APIs allow that on the X message level. We even install a low-level keyboard hook on Windows to salvage some of the keys that Windows insists on intercepting ahead of the application. IOW, I see no architectural limitations here, only implementation that might be missing or hard to come up with. > Another example was described in Daniel Colascione’s article/rant > “Buttery Smooth Emacs”. Daniel's blog is a good read for someone who is familiar with the internals, but I don't recommend to form your opinions about the Emacs internals and their problems based solely on that blog. For starters, some of what is written there is no longer true these days. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 18:51 ` What improvements would be truly useful? Daniele Nicolodi 2018-03-05 19:22 ` Eli Zaretskii @ 2018-03-05 21:15 ` Juri Linkov 2018-03-05 23:46 ` Óscar Fuentes 2018-03-05 22:09 ` What improvements would be truly useful? John Wiegley 2 siblings, 1 reply; 253+ messages in thread From: Juri Linkov @ 2018-03-05 21:15 UTC (permalink / raw) To: Daniele Nicolodi; +Cc: emacs-devel > What would improve my user experience would be improvements to the > display engine that will allow a better document viewing capabilities > in something like pdf-tools (like continuous scrolling). Continuous scrolling can be easily implemented with a simple hack to insert adjacent images for the previous/next pdf pages in the same DocView buffer. But what would be much more strategically advantageous is to employ the Blink rendering engine as an alternative Emacs display engine. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 21:15 ` Juri Linkov @ 2018-03-05 23:46 ` Óscar Fuentes 2018-03-06 3:36 ` Eli Zaretskii 2018-04-02 20:40 ` Continuous image scrolling (was: What improvements would be truly useful?) Juri Linkov 0 siblings, 2 replies; 253+ messages in thread From: Óscar Fuentes @ 2018-03-05 23:46 UTC (permalink / raw) To: emacs-devel Juri Linkov <juri@linkov.net> writes: >> What would improve my user experience would be improvements to the >> display engine that will allow a better document viewing capabilities >> in something like pdf-tools (like continuous scrolling). > > Continuous scrolling can be easily implemented with a simple hack > to insert adjacent images for the previous/next pdf pages in > the same DocView buffer. I've looked into implementing this feature and it is not as simple as it seems. The hack you mention is precisely that: a hack, and a very cranky one. AFAIK there is no way of implementing continous scrolling with adjacent images if you care at all about robustness and user experience. And the fact that people is asking for this feature for years and, to this day, nobody implemented it, seems to confirm my impressions. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 23:46 ` Óscar Fuentes @ 2018-03-06 3:36 ` Eli Zaretskii 2018-04-02 20:40 ` Continuous image scrolling (was: What improvements would be truly useful?) Juri Linkov 1 sibling, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-03-06 3:36 UTC (permalink / raw) To: Óscar Fuentes; +Cc: emacs-devel > From: Óscar Fuentes <ofv@wanadoo.es> > Date: Tue, 06 Mar 2018 00:46:27 +0100 > > I've looked into implementing this feature and it is not as simple as it > seems. The hack you mention is precisely that: a hack, and a very cranky > one. AFAIK there is no way of implementing continous scrolling with > adjacent images if you care at all about robustness and user experience. Can you explain the obstacles that prevent implementing this? We have vscroll support in the display engine, so I think the implementation should be quite easy. But maybe I'm missing something. > And the fact that people is asking for this feature for years and, to > this day, nobody implemented it, seems to confirm my impressions. That could be because people are unaware of some crucial feature, or because no one with the know-how had enough motivation to code this, or for any number of other reasons. Not necessarily because it's impossible. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Continuous image scrolling (was: What improvements would be truly useful?) 2018-03-05 23:46 ` Óscar Fuentes 2018-03-06 3:36 ` Eli Zaretskii @ 2018-04-02 20:40 ` Juri Linkov 2018-04-03 1:59 ` Continuous image scrolling Óscar Fuentes 1 sibling, 1 reply; 253+ messages in thread From: Juri Linkov @ 2018-04-02 20:40 UTC (permalink / raw) To: Óscar Fuentes; +Cc: emacs-devel >>> What would improve my user experience would be improvements to the >>> display engine that will allow a better document viewing capabilities >>> in something like pdf-tools (like continuous scrolling). >> >> Continuous scrolling can be easily implemented with a simple hack >> to insert adjacent images for the previous/next pdf pages in >> the same DocView buffer. > > I've looked into implementing this feature and it is not as simple as it > seems. The hack you mention is precisely that: a hack, and a very cranky > one. AFAIK there is no way of implementing continous scrolling with > adjacent images if you care at all about robustness and user experience. > And the fact that people is asking for this feature for years and, to > this day, nobody implemented it, seems to confirm my impressions. I just realized we already have continuous image scrolling mode: 1. visiting a PDF file generates PNG images in the temporary directory 2. C-x d /tmp/docview1000/... RET 3. M-x iimage-mode RET 4. enjoy continuous image scrolling mode directly in dired (the same logic could be later incorporated into doc-view.el) I tried this with a directory containing ca 1000 pages/images and there is no performance degradation while continuously scrolling all these 1000 images. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-02 20:40 ` Continuous image scrolling (was: What improvements would be truly useful?) Juri Linkov @ 2018-04-03 1:59 ` Óscar Fuentes 2018-04-03 7:01 ` Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 253+ messages in thread From: Óscar Fuentes @ 2018-04-03 1:59 UTC (permalink / raw) To: emacs-devel Juri Linkov <juri@linkov.net> writes: >>>> What would improve my user experience would be improvements to the >>>> display engine that will allow a better document viewing capabilities >>>> in something like pdf-tools (like continuous scrolling). >>> >>> Continuous scrolling can be easily implemented with a simple hack >>> to insert adjacent images for the previous/next pdf pages in >>> the same DocView buffer. >> >> I've looked into implementing this feature and it is not as simple as it >> seems. The hack you mention is precisely that: a hack, and a very cranky >> one. AFAIK there is no way of implementing continous scrolling with >> adjacent images if you care at all about robustness and user experience. >> And the fact that people is asking for this feature for years and, to >> this day, nobody implemented it, seems to confirm my impressions. > > I just realized we already have continuous image scrolling mode: > > 1. visiting a PDF file generates PNG images in the temporary directory > 2. C-x d /tmp/docview1000/... RET > 3. M-x iimage-mode RET > 4. enjoy continuous image scrolling mode directly in dired > (the same logic could be later incorporated into doc-view.el) > > I tried this with a directory containing ca 1000 pages/images > and there is no performance degradation while continuously scrolling > all these 1000 images. PDF-Tools (which is vastly superior to the built-in PDF viewer) does not work this way. It generates pages on demand. It is an absurd waste of resources to visit a book and generate one png file for each page. PDF-Tools solves this and does much more. So, if the solution depends on having pre-generated images, it is worse than not having continuous scroll, IMAO. OTOH, I tried what you suggest on a directory with lots of images. The result is quite crude. For example, it seems that the curso height corresponds to the image height, i.e. it is not possible to finely scroll the sequence of images up and down, you go one image at the time. The problems I faced while trying to implement continous document scroll for PDF-Tools revolved around making the scroll actually continous: if you scroll down from page P-1 to page P, remove page P-2 and append page P+1 without producing visible jumps. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 1:59 ` Continuous image scrolling Óscar Fuentes @ 2018-04-03 7:01 ` Eli Zaretskii 2018-04-03 19:59 ` Juri Linkov 2018-04-04 19:19 ` John Wiegley 2 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-04-03 7:01 UTC (permalink / raw) To: Óscar Fuentes; +Cc: emacs-devel > From: Óscar Fuentes <ofv@wanadoo.es> > Date: Tue, 03 Apr 2018 03:59:23 +0200 > > The problems I faced while trying to implement continous document scroll > for PDF-Tools revolved around making the scroll actually continous: if > you scroll down from page P-1 to page P, remove page P-2 and append page > P+1 without producing visible jumps. Sounds like some simple enough changes to the logic of line-move-visual and its subroutines. Patches are welcome. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 1:59 ` Continuous image scrolling Óscar Fuentes 2018-04-03 7:01 ` Eli Zaretskii @ 2018-04-03 19:59 ` Juri Linkov 2018-04-03 20:20 ` Drew Adams ` (2 more replies) 2018-04-04 19:19 ` John Wiegley 2 siblings, 3 replies; 253+ messages in thread From: Juri Linkov @ 2018-04-03 19:59 UTC (permalink / raw) To: Óscar Fuentes; +Cc: emacs-devel >> I just realized we already have continuous image scrolling mode: >> >> 1. visiting a PDF file generates PNG images in the temporary directory >> 2. C-x d /tmp/docview1000/... RET >> 3. M-x iimage-mode RET >> 4. enjoy continuous image scrolling mode directly in dired >> (the same logic could be later incorporated into doc-view.el) >> >> I tried this with a directory containing ca 1000 pages/images >> and there is no performance degradation while continuously scrolling >> all these 1000 images. > > PDF-Tools (which is vastly superior to the built-in PDF viewer) does not > work this way. It generates pages on demand. It is an absurd waste of > resources to visit a book and generate one png file for each page. > PDF-Tools solves this and does much more. > > So, if the solution depends on having pre-generated images, it is worse > than not having continuous scroll, IMAO. This is an optimization, but a significant one, indeed, if you are not going to read the whole PDF at once. > OTOH, I tried what you suggest on a directory with lots of images. The > result is quite crude. For example, it seems that the curso height > corresponds to the image height, It's possible to hide the cursor like we do in image-mode. > i.e. it is not possible to finely scroll the sequence of images up and > down, you go one image at the time. It's because next-line goes to the next file in Dired by default, this is why I disabled this inconvenience in my ~/.emacs by using normal cursor motion keybindings: (define-key dired-mode-map [remap next-line] nil) (define-key dired-mode-map [remap previous-line] nil) > The problems I faced while trying to implement continous document scroll > for PDF-Tools revolved around making the scroll actually continous: if > you scroll down from page P-1 to page P, remove page P-2 I see no need to remove page P-2. For optimization it's better to keep it, so that when the user returns to that page, it's already here. > and append page P+1 without producing visible jumps. Based on the simplistic approach like used by iimage-mode, it should be easy to insert placeholders for all pages, and use font-lock machinery to replace placeholders with generated images when the user navigates to other parts of the PDF buffer. ^ permalink raw reply [flat|nested] 253+ messages in thread
* RE: Continuous image scrolling 2018-04-03 19:59 ` Juri Linkov @ 2018-04-03 20:20 ` Drew Adams 2018-04-04 19:54 ` Juri Linkov 2018-04-03 21:08 ` Stefan Monnier 2018-04-03 21:57 ` Clément Pit-Claudel 2 siblings, 1 reply; 253+ messages in thread From: Drew Adams @ 2018-04-03 20:20 UTC (permalink / raw) To: Juri Linkov, Óscar Fuentes; +Cc: emacs-devel > use font-lock machinery to replace placeholders with > generated images when the user navigates to other parts > of the PDF buffer. Interesting idea! But would that be responsive, for the user? Would the images be generated on the fly? Would they be automatically deleted and garbaged afterward? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 20:20 ` Drew Adams @ 2018-04-04 19:54 ` Juri Linkov 0 siblings, 0 replies; 253+ messages in thread From: Juri Linkov @ 2018-04-04 19:54 UTC (permalink / raw) To: Drew Adams; +Cc: Óscar Fuentes, emacs-devel >> use font-lock machinery to replace placeholders with >> generated images when the user navigates to other parts >> of the PDF buffer. > > Interesting idea! But would that be responsive, for > the user? Would the images be generated on the fly? > Would they be automatically deleted and garbaged > afterward? I think it will be no less responsive than other PDF readers that also generate images on the fly. But the main problem is how to pre-render these placeholders to avoid visible jumps on inserting new images. Maybe we need to scan the whole PDF document and get dimensions of all pages, then use them for placeholders. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 19:59 ` Juri Linkov 2018-04-03 20:20 ` Drew Adams @ 2018-04-03 21:08 ` Stefan Monnier 2018-04-03 21:57 ` Clément Pit-Claudel 2 siblings, 0 replies; 253+ messages in thread From: Stefan Monnier @ 2018-04-03 21:08 UTC (permalink / raw) To: emacs-devel > I see no need to remove page P-2. For optimization it's better to keep it, > so that when the user returns to that page, it's already here. Reminds me: I've had Emacs crash on me when flipping though large PDF documents with doc-view. I haven't been able to reproduce it, but I have the impression that we have a problem there somewhere. [ It's not directly related to the above in the sense that doc-view only displays one page at any given time anyway. ] Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 19:59 ` Juri Linkov 2018-04-03 20:20 ` Drew Adams 2018-04-03 21:08 ` Stefan Monnier @ 2018-04-03 21:57 ` Clément Pit-Claudel 2018-04-04 6:27 ` Eli Zaretskii ` (2 more replies) 2 siblings, 3 replies; 253+ messages in thread From: Clément Pit-Claudel @ 2018-04-03 21:57 UTC (permalink / raw) To: emacs-devel On 2018-04-03 15:59, Juri Linkov wrote: >> i.e. it is not possible to finely scroll the sequence of images up and >> down, you go one image at the time. > It's because next-line goes to the next file in Dired by default, > this is why I disabled this inconvenience in my ~/.emacs by using > normal cursor motion keybindings: Maybe I'm misunderstanding the original request, but if not then I don't think this is the issue. AFAIU, one thing that is not too easy to implement today in ELisp is continuous ("smooth") scrolling over multiple images, as shown in e.g. evince: if I drag the scroll bars or press the up and down keys, the current page and the following one move up and down by a bit. We usually call this pixel-scroll in Emacs, and we have an implementation of it based on set-window-vscroll in lisp/pixel-scroll.el. This is also what Docview and PDFTools use to scroll images that don't fit in the selected window. But I don't think that trick works for sequences of images, at least not straight out of the box. The main issue, IIUC, is that images occupy one (tall) line, and Emacs tries to always keep the line containing the point in full view, which means that set-window-vscroll does not always work if the point is on a line containing an image. You can see what I mean concretely with the following example. Open a new buffer, and run (insert (propertize " " 'display '(image :type jpeg :file "/path/to/some/large/picture.jpg" :scale 1))). Then insert 5 lines of "A". Your buffer will look like this: |----------------| | Picture here | | | |----------------| A A A A Put the point on the third A and run (set-window-vscroll (selected-window) 8 t); note how the images moves a bit up. That's the kind of scrolling we want, which is encouraging :) But now put the point on the picture's line, and try the same experiment; notice how the picture doesn't move, because we try to keep the line in full view. (if the image is larger than the window, it does work, and that's how docview scrolls single pages. I don't know if there's a way to get that behavior when the image fits in the window). That behavior becomes an issue when you have sequences of images, because you can't leave the point on the line of the first image, but moving the point to the line of the second image scrolls it entirely into view. The two techniques to work around this that I'm aware of are (1) cutting the images into thin horizontal strips (and showing one strip per line), and (2) inserting a thin text line between each image on which to place the point while scrolling. I don't know if either of these would work for pdftools. Hopefully there's a third, simpler technique to achieve this? Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 21:57 ` Clément Pit-Claudel @ 2018-04-04 6:27 ` Eli Zaretskii 2018-04-04 19:50 ` Juri Linkov 2018-04-04 23:31 ` Tak Kunihiro 2 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-04-04 6:27 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Tue, 3 Apr 2018 17:57:35 -0400 > > AFAIU, one thing that is not too easy to implement today in ELisp is continuous ("smooth") scrolling over multiple images, as shown in e.g. evince: if I drag the scroll bars or press the up and down keys, the current page and the following one move up and down by a bit. It could/should be easy to implement in Lisp because the current behavior is implemented in Lisp. At least, I won't believe assertions such as the above until Someone™ digs into the code in line-move-visual and its subroutines, where the current behavior is implemented, and presents clear evidence that some code or feature coded in C gets in the way. > The main issue, IIUC, is that images occupy one (tall) line, and Emacs tries to always keep the line containing the point in full view, which means that set-window-vscroll does not always work if the point is on a line containing an image. Yes, but most, if not all, of the logic supporting this is in simple.el. > But now put the point on the picture's line, and try the same experiment; notice how the picture doesn't move, because we try to keep the line in full view. (if the image is larger than the window, it does work, and that's how docview scrolls single pages. I don't know if there's a way to get that behavior when the image fits in the window). That behavior becomes an issue when you have sequences of images, because you can't leave the point on the line of the first image, but moving the point to the line of the second image scrolls it entirely into view. > > The two techniques to work around this that I'm aware of are (1) cutting the images into thin horizontal strips (and showing one strip per line), and (2) inserting a thin text line between each image on which to place the point while scrolling. I don't know if either of these would work for pdftools. Hopefully there's a third, simpler technique to achieve this? It makes little sense to me to work around the behavior we ourselves implemented. Instead, I invite volunteers to take a good look at the code and try changing it to lift the limitations that currently get in the way. The current code behaves like it does because it was _programmed_ to behave that way. It explicitly uses window-vscroll only when the current line cannot be fully shown in the window for some reason. But if you look at the relevant code, you will see that this condition is programmed there, and is specifically tested to determine when to use window-vscroll and when to scroll to the next/previous screen line. So by changing that logic, perhaps controlled by some defcustom, it should be possible to get what DocView and PDF-tools want to accomplish. Let me remind you that similar misconceptions were around regarding pixel-level scrolling of text, until Tak came up with his package that did just that, entirely in Lisp. I hope someone will step forward and do the necessary research of what is needed, because my gut feeling is that the features sought out here are within our reach. (I can help with advice, because I'm responsible for at least some of the code in that area.) Any volunteers? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 21:57 ` Clément Pit-Claudel 2018-04-04 6:27 ` Eli Zaretskii @ 2018-04-04 19:50 ` Juri Linkov 2018-04-05 6:04 ` Eli Zaretskii 2018-04-04 23:31 ` Tak Kunihiro 2 siblings, 1 reply; 253+ messages in thread From: Juri Linkov @ 2018-04-04 19:50 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > But now put the point on the picture's line, and try the same experiment; > notice how the picture doesn't move, because we try to keep the line in > full view. (if the image is larger than the window, it does work, and > that's how docview scrolls single pages. I don't know if there's a way to > get that behavior when the image fits in the window). I tried only with images larger than the window height where multi-image scrolling works fine. But now I see that scrolling smaller images is not so smooth. I don't know if such narrow images are common in PDF documents. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-04 19:50 ` Juri Linkov @ 2018-04-05 6:04 ` Eli Zaretskii 0 siblings, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-04-05 6:04 UTC (permalink / raw) To: Juri Linkov; +Cc: cpitclaudel, emacs-devel > From: Juri Linkov <juri@linkov.net> > Date: Wed, 04 Apr 2018 22:50:43 +0300 > Cc: emacs-devel@gnu.org > > I tried only with images larger than the window height where multi-image > scrolling works fine. But now I see that scrolling smaller images is not > so smooth. I don't know if such narrow images are common in PDF documents. With today's large monitors and user tendency to maximize the frame, it's quite possible, I think. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 21:57 ` Clément Pit-Claudel 2018-04-04 6:27 ` Eli Zaretskii 2018-04-04 19:50 ` Juri Linkov @ 2018-04-04 23:31 ` Tak Kunihiro 2018-04-05 2:45 ` Clément Pit-Claudel 2 siblings, 1 reply; 253+ messages in thread From: Tak Kunihiro @ 2018-04-04 23:31 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel I think with the following setup, M-x pixel-scroll-mode (setq pixel-resolution-fine-flag t) a buffer with large images, as you shown, can be scrolled by height of typical line. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-04 23:31 ` Tak Kunihiro @ 2018-04-05 2:45 ` Clément Pit-Claudel 2018-04-05 3:54 ` Tak Kunihiro 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-04-05 2:45 UTC (permalink / raw) To: Tak Kunihiro; +Cc: emacs-devel On 2018-04-04 19:31, Tak Kunihiro wrote: > I think with the following setup, > > M-x pixel-scroll-mode > (setq pixel-resolution-fine-flag t) > > a buffer with large images, as you shown, can be scrolled by height of typical line. I think I must be doing something wrong :/ I used this snippet to insert 10 copies of a large picture in a new buffer: (dotimes (_ 10) (insert (propertize " " 'display '(image :type jpeg :file "some-large-picture.jpg" :scale 1)) "\n")) and then I turned pixel-scroll-mode on with the setting you mentioned, but Emacs still scrolls by full images. Clément. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-05 2:45 ` Clément Pit-Claudel @ 2018-04-05 3:54 ` Tak Kunihiro 2018-04-05 19:56 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Tak Kunihiro @ 2018-04-05 3:54 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: Tak Kunihiro, emacs-devel >> I think with the following setup, >> >> M-x pixel-scroll-mode >> (setq pixel-resolution-fine-flag t) >> >> a buffer with large images, as you shown, can be scrolled by height of typical line. > > I think I must be doing something wrong :/ > > I used this snippet to insert 10 copies of a large picture in a new buffer: > > (dotimes (_ 10) > (insert (propertize " " 'display '(image :type jpeg :file "some-large-picture.jpg" :scale 1)) "\n")) > > and then I turned pixel-scroll-mode on with the setting you mentioned, but Emacs still scrolls by full images. Let me assume height of an image is less than height of visible area of a window. M-x pixel-scroll-mode (setq pixel-resolution-fine-flag t) M-: (pixel-scroll-up 1) The (pixel-scroll-up 1) scrolls a buffer up by (frame-char-height) with re-displaying each pixel. A function that scrolls a buffer up like (pixel-scroll-up 1) but without re-displaying each pixel, should be written. The function serves as alternative of (scroll-up). ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-05 3:54 ` Tak Kunihiro @ 2018-04-05 19:56 ` Clément Pit-Claudel 2018-04-05 22:59 ` Tak Kunihiro 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-04-05 19:56 UTC (permalink / raw) To: Tak Kunihiro; +Cc: emacs-devel On 2018-04-04 23:54, Tak Kunihiro wrote: >>> I think with the following setup, >>> >>> M-x pixel-scroll-mode >>> (setq pixel-resolution-fine-flag t) >>> >>> a buffer with large images, as you shown, can be scrolled by height of typical line. >> >> I think I must be doing something wrong :/ >> >> I used this snippet to insert 10 copies of a large picture in a new buffer: >> >> (dotimes (_ 10) >> (insert (propertize " " 'display '(image :type jpeg :file "some-large-picture.jpg" :scale 1)) "\n")) >> >> and then I turned pixel-scroll-mode on with the setting you mentioned, but Emacs still scrolls by full images. > > Let me assume height of an image is less than height of visible area of > a window. > > M-x pixel-scroll-mode > (setq pixel-resolution-fine-flag t) > M-: (pixel-scroll-up 1) > > The (pixel-scroll-up 1) scrolls a buffer up by (frame-char-height) with > re-displaying each pixel. > > A function that scrolls a buffer up like (pixel-scroll-up 1) but without > re-displaying each pixel, should be written. The function serves as > alternative of (scroll-up). I don't understand. I followed your instructions, but M-: (pixel-scroll-up 1) scrolls up by a full image. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-05 19:56 ` Clément Pit-Claudel @ 2018-04-05 22:59 ` Tak Kunihiro 2018-04-06 4:36 ` Clément Pit-Claudel 0 siblings, 1 reply; 253+ messages in thread From: Tak Kunihiro @ 2018-04-05 22:59 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: Tak Kunihiro, emacs-devel Can you try following on 26.0.91 or later? $ emacs -Q M-x about-emacs M-x pixel-scroll-mode M-: (setq pixel-resolution-fine-flag t) M-: (pixel-scroll-up 1) ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-05 22:59 ` Tak Kunihiro @ 2018-04-06 4:36 ` Clément Pit-Claudel 2018-04-06 9:35 ` Tak Kunihiro 0 siblings, 1 reply; 253+ messages in thread From: Clément Pit-Claudel @ 2018-04-06 4:36 UTC (permalink / raw) To: Tak Kunihiro; +Cc: emacs-devel On 2018-04-05 18:59, Tak Kunihiro wrote: > Can you try following on 26.0.91 or later? > > $ emacs -Q > M-x about-emacs > M-x pixel-scroll-mode > M-: (setq pixel-resolution-fine-flag t) > M-: (pixel-scroll-up 1) That works fine. But about-emacs doesn't show a buffer with multiple large images in a row, right? ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-06 4:36 ` Clément Pit-Claudel @ 2018-04-06 9:35 ` Tak Kunihiro 0 siblings, 0 replies; 253+ messages in thread From: Tak Kunihiro @ 2018-04-06 9:35 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: Tak Kunihiro, emacs-devel I found following only works when height of an image is less than half of height of a window. (progn (pixel-scroll-mode 1) (setq pixel-resolution-fine-flag t) (dotimes (_ 10) (insert (propertize " " 'display '(image :type jpeg :file "some-large-picture.jpg" :scale 1)) "\n")) (dotimes (_ 100) (pixel-scroll-down 1) (sit-for 0.3))) ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Continuous image scrolling 2018-04-03 1:59 ` Continuous image scrolling Óscar Fuentes 2018-04-03 7:01 ` Eli Zaretskii 2018-04-03 19:59 ` Juri Linkov @ 2018-04-04 19:19 ` John Wiegley 2 siblings, 0 replies; 253+ messages in thread From: John Wiegley @ 2018-04-04 19:19 UTC (permalink / raw) To: Óscar Fuentes; +Cc: emacs-devel >>>>> "ÓF" == Óscar Fuentes <ofv@wanadoo.es> writes: ÓF> PDF-Tools (which is vastly superior to the built-in PDF viewer) does not ÓF> work this way. It generates pages on demand. It is an absurd waste of ÓF> resources to visit a book and generate one png file for each page. ÓF> PDF-Tools solves this and does much more. It really is quite good, I use it as my main PDF reader on the Mac now. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 18:51 ` What improvements would be truly useful? Daniele Nicolodi 2018-03-05 19:22 ` Eli Zaretskii 2018-03-05 21:15 ` Juri Linkov @ 2018-03-05 22:09 ` John Wiegley 2018-03-05 23:04 ` daniel sutton 2018-03-06 20:51 ` Richard Stallman 2 siblings, 2 replies; 253+ messages in thread From: John Wiegley @ 2018-03-05 22:09 UTC (permalink / raw) To: Daniele Nicolodi; +Cc: emacs-devel >>>>> "DN" == Daniele Nicolodi <daniele@grinta.net> writes: DN> Personally, I find that better support for display with variable width DN> fonts will not improve my use of Emacs. What would improve my user DN> experience would be improvements to the display engine that will allow a DN> better document viewing capabilities in something like pdf-tools (like DN> continuous scrolling). I have to agree with Daniele here. I don't use Emacs for writing such documents, nor would having variable width support by itself grant all the other features such users have come to expect from modern Word Processors. Time spent on a better GC could help the *overall* user experience, in the form of generally better latency, even if no one would be able to point to the GC as the reason for their better experience with Emacs. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 22:09 ` What improvements would be truly useful? John Wiegley @ 2018-03-05 23:04 ` daniel sutton 2018-03-06 20:51 ` Richard Stallman 1 sibling, 0 replies; 253+ messages in thread From: daniel sutton @ 2018-03-05 23:04 UTC (permalink / raw) To: Daniele Nicolodi, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1244 bytes --] I also really like Daniel's passion and ideas. I think he has been contributing new ideas and plenty of code to back it up. Seems like something to be encouraged. On Mon, Mar 5, 2018 at 4:09 PM, John Wiegley <johnw@gnu.org> wrote: > >>>>> "DN" == Daniele Nicolodi <daniele@grinta.net> writes: > > DN> Personally, I find that better support for display with variable width > DN> fonts will not improve my use of Emacs. What would improve my user > DN> experience would be improvements to the display engine that will allow > a > DN> better document viewing capabilities in something like pdf-tools (like > DN> continuous scrolling). > > I have to agree with Daniele here. I don't use Emacs for writing such > documents, nor would having variable width support by itself grant all the > other features such users have come to expect from modern Word Processors. > > Time spent on a better GC could help the *overall* user experience, in the > form of generally better latency, even if no one would be able to point to > the > GC as the reason for their better experience with Emacs. > > -- > John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F > http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 > > [-- Attachment #2: Type: text/html, Size: 1834 bytes --] ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 22:09 ` What improvements would be truly useful? John Wiegley 2018-03-05 23:04 ` daniel sutton @ 2018-03-06 20:51 ` Richard Stallman 1 sibling, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-06 20:51 UTC (permalink / raw) To: John Wiegley; +Cc: daniele, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] I don't use Emacs for writing such > documents, nor would having variable width support by itself grant all the > other features such users have come to expect from modern Word Processors. You're correct in observing that to make Emacs work as a word processor requires adding a number of features. A single added feature won't reach that point. A few features, well chosen, WILL reach that point, and then we will see people using Emacs as a word processor. Thus, I picked one of these features, one which we certainly need, and asked people to implement it in a user-usable way. When that's done, we can add another word-processing feature, and another, and soon people will start using Emacs for some simple cases of word processing. Some simple cases, such as letters, are not very many features away. I am sure we could get there this year. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman ` (4 preceding siblings ...) 2018-03-05 18:51 ` What improvements would be truly useful? Daniele Nicolodi @ 2018-03-08 11:44 ` Toon Claes 2018-03-08 20:08 ` Richard Stallman 2018-03-12 21:53 ` Dmitry Gutov 5 siblings, 2 replies; 253+ messages in thread From: Toon Claes @ 2018-03-08 11:44 UTC (permalink / raw) To: Richard Stallman, Alan Mackenzie, Dmitry Gutov; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 628 bytes --] IMHO, one thing that I would find interesting is proper support for multiple major modes. I know there has been some talking about this in the past: https://lists.gnu.org/archive/html/emacs-devel/2016-04/msg00585.html But I'm not sure what the outcome was of that very long thread. I only know later on some improvements were made to have html, css, and js modes working together: https://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00775.html But still having great multiple major mode support--with islands having their own major and minor modes--would make Emacs a more modern editor. -- Toon [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 832 bytes --] ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 11:44 ` Toon Claes @ 2018-03-08 20:08 ` Richard Stallman 2018-03-12 21:53 ` Dmitry Gutov 1 sibling, 0 replies; 253+ messages in thread From: Richard Stallman @ 2018-03-08 20:08 UTC (permalink / raw) To: Toon Claes; +Cc: acm, emacs-devel, dgutov [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > But still having great multiple major mode support--with islands having > their own major and minor modes--would make Emacs a more modern editor. I strongly support the request. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: What improvements would be truly useful? 2018-03-08 11:44 ` Toon Claes 2018-03-08 20:08 ` Richard Stallman @ 2018-03-12 21:53 ` Dmitry Gutov 1 sibling, 0 replies; 253+ messages in thread From: Dmitry Gutov @ 2018-03-12 21:53 UTC (permalink / raw) To: Toon Claes, Richard Stallman, Alan Mackenzie; +Cc: emacs-devel On 3/8/18 1:44 PM, Toon Claes wrote: > IMHO, one thing that I would find interesting is proper support > for multiple major modes. > > I know there has been some talking about this in the past: > > https://lists.gnu.org/archive/html/emacs-devel/2016-04/msg00585.html > > But I'm not sure what the outcome was of that very long thread. That one reached a dead end, for now. > I only know later on some improvements were made to have html, css, and > js modes working together: > > https://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00775.html > > But still having great multiple major mode support--with islands having > their own major and minor modes--would make Emacs a more modern editor. mmm-mode (a very old package providing features like that) is soon going to be in ELPA. If anyone on this mailing list wanted to contribute, but stopped because it wasn't a part of Emacs or ELPA, that will be their chance. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Let's make the GC safe and iterative 2018-03-01 23:22 ` Let's make the GC safe and iterative (Was: Re: bug#30626) Daniel Colascione 2018-03-01 23:29 ` Paul Eggert @ 2018-03-01 23:38 ` Stefan Monnier 2018-03-02 0:05 ` Daniel Colascione 1 sibling, 1 reply; 253+ messages in thread From: Stefan Monnier @ 2018-03-01 23:38 UTC (permalink / raw) To: emacs-devel > We need to fix GC being deeply recursive once and for all. Tweaking stack > sizes on various platforms and trying to spot-fix GC for the occasional > deeply recursive structure is annoying. Here's my proposal: I'm OK with making the GC loop without recursing on the C stack, but I have two comments: 1- Don't use a queue: use a stack. Mark&sweep naturally work with a stack whereas stop© naturally works with a queue, so in most cases the choice is implicit/accidental, but experience shows that if we can choose, the stack is the better option (e.g. there's been various works that try to tweak stop© to use a stack rather than a queue), for reasons of locality. 2- Why do you say "We can't allocate memory to hold the queue during GC"? We very well can, and doing it should make things simpler (and make sure we don't preallocate way too much memory). If instead of a queue we use a stack and we just push Lisp_Object values onto that stack, the resulting space use can't be worse than what we have now (it's just going to use our malloc-managed stack instead of the C stack). Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Let's make the GC safe and iterative 2018-03-01 23:38 ` Let's make the GC safe and iterative Stefan Monnier @ 2018-03-02 0:05 ` Daniel Colascione 2018-03-02 13:47 ` Stefan Monnier 0 siblings, 1 reply; 253+ messages in thread From: Daniel Colascione @ 2018-03-02 0:05 UTC (permalink / raw) To: Stefan Monnier, emacs-devel On 03/01/2018 03:38 PM, Stefan Monnier wrote: >> We need to fix GC being deeply recursive once and for all. Tweaking stack >> sizes on various platforms and trying to spot-fix GC for the occasional >> deeply recursive structure is annoying. Here's my proposal: > > I'm OK with making the GC loop without recursing on the C stack, but > I have two comments: > 1- Don't use a queue: use a stack. Mark&sweep naturally work with > a stack whereas stop© naturally works with a queue, so in most cases > the choice is implicit/accidental, but experience shows that if we > can choose, the stack is the better option (e.g. there's been > various works that try to tweak stop© to use a stack rather than > a queue), for reasons of locality. Sure. Using a stack instead of a queue is a minor detail; the basic algorithm is the same. Within blocks, we still need to be queue-based though: we'll scan the scan_pending bitmap once; if more bits behind the scan_pending read position become set during the scan, we won't know until the next time we examine the block. But we *can* make sure that we re-examine this block immediately after we finish the scan_pending bit-scan. > 2- Why do you say "We can't allocate memory to hold the queue during GC"? > We very well can, and doing it should make things simpler (and make > sure we don't preallocate way too much memory). We can try, but we need a plan if allocation fails. I don't want Emacs to be one of those programs that just aborts if malloc fails. Too many other programs get it wrong these days. I don't think the worst-case preallocation overhead is severe enough that we have to give up malloc robustness. > If instead of a queue we use a stack and we just push Lisp_Object values > onto that stack, the resulting space use can't be worse than what we > have now (it's just going to use our malloc-managed stack instead of the > C stack). Sure, except that stack use is ephemeral, and the space we allocate for the stack gets used for lisp too. OTOH, we need to preallocate these linkage structures and keep them allocated between GCs. But like I said, I don't think the overhead is worth worrying about. ^ permalink raw reply [flat|nested] 253+ messages in thread
* Re: Let's make the GC safe and iterative 2018-03-02 0:05 ` Daniel Colascione @ 2018-03-02 13:47 ` Stefan Monnier 0 siblings, 0 replies; 253+ messages in thread From: Stefan Monnier @ 2018-03-02 13:47 UTC (permalink / raw) To: Daniel Colascione; +Cc: emacs-devel > Sure. Using a stack instead of a queue is a minor detail; the basic > algorithm is the same. The point is that a stack will be better locality-wise and (more importantly) that it should be as good as what we have now w.r.t memory use (actually, it should be significantly better, because at each "recursive" step we only push one Lisp_Object on our stack whereas the current code pushes an activation frame which is at least twice as large since it also needs a return address). So I think it does affect the algorithm: I'm not convinced we need to do anything special for objects allocated from blocks. >> 2- Why do you say "We can't allocate memory to hold the queue during GC"? >> We very well can, and doing it should make things simpler (and make >> sure we don't preallocate way too much memory). > We can try, but we need a plan if allocation fails. We can just abort the GC (only requires resetting the markbits). It's not like we GC when our memory is full: we just GC on a regular basis for "prophylactic" reasons. > I don't think the worst-case preallocation overhead is severe enough > that we have to give up malloc robustness. It sounds pretty significant to me. I could live with it if it were indispensable but I find it difficult to justify. > Sure, except that stack use is ephemeral, Our manually-managed stack can have the same property. > and the space we allocate for the stack gets used for lisp too. Yes, that's a downside of such a change w.r.t average use of the combined stack space, but I don't think it affect the maximal combined stack space, so I'm not worried. This said, we could also move the Lisp stack to that same manually-managed stack (at least for the bytecode stacks). Stefan ^ permalink raw reply [flat|nested] 253+ messages in thread
* bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' 2018-02-27 11:39 ` Michael Heerdegen 2018-02-27 12:08 ` Michael Heerdegen @ 2018-02-27 18:00 ` Eli Zaretskii 1 sibling, 0 replies; 253+ messages in thread From: Eli Zaretskii @ 2018-02-27 18:00 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30626 > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: bug-gnu-emacs@gnu.org, 30626@debbugs.gnu.org > Date: Tue, 27 Feb 2018 12:39:47 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > > I guess it's a stack overflow: that function recurses into > > subdirectories. > > > > To avoid such problems, the function should be rewritten to work by > > BFS, not DFS. > > Here is the backtrace I'm now able to produce. Looks like the crash > happens in gc: GC is deeply-recursive, and you have exacerbated that by using up a lot of stack. ^ permalink raw reply [flat|nested] 253+ messages in thread
end of thread, other threads:[~2019-06-04 0:26 UTC | newest] Thread overview: 253+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-02-27 9:22 bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' Michael Heerdegen 2018-02-27 11:21 ` Eli Zaretskii 2018-02-27 11:39 ` Michael Heerdegen 2018-02-27 12:08 ` Michael Heerdegen 2018-02-27 18:08 ` Eli Zaretskii 2018-02-28 1:29 ` Noam Postavsky 2018-02-28 10:58 ` Michael Heerdegen 2018-02-28 16:00 ` Eli Zaretskii 2018-02-28 16:20 ` Michael Heerdegen 2018-02-28 17:22 ` Eli Zaretskii 2018-02-28 18:25 ` Michael Heerdegen 2018-03-01 11:25 ` Michael Heerdegen 2018-03-01 15:00 ` Eli Zaretskii 2018-03-02 14:11 ` Noam Postavsky 2018-03-02 15:06 ` Michael Heerdegen 2018-03-02 15:43 ` Eli Zaretskii 2018-03-02 20:16 ` Nicolas Petton 2018-03-02 20:58 ` Nicolas Petton 2018-03-03 7:56 ` Michael Heerdegen 2018-03-03 7:54 ` Michael Heerdegen 2018-03-03 8:47 ` Nicolas Petton 2018-03-02 21:48 ` John Mastro 2018-03-03 23:00 ` Noam Postavsky 2018-03-04 15:56 ` Noam Postavsky 2018-03-04 17:02 ` Eli Zaretskii 2018-03-11 18:52 ` Noam Postavsky 2018-03-11 20:31 ` Eli Zaretskii 2018-03-11 21:51 ` Noam Postavsky 2018-03-12 3:28 ` Eli Zaretskii 2018-03-13 1:59 ` Noam Postavsky 2018-03-13 16:06 ` Eli Zaretskii 2018-03-14 0:09 ` Noam Postavsky 2018-03-15 16:34 ` Eli Zaretskii 2018-03-17 15:53 ` Noam Postavsky 2018-03-17 16:10 ` Eli Zaretskii 2018-03-17 16:27 ` Eli Zaretskii 2018-03-17 17:28 ` Noam Postavsky 2018-03-19 20:05 ` Eli Zaretskii 2019-04-25 3:20 ` Noam Postavsky 2019-04-25 5:19 ` Michael Heerdegen 2019-05-10 13:20 ` Michael Heerdegen 2019-05-25 20:29 ` Noam Postavsky 2019-05-26 0:32 ` Michael Heerdegen 2019-05-26 0:40 ` Noam Postavsky 2019-05-26 1:15 ` Michael Heerdegen 2019-06-04 0:26 ` Noam Postavsky 2018-02-28 11:05 ` Michael Heerdegen 2018-02-28 13:20 ` Nicolas Petton 2018-03-01 10:44 ` Daniel Colascione 2018-03-01 15:51 ` Noam Postavsky 2018-03-01 16:54 ` Michael Heerdegen 2018-03-01 17:15 ` Noam Postavsky 2018-03-02 7:08 ` Michael Heerdegen 2018-03-02 13:01 ` Noam Postavsky 2018-03-02 13:13 ` Michael Heerdegen 2018-03-02 13:04 ` Michael Heerdegen 2018-03-01 23:22 ` Let's make the GC safe and iterative (Was: Re: bug#30626) Daniel Colascione 2018-03-01 23:29 ` Paul Eggert 2018-03-05 6:31 ` Ken Raeburn 2018-03-05 13:11 ` What improvements would be truly useful? Richard Stallman 2018-03-05 14:02 ` John Yates 2018-03-05 17:21 ` Paul Eggert 2018-03-05 16:33 ` Stefan Monnier 2018-03-05 17:32 ` Rostislav Svoboda 2018-03-05 18:04 ` Eli Zaretskii 2018-03-05 19:18 ` Daniel Colascione 2018-03-05 20:00 ` Eli Zaretskii 2018-03-05 23:05 ` Richard Stallman 2018-03-05 23:16 ` dancol 2018-03-06 20:54 ` Richard Stallman 2018-03-06 21:15 ` Daniel Colascione 2018-03-08 4:45 ` Stefan Monnier 2018-03-08 9:16 ` Jefferson Carpenter 2018-03-08 9:17 ` Yuri Khan 2018-03-08 13:40 ` Eli Zaretskii 2018-03-08 20:07 ` Richard Stallman 2018-03-08 20:29 ` Marcin Borkowski 2018-03-09 4:43 ` Stefan Monnier 2018-03-09 22:20 ` Richard Stallman 2018-03-09 22:42 ` Karl Fogel 2018-03-11 17:02 ` Marcin Borkowski 2018-03-06 20:01 ` Marcin Borkowski 2018-03-06 20:32 ` Eli Zaretskii 2018-03-06 20:41 ` Marcin Borkowski 2018-03-07 17:13 ` Eli Zaretskii 2018-03-07 18:30 ` Marcin Borkowski 2018-03-07 19:36 ` Eli Zaretskii 2018-03-07 20:49 ` Marcin Borkowski 2018-03-07 23:00 ` Richard Stallman 2018-03-09 10:56 ` Phillip Lord 2018-03-09 13:53 ` Eli Zaretskii 2018-03-10 16:02 ` Phillip Lord 2018-03-10 18:56 ` Eli Zaretskii 2018-03-09 22:20 ` Richard Stallman 2018-03-06 15:48 ` Dmitry Gutov 2018-03-05 19:05 ` Aaron Ecay 2018-03-05 20:55 ` Ricardo Wurmus 2018-03-05 23:05 ` Richard Stallman 2018-03-09 11:02 ` Phillip Lord 2018-03-09 22:20 ` Richard Stallman 2018-03-10 20:23 ` Phillip Lord 2018-03-11 23:26 ` Richard Stallman 2018-03-05 17:57 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 2018-03-05 19:32 ` dancol 2018-03-05 19:49 ` Variable-width font indentation Paul Eggert 2018-03-06 15:15 ` Dmitry Gutov 2018-03-06 15:34 ` Clément Pit-Claudel 2018-03-06 17:09 ` Eli Zaretskii 2018-03-05 19:58 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 2018-03-05 20:28 ` Variable-width font indentation Clément Pit-Claudel 2018-03-05 22:30 ` Paul Eggert 2018-03-05 22:53 ` Daniel Colascione 2018-03-06 1:06 ` Clément Pit-Claudel 2018-03-06 1:30 ` Paul Eggert 2018-03-06 1:40 ` Clément Pit-Claudel 2018-03-06 2:04 ` Paul Eggert 2018-03-06 3:36 ` Clément Pit-Claudel 2018-03-06 16:47 ` Eli Zaretskii 2018-03-06 19:50 ` Clément Pit-Claudel 2018-03-06 5:48 ` Daniel Colascione 2018-03-06 13:18 ` Clément Pit-Claudel 2018-03-06 16:36 ` Eli Zaretskii 2018-03-06 20:11 ` Clément Pit-Claudel 2018-03-06 20:40 ` Eli Zaretskii 2018-03-07 13:15 ` Clément Pit-Claudel 2018-03-07 18:26 ` Eli Zaretskii 2018-03-09 16:07 ` Clément Pit-Claudel 2018-03-07 22:13 ` Clément Pit-Claudel 2018-03-08 13:21 ` Eli Zaretskii 2018-03-08 14:05 ` Clément Pit-Claudel 2018-03-06 16:16 ` Eli Zaretskii 2018-03-06 16:38 ` Daniel Colascione 2018-03-06 17:49 ` Eli Zaretskii 2018-03-06 17:55 ` dancol 2018-03-06 20:18 ` Eli Zaretskii 2018-03-06 20:20 ` Daniel Colascione 2018-03-06 18:53 ` Sam Steingold 2018-03-06 22:43 ` Ricardo Wurmus 2018-03-07 17:12 ` Eli Zaretskii 2018-03-07 19:38 ` Daniel Colascione 2018-03-07 20:11 ` Eli Zaretskii 2018-03-07 23:01 ` Richard Stallman 2018-03-08 12:33 ` Robert Pluim 2018-03-08 13:50 ` Eli Zaretskii 2018-03-08 15:15 ` Robert Pluim 2018-03-06 20:52 ` Richard Stallman 2018-03-06 4:05 ` Herring, Davis 2018-03-06 13:33 ` Clément Pit-Claudel 2018-03-06 14:18 ` Herring, Davis 2018-03-06 15:02 ` Clément Pit-Claudel 2018-03-06 16:11 ` Eli Zaretskii 2018-03-06 19:59 ` Clément Pit-Claudel 2018-03-06 20:31 ` Eli Zaretskii 2018-03-06 21:15 ` Paul Eggert 2018-03-06 21:47 ` Clément Pit-Claudel 2018-03-07 17:22 ` Eli Zaretskii 2018-03-07 18:27 ` Clément Pit-Claudel 2018-03-07 20:09 ` Eli Zaretskii 2018-03-07 20:32 ` Clément Pit-Claudel 2018-03-08 15:39 ` Eli Zaretskii 2018-03-08 16:30 ` Clément Pit-Claudel 2018-03-08 19:07 ` Eli Zaretskii 2018-03-08 19:55 ` Clément Pit-Claudel 2018-03-09 8:30 ` Eli Zaretskii 2018-03-09 17:52 ` Paul Eggert 2018-03-09 18:35 ` Eli Zaretskii 2018-03-09 20:16 ` Paul Eggert 2018-03-09 21:19 ` Eli Zaretskii 2018-03-09 21:55 ` Paul Eggert 2018-03-10 0:09 ` James Cloos 2018-03-10 8:20 ` Eli Zaretskii 2018-03-10 19:48 ` James Cloos 2018-03-10 20:00 ` Eli Zaretskii 2018-03-10 22:18 ` James Cloos 2018-03-11 3:43 ` Eli Zaretskii 2018-03-09 19:48 ` Clément Pit-Claudel 2018-03-09 21:18 ` Eli Zaretskii 2018-03-09 22:54 ` Clément Pit-Claudel 2018-03-10 8:04 ` Eli Zaretskii 2018-03-10 4:27 ` Yuri Khan 2018-03-10 8:39 ` Eli Zaretskii 2018-03-10 11:42 ` Yuri Khan 2018-03-10 14:28 ` Eli Zaretskii 2018-03-10 13:49 ` Clément Pit-Claudel 2018-03-08 4:50 ` Stefan Monnier 2018-03-08 13:44 ` Eli Zaretskii 2018-03-08 22:03 ` Paul Eggert 2018-03-09 8:34 ` Eli Zaretskii 2018-03-09 16:05 ` Clément Pit-Claudel 2018-03-09 16:21 ` Eli Zaretskii 2018-03-10 8:12 ` Variable-width font alignment Stephen Leake 2018-03-10 8:56 ` Eli Zaretskii 2018-03-10 17:30 ` Stephen Leake 2018-03-10 19:02 ` Eli Zaretskii 2018-03-10 7:42 ` Variable-width font indentation Stephen Leake 2018-03-06 16:35 ` Stefan Monnier 2018-03-06 19:59 ` Clément Pit-Claudel 2018-03-05 23:05 ` Variable-width font indentation (was: What improvements would be truly useful?) Richard Stallman 2018-03-06 16:04 ` Variable-width font indentation Stefan Monnier 2018-03-06 17:43 ` Eli Zaretskii 2018-03-06 18:14 ` Stefan Monnier 2018-03-06 20:56 ` Richard Stallman 2018-03-06 20:55 ` Richard Stallman 2018-03-07 7:05 ` Yuri Khan 2018-03-06 16:14 ` Variable-width font indentation (was: What improvements would be truly useful?) Eli Zaretskii 2018-03-06 20:55 ` Richard Stallman 2018-03-05 18:51 ` What improvements would be truly useful? Daniele Nicolodi 2018-03-05 19:22 ` Eli Zaretskii 2018-03-06 6:32 ` Daniele Nicolodi 2018-03-06 16:52 ` Eli Zaretskii 2018-03-06 17:01 ` Daniel Colascione 2018-03-07 5:45 ` Daniele Nicolodi 2018-03-07 17:45 ` Eli Zaretskii 2018-03-07 17:49 ` Daniele Nicolodi 2018-03-07 18:06 ` Eli Zaretskii 2018-03-07 21:45 ` Philipp Stephani 2018-03-08 13:20 ` Eli Zaretskii 2018-03-08 16:24 ` Alan Third 2018-03-08 18:02 ` Daniel Colascione 2018-03-06 7:48 ` Yuri Khan 2018-03-06 17:08 ` Eli Zaretskii 2018-03-05 21:15 ` Juri Linkov 2018-03-05 23:46 ` Óscar Fuentes 2018-03-06 3:36 ` Eli Zaretskii 2018-04-02 20:40 ` Continuous image scrolling (was: What improvements would be truly useful?) Juri Linkov 2018-04-03 1:59 ` Continuous image scrolling Óscar Fuentes 2018-04-03 7:01 ` Eli Zaretskii 2018-04-03 19:59 ` Juri Linkov 2018-04-03 20:20 ` Drew Adams 2018-04-04 19:54 ` Juri Linkov 2018-04-03 21:08 ` Stefan Monnier 2018-04-03 21:57 ` Clément Pit-Claudel 2018-04-04 6:27 ` Eli Zaretskii 2018-04-04 19:50 ` Juri Linkov 2018-04-05 6:04 ` Eli Zaretskii 2018-04-04 23:31 ` Tak Kunihiro 2018-04-05 2:45 ` Clément Pit-Claudel 2018-04-05 3:54 ` Tak Kunihiro 2018-04-05 19:56 ` Clément Pit-Claudel 2018-04-05 22:59 ` Tak Kunihiro 2018-04-06 4:36 ` Clément Pit-Claudel 2018-04-06 9:35 ` Tak Kunihiro 2018-04-04 19:19 ` John Wiegley 2018-03-05 22:09 ` What improvements would be truly useful? John Wiegley 2018-03-05 23:04 ` daniel sutton 2018-03-06 20:51 ` Richard Stallman 2018-03-08 11:44 ` Toon Claes 2018-03-08 20:08 ` Richard Stallman 2018-03-12 21:53 ` Dmitry Gutov 2018-03-01 23:38 ` Let's make the GC safe and iterative Stefan Monnier 2018-03-02 0:05 ` Daniel Colascione 2018-03-02 13:47 ` Stefan Monnier 2018-02-27 18:00 ` bug#30626: 26.0.91; Crash when traversing a `stream-of-directory-files' Eli Zaretskii
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.