An Emacs major mode for editing shiftless configuration files and a loader & dumper.
(require 'shiftless-mode)You have your font-lock (colors), you have your indentation, and you have your interface to insert structures:
| Shortcut | Action |
|---|---|
C-c l | insert a list |
C-c a | insert an association |
C-u ... | insert list or association without surrounding brackets |
C-u C-u ... | insert list or association without any newlines |
Value: prompts automatically escape strings, so no need to surround strings with single quotes or type any more backslashes than you actually want.
Value: prompts also accept a or l to insert a nested list or association
You can customize shiftless:indent-level (default 2 spaces).
(require 'shiftless)sample.slc:
anime = [
title = 'JoJo\'s Bizarre Adventure'
mangaka = [
first-name = 'Hirohiko'
last-name = 'Araki'
age = immortal]
parts = ['Phantom Blood' 'Stardust Crusaders' 'Diamond is Unbreakable' 'Golden Wind']
rating = 11/10
episodes = 152
[manga chapters] = [917]]
shiftless:load can take a file name or a string containing shiftless.
(let ((data (shiftless:load "sample.slc")))
;; implicit type access
(shiftless:access-value data 'anime 'mangaka 'age) ;importal
(shiftless:access-value data 'anime 'manga 'chapters) ;917
;; explicit type access
(shiftless:access-as 'string data 'anime 'mangaka 'age) ;"importal"
(shiftless:access-as 'symbol data 'anime 'mangaka 'last-name) ;araki
)You can also use shiftless:presentp with the same arguments as shiftless:access-value to see if the data includes a certain property.
If you want data structures eagerly loaded instead of delaying parsing until access, you can use a schema as the second argument to shiftless:load. There is the built in schema, :implicit, which loads things based on their written type (‘string’ is a string, -124.4 is a float, symbol is a symbol, t is true). Otherwise, you can give a file name of a schema file which is formatted the way you want your configuration formatted except instead of values, you have symbols that represent types: integer, float, symbol, string, boolean, or a list containing a type or other structure ([float] means list of floats).
db-info.slc
versions = [
my = 4.2.2
postgres = 5.30
ms = 3.4.1]
active = postgres
schema.slc
versions = [
my = string
postgres = string
ms = string]
active = string
It is not suggested to use shiftless:access-value while using a schema because the type has already been calculated.
(let ((data (shiftless:load "db-info.slc"
"schema.slc")))
;; access data
(shiftless:access data 'versions 'postgres) ; "5.30"
(shiftless:access data 'active) ; "postgres"
)shiftless:dump takes a lisp data structure and a file name. It writes the equivalent shiftless data structure to the file.
shiftless:stringify takes a lisp data structure and outputs the equivalent shiftless data structure as a string.
Both also take arguments to customize newlines and indent level.