Skip to content

emacs-twist/fromElisp

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 

Repository files navigation

fromElisp

An Emacs Lisp reader in Nix. Yes, it’s necessary.

nix-repl> :p fromElisp "(use-package lsp-mode :ensure :commands lsp)"
[ [ "use-package" "lsp-mode" ":ensure" ":commands" "lsp" ] ]

Functionality

fromElisp provides four main functions: fromElisp, parseElisp, fromOrgModeBabelElisp and parseOrgModeBabelElisp.

  • fromElisp elisp (string)

    Takes a string argument and tries to convert the Elisp read from it to the closest equivalent data type in Nix.

    For example,

    (use-package highlight-symbol
      :ensure t
      :hook (((python-mode emacs-lisp-mode nix-mode) . highlight-symbol-mode)
             ((python-mode emacs-lisp-mode nix-mode) . highlight-symbol-nav-mode))
      :config
      (highlight-symbol-nav-mode)
      (setq highlight-symbol-idle-delay 0.5)
      (set-face-attribute 'highlight-symbol-face nil :background "dark cyan"))
        

    is read as

    [[ "use-package" "highlight-symbol"
       ":ensure" true
       ":hook" [[[ "python-mode" "emacs-lisp-mode" "nix-mode" ] "highlight-symbol-mode" ]
                [[ "python-mode" "emacs-lisp-mode" "nix-mode" ] "highlight-symbol-nav-mode" ]]
       ":config"
       [ "highlight-symbol-nav-mode" ]
       [ "setq" "highlight-symbol-idle-delay" 0.5 ]
       [ "set-face-attribute" [ "quote" "highlight-symbol-face" ] [ ] ":background" "dark cyan" ]]]
        
  • parseElisp elisp (string)

    Takes a string argument and provides an AST with additional structural info, such as object type, line number and list depth.

    The AST provided for the code

    (setq mouse-wheel-scroll-amount '(3 ((shift) . 1)))
        

    would be

    [{ depth = 0; line = 1; type = "list"; value = [
         { line = 1; type = "symbol"; value = "setq"; }
         { line = 1; type = "symbol"; value = "mouse-wheel-scroll-amount"; }
         { line = 1; type = "quote"; value = {
             depth = 1; line = 1; type = "list"; value = [
               { line = 1; type = "integer"; value = 3; }
               { depth = 2; line = 1; type = "list"; value = [
                   { depth = 3; line = 1; type = "list"; value = [
                       { line = 1; type = "symbol"; value = "shift"; }
                     ];
                   }
                   { line = 1; type = "integer"; value = 1; }
                 ];
               }
             ];
           };
         }
       ];
     }]
        
  • fromOrgModeBabelElisp text (string)

    fromElisp, but for Org mode babel files. Runs fromElisp on the result of tangling all Elisp code blocks with :tangle yes set. Tangling is done internally, not by Org mode.

  • parseOrgModeBabelElisp text (string)

    parseElisp, but for Org mode babel files. Runs parseElisp on the result of tangling all Elisp code blocks with :tangle yes set. Tangling is done internally, not by Org mode.

Other functions

  • tokenizeElisp elisp (string)

    Takes a string argument and produces a list of tokens from the Elisp read from it. Used internally by fromElisp and parseElisp.

  • tokenizeElisp’ args (attrs)

    An alternate version of tokenizeElisp allowing the specification of the starting line number.

    args is an attribute set with the following attributes:

    • elisp (string, required)

      The string of Elisp to tokenize.

    • startLineNumber (int, optional)

      The line number to use for the first line of elisp. Useful if elisp is a block of code from a larger file and you want line numbers to be correct.

  • parseElisp’ tokens (list)

    An alternate version of parseElisp which takes as its argument a list of tokens produced by tokenizeElisp.

  • fromElisp’ ast (list)

    An alternate version of fromElisp which takes as its argument an AST produced by parseElisp.

  • tokenizeOrgModeBabelElisp text (string)

    Run tokenizeElisp’ on all Elisp code blocks (with :tangle yes set) from Org mode babel text text.

  • tokenizeOrgModeBabelElisp’ defaultArgs (attrs) text (string)

    An alternate version of tokenizeOrgModeBabelElisp which allows the specification of default arguments for Org babel headers. Currently only :tangle is supported.

  • parseOrgBabelElisp’ defaultArgs (attrs) text (string)

    An alternate version of parseOrgBabelElisp which allows the specification of default arguments for Org babel headers. Currently only :tangle is supported.

  • fromOrgBabelElisp’ defaultArgs (attrs) text (string)

    An alternate version of fromOrgModeBabelElisp which allows the specification of default arguments for Org babel headers. Currently only :tangle is supported.

Usage

You can use fromElisp in your code in multiple ways.

fetchGit

You can use fetchGit without a rev attribute to try it out quickly and then add the rev when you want reproducibility.

with (import (builtins.fetchGit {
  url = "https://github.com/talyz/fromElisp.git";
  ref = "master";
  # rev = "c13d6035666f36ca940db996f1dbaf83cb4e8453";
}));
# ... code ...

niv

If you use niv to manage your Nix dependencies, simply run

$ niv add talyz/fromElisp

to add fromElisp to your dependencies and import it as follows:

with (import (import ./nix/sources.nix).fromElisp {});
# ... code ...

Git submodule

If you plan on contributing to fromElisp and want to do it from your own source, you can import it as a Git submodule.

Limitations

  • No Unicode support

    Nix doesn’t support Unicode, so we can’t either.

  • No evaluation

    This is a reader and not an evaluator. You can make some pretty reasonable assumptions from the structure of the code, though: it’s, for example, used in the Emacs overlay to implement the functionality of emacsWithPackagesFromUsePackage.

About

An Emacs Lisp reader in Nix.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Nix 100.0%