unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Christmas wish: literal elisp
@ 2019-12-20 14:35 arthur miller
  0 siblings, 0 replies; only message in thread
From: arthur miller @ 2019-12-20 14:35 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 1649 bytes --]

My previous patch didn't take into account if a literal comment started with a
'#' or ''' which are valid starters for some elisp expressions. I have now
updated my patch so it checks those as well. Naturally a literal comment can't
start with an '(' as a first non-white character. As I am aware of that is the
only limitation for literal comments. I don't think that would be a deal
breaker. Maybe there are some other places that breaks, that I am not aware of
since I am not good with elisp.

I have tested with org files as well to see if my theorycrafting holds, and it
does (mostly). I was able to evaluate my init file which is several thousands
of lines org file full of elisp (use-package & Co) without entangling it. I
have also tested some simple org feature (code folding) in ordinary elisp and
it also worked as expected. I do get an error message when I load org-mode into
elisp file: "helm-M-x-execute-command: Symbol’s function definition is void: fn"
if I load manually, or if I load org-mode with comment line at the top:
"File mode specification error: (void-function fn)".

However, despite those messages everything seems to work as expected, so I am
not sure about how to deal with those or why do I get them. I get this even when
I load my init.org, but org-mode seems to work normally when I try to edit it.

As a more polish, I think it might be nicer one had buffer local variable to
enable/disable literal comments so that both byte compilera and read-eval loop
could use it. One could then make minor mode to turn literal elisp on/off per
buffer or globally as is usual emacs way of doing this.

[-- Attachment #1.2: Type: text/html, Size: 2486 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bytecomp.patch --]
[-- Type: text/x-patch; name="bytecomp.patch", Size: 3281 bytes --]

--- bytecomp.el	2019-12-20 01:05:44.575414147 +0100
+++ mybytecomp.el	2019-12-20 15:06:04.212544211 +0100
@@ -154,6 +154,14 @@
   :type '(choice (const nil) function)
   :version "23.2")
 
+(defcustom byte-compile-allow-literal-comments nil
+  "If not nil, byte compiler will allow you to type
+   top-level comments without using semicolon in emacs lisp."
+  :group 'bytecomp
+  :type 'boolean
+  :safe #'booleanp
+  :version "27.1")
+
 ;; This enables file name handlers such as jka-compr
 ;; to remove parts of the file name that should not be copied
 ;; through to the output file name.
@@ -2079,8 +2087,8 @@
 	(print-level nil)
 	;; Prevent edebug from interfering when we compile
 	;; and put the output into a file.
-;; 	(edebug-all-defs nil)
-;; 	(edebug-all-forms nil)
+        ;; 	(edebug-all-defs nil)
+        ;; 	(edebug-all-forms nil)
 	;; Simulate entry to byte-compile-top-level
         (byte-compile-jump-tables nil)
         (byte-compile-constants nil)
@@ -2127,19 +2135,37 @@
 			       (= (following-char) ?\;))
 		   (forward-line 1))
 		 (not (eobp)))
-	  (setq byte-compile-read-position (point)
+
+          (setq byte-compile-read-position (point)
 		byte-compile-last-position byte-compile-read-position)
-          (let* ((lread--unescaped-character-literals nil)
-                 (form (read inbuffer))
-                 (warning (byte-run--unescaped-character-literals-warning)))
-            (when warning (byte-compile-warn "%s" warning))
-	    (byte-compile-toplevel-file-form form)))
-	;; Compile pending forms at end of file.
-	(byte-compile-flush-pending)
-	;; Make warnings about unresolved functions
-	;; give the end of the file as their position.
-	(setq byte-compile-last-position (point-max))
-	(byte-compile-warn-about-unresolved-functions))
+
+	  (if byte-compile-allow-literal-comments
+              (progn
+                (if (= (following-char) ?\')
+                    (forward-char))
+                (if (= (following-char) ?\()
+                    (progn
+                      (if (= (preceding-char) ?\')
+                          (backward-char))
+                      (let* ((lread--unescaped-character-literals nil)
+                             (form (read inbuffer))
+                             (warning (byte-run--unescaped-character-literals-warning)))
+                        (when warning (byte-compile-warn "%s" warning))
+	                (byte-compile-toplevel-file-form form)))
+                  (forward-line 1)))
+            (progn
+              (let* ((lread--unescaped-character-literals nil)
+                     (form (read inbuffer))
+                     (warning (byte-run--unescaped-character-literals-warning)))
+                (when warning (byte-compile-warn "%s" warning))
+	        (byte-compile-toplevel-file-form form)))))
+
+        ;; Compile pending forms at end of file.
+        (byte-compile-flush-pending)
+        ;; Make warnings about unresolved functions
+        ;; give the end of the file as their position.
+        (setq byte-compile-last-position (point-max))
+        (byte-compile-warn-about-unresolved-functions))
       ;; Fix up the header at the front of the output
       ;; if the buffer contains multibyte characters.
       (and byte-compile-current-file

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: lread.patch --]
[-- Type: text/x-patch; name="lread.patch", Size: 1041 bytes --]

--- lread.c	2019-12-20 01:07:33.264089317 +0100
+++ mylread.c	2019-12-20 15:05:45.035493674 +0100
@@ -1955,6 +1955,8 @@
   /* True on the first time around.  */
   bool first_sexp = 1;
   Lisp_Object macroexpand = intern ("internal-macroexpand-for-load");
+  Lisp_Object litcode = intern ("emacs-lisp-allow-literal-comments");
+  Lisp_Object allow_literal_comments = find_symbol_value(litcode);
 
   if (NILP (Ffboundp (macroexpand))
       || (STRINGP (sourcename) && suffix_p (sourcename, ".elc")))
@@ -2053,6 +2055,20 @@
 	  || c == NO_BREAK_SPACE)
 	goto read_next;
 
+      if (EQ (allow_literal_comments, Qt))
+        {
+          if (c != '(')
+            {
+              if(c == '#') c = READCHAR;
+              if(c == '(') UNREAD(c);
+              else
+                {
+                  while ((c = READCHAR) != '\n' && c != -1);
+                  goto read_next;
+                }
+            }
+        }
+
       if (! HASH_TABLE_P (read_objects_map)
 	  || XHASH_TABLE (read_objects_map)->count)
 	read_objects_map

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: chatty.el --]
[-- Type: text/x-emacs-lisp; name="chatty.el", Size: 720 bytes --]

;; -*- mode: org; -*-

Elisp now alows comments without ;.

' can also use start literal comments with
# also works

* Some elisp here
(setq emacs-lisp-allow-literal-comments t)
(setq byte-compile-allow-literal-comments t)
(message "I can now run simple elisp on my own!")

* More stuff here
#+BEGIN_SRC emacs-lisp
(message "Hello, World!")
#+END_SRC

It is of course possible to intertwene code
with comments anywhere in the file.

(message "Hello Again!")

Of course we can also comment-out code
just as before:

;;(message "I am silent")
In code blocs the ';' is still a comment delimiter:
(message
 ;; Here is a line comment
 "I am a bit chatty today!")

That's it for today folks!

(message "Bye bye cruel world!")

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-12-20 14:35 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-12-20 14:35 Christmas wish: literal elisp arthur miller

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).