• R/O
  • SSH

Joypy: Commit

Main interpreter and library.


Commit MetaInfo

Revision1f58e80502723e9bbc804cdde850659958153aeb (tree)
Time2018-07-22 09:56:53
AuthorSimon Forman <sforman@hush...>
CommiterSimon Forman

Log Message

Config file and CLI arg parser.

Change Summary

Incremental Difference

diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/default_joy_home/definitions.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/joy/gui/default_joy_home/definitions.txt Sat Jul 21 17:56:53 2018 -0700
@@ -0,0 +1,17 @@
1+see_stack == good_viewer_location open_stack
2+see_resources == list_resources good_viewer_location open_viewer
3+open_resource_at_good_location == good_viewer_location open_resource
4+see_log == "log.txt" open_resource_at_good_location
5+see_definitions == "definitions.txt" open_resource_at_good_location
6+round_to_cents == 100 * ++ floor 100 /
7+reset_log == "del log.lines[1:] ; log.at_line = 0" evaluate
8+see_menu == "menu.txt" good_viewer_location open_resource
9+
10+# Ordered Binary Tree datastructure functions.
11+BTree-new == swap [[] []] cons cons
12+ _BTree-P == over [popop popop first] nullary
13+ _BTree-T> == [cons cons dipdd] cons cons cons infra
14+ _BTree-T< == [cons cons dipd] cons cons cons infra
15+ _BTree-E == pop swap roll< rest rest cons cons
16+ _BTree-recur == _BTree-P [_BTree-T>] [_BTree-E] [_BTree-T<] cmp
17+BTree-add == [popop not] [[pop] dipd BTree-new] [] [_BTree-recur] genrec
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/default_joy_home/log.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/joy/gui/default_joy_home/log.txt Sat Jul 21 17:56:53 2018 -0700
@@ -0,0 +1,4 @@
1+Joypy - Copyright © 2018 Simon Forman
2+This program comes with ABSOLUTELY NO WARRANTY; for details right-click "warranty". This is free software, and you are welcome to redistribute it under certain conditions; right-click "sharing" for details. Right-click on these commands to see docs on UI commands: key_bindings mouse_bindings
3+
4+ <-
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/default_joy_home/scratch.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/joy/gui/default_joy_home/scratch.txt Sat Jul 21 17:56:53 2018 -0700
@@ -0,0 +1,120 @@
1+reset_log words mouse_bindings key_bindings
2+
3+Stack Chatter
4+
5+ dup dupd dupdd over tuck
6+ pop popd popdd popop popopd popopdd
7+ swap roll< roll> rolldown rollup
8+ unit clear
9+
10+Math
11+
12+ add + sub - mul * truediv / mod %
13+ div divmod floor pm
14+ abs sqr sqrt neg pow
15+ max min sum average product
16+ pred -- succ ++ lshift << rshift >>
17+
18+Logic
19+
20+ ge gt eq le lt ne
21+ < <= = >= > != <>
22+ and & or not xor ^
23+ bool truthy ?
24+
25+Combinators
26+
27+ i x b infra dip dipd dipdd dupdip dupdipd
28+ cleave fork app1 app2 app3 map pam
29+ nullary unary binary ternary
30+
31+Control Flow
32+
33+ branch cond ifte choice
34+ loop while genrec primrec
35+ make_generator
36+
37+List Manipulation
38+
39+ enstacken disenstacken stack unstack
40+ first first_two second third fourth rest rrest
41+ flatten drop take reverse select zip
42+ size sort shunt getitem
43+ step step_zero times
44+ cons ccons uncons swons unswons
45+ concat unique
46+ remove
47+ at of pick
48+ unquoted quoted
49+
50+Misc
51+
52+ down_to_zero cmp gcd help id
53+ least_fraction parse quoted
54+ range range_to_zero
55+ reset_log show_log
56+ run
57+ stuncons stununcons
58+ swaack
59+ void
60+
61+
62+[ ] Add logging?
63+[ ] INI file?
64+[ ] definitions.txt
65+[ ] Integrate inference
66+[ ] command to (re-)run with trace
67+[ ] Backtime button?
68+
69+
70+------------------------------------------
71+[23 18] [unit i]
72+
73+sqr foo == uncons mul
74+
75+ swaack
76+
77+ over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
78+
79+5 sqrt 2 / 0.5 +
80+5 sqrt 1 + 2 /
81+phi == 5 sqrt ++ 2 /
82+phi == 1.618033988749895
83+(But this is Lambda Abstaction sneaking in the back door.)
84+=
85+clear
86+
87+(n1 n2 -- ☯)
88+
89+2018 20 18 20 23 0.5
90+472 83 / -7
91+100
92+
93+100 * floor 100 / show_log
94+
95+[2 3] [swap truediv] infra
96+
97+dup infra key_bindings divmod
98+
99+ 1 [dup 1 <<] make_generator 23 [x popd] times first
100+
101+mcc91 == [100 >] [10 -] [11 + mcc91 mcc91] ifte
102+ == [100 >] [10 -] [11 + [mcc91] [mcc91] b] ifte
103+ == [100 >] [10 -] [11 + [mcc91] dup b] ifte
104+mcc91 == [100 >] [10 -] [11 +] [dup b] genrec
105+
106+279841 20 20 20 202318 279841 279841 27984127984120202318
107+
108+inscribe
109+
110+round_to_cents == 100 * ++ floor 100 /
111+
112+
113+ [12 18] [[pm] infra] make_generator
114+
115+ [12 18] [[[+] [3 /] fork popopdd] infra] make_generator
116+
117+ [stack] [pop] while
118+
119+
120+
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/default_joy_home/stack.pickle
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/joy/gui/default_joy_home/stack.pickle Sat Jul 21 17:56:53 2018 -0700
@@ -0,0 +1,1 @@
1+(t.
\ No newline at end of file
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/default_joy_home/thun.config
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/joy/gui/default_joy_home/thun.config Sat Jul 21 17:56:53 2018 -0700
@@ -0,0 +1,53 @@
1+
2+[key bindings]
3+<F5> = swap
4+<F6> = dup
5+<Shift-F5> = roll<
6+<Shift-F6> = roll>
7+<F7> = over
8+<Shift-F7> = tuck
9+<F8> = parse
10+<F12> = words
11+<F1> = reset_log show_log
12+<Escape> = clear reset_log show_log
13+<Control-Delete> = pop
14+<Control-i> = i
15+
16+
17+[Definitions]
18+of = swap at
19+product = 1 swap [*] step
20+flatten = [] swap [concat] step
21+quoted = [unit] dip
22+unquoted = [i] dip
23+enstacken = stack [clear] dip
24+? = dup truthy
25+disenstacken = ? [uncons ?] loop pop
26+dinfrirst = dip infra first
27+nullary = [stack] dinfrirst
28+unary = nullary popd
29+binary = nullary [popop] dip
30+ternary = unary [popop] dip
31+pam = [i] map
32+run = [] swap infra
33+sqr = dup mul
34+size = 0 swap [pop ++] step
35+fork = [i] app2
36+cleave = fork [popd] dip
37+average = [sum 1.0 *] [size] cleave /
38+gcd = 1 [tuck modulus dup 0 >] loop pop
39+least_fraction = dup [gcd] infra [div] concat map
40+*fraction = [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons
41+*fraction0 = concat [[swap] dip * [*] dip] infra
42+down_to_zero = [0 >] [dup --] while
43+range_to_zero = unit [down_to_zero] infra
44+anamorphism = [pop []] swap [dip swons] genrec
45+range = [0 <=] [1 - dup] anamorphism
46+while = swap [nullary] cons dup dipd concat loop
47+dupdipd = dup dipd
48+primrec = [i] genrec
49+step_zero = 0 roll> step
50+codireco = cons dip rest cons
51+make_generator = [codireco] ccons
52+ifte = [nullary not] dipd branch
53+
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/init_joy_home.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/joy/gui/init_joy_home.py Sat Jul 21 17:56:53 2018 -0700
@@ -0,0 +1,124 @@
1+'''
2+Utility module to help with setting up the initial contents of the
3+JOY_HOME directory.
4+
5+These contents are kept in this Python module as a base64-encoded zip
6+file, so you can just do, e.g.:
7+
8+ import init_joy_home
9+ init_joy_home.initialize(JOY_HOME)
10+
11+'''
12+import base64, os, StringIO, zipfile
13+
14+
15+def initialize(joy_home):
16+ Z.extractall(joy_home)
17+
18+
19+def create_data(from_dir='./default_joy_home'):
20+ f = StringIO.StringIO()
21+ z = zipfile.ZipFile(f, mode='w')
22+ for fn in os.listdir(from_dir):
23+ from_fn = os.path.join(from_dir, fn)
24+ z.write(from_fn, fn)
25+ z.close()
26+ return base64.encodestring(f.getvalue())
27+
28+
29+Z = zipfile.ZipFile(StringIO.StringIO(base64.decodestring('''\
30+UEsDBBQAAAAAAKW29EyLEfLTUQgAAFEIAAALAAAAc2NyYXRjaC50eHRyZXNldF9sb2cgd29yZHMg
31+bW91c2VfYmluZGluZ3Mga2V5X2JpbmRpbmdzCgpTdGFjayBDaGF0dGVyCgogZHVwIGR1cGQgZHVw
32+ZGQgb3ZlciB0dWNrCiBwb3AgcG9wZCBwb3BkZCBwb3BvcCBwb3BvcGQgcG9wb3BkZAogc3dhcCBy
33+b2xsPCByb2xsPiByb2xsZG93biByb2xsdXAgCiB1bml0IGNsZWFyCgpNYXRoCgogYWRkICsgc3Vi
34+IC0gbXVsICogdHJ1ZWRpdiAvIG1vZCAlCiBkaXYgZGl2bW9kIGZsb29yIHBtCiBhYnMgc3FyIHNx
35+cnQgbmVnIHBvdwogbWF4IG1pbiBzdW0gYXZlcmFnZSBwcm9kdWN0CiBwcmVkIC0tIHN1Y2MgKysg
36+bHNoaWZ0IDw8IHJzaGlmdCA+PgoKTG9naWMKCiBnZSBndCBlcSBsZSBsdCBuZQogIDwgPD0gPSAg
37+Pj0gPiAgIT0gPD4KIGFuZCAmIG9yIG5vdCB4b3IgXgogYm9vbCB0cnV0aHkgPwoKQ29tYmluYXRv
38+cnMKCiBpIHggYiBpbmZyYSBkaXAgZGlwZCBkaXBkZCBkdXBkaXAgZHVwZGlwZAogY2xlYXZlIGZv
39+cmsgYXBwMSBhcHAyIGFwcDMgbWFwIHBhbQogbnVsbGFyeSB1bmFyeSBiaW5hcnkgdGVybmFyeSAK
40+CkNvbnRyb2wgRmxvdwoKIGJyYW5jaCBjb25kIGlmdGUgY2hvaWNlCiBsb29wIHdoaWxlIGdlbnJl
41+YyBwcmltcmVjCiBtYWtlX2dlbmVyYXRvcgoKTGlzdCBNYW5pcHVsYXRpb24KCiBlbnN0YWNrZW4g
42+ZGlzZW5zdGFja2VuIHN0YWNrIHVuc3RhY2sKIGZpcnN0IGZpcnN0X3R3byBzZWNvbmQgdGhpcmQg
43+Zm91cnRoIHJlc3QgcnJlc3QKIGZsYXR0ZW4gZHJvcCB0YWtlIHJldmVyc2Ugc2VsZWN0IHppcAog
44+c2l6ZSBzb3J0IHNodW50IGdldGl0ZW0KIHN0ZXAgc3RlcF96ZXJvIHRpbWVzIAogY29ucyBjY29u
45+cyB1bmNvbnMgc3dvbnMgdW5zd29ucwogY29uY2F0IHVuaXF1ZQogcmVtb3ZlCiBhdCBvZiBwaWNr
46+CiB1bnF1b3RlZCBxdW90ZWQKCk1pc2MKCiBkb3duX3RvX3plcm8gY21wIGdjZCBoZWxwIGlkIAog
47+bGVhc3RfZnJhY3Rpb24gcGFyc2UgcXVvdGVkCiByYW5nZSByYW5nZV90b196ZXJvCiByZXNldF9s
48+b2cgIHNob3dfbG9nCiBydW4gCiBzdHVuY29ucyBzdHVudW5jb25zCiBzd2FhY2sgCiB2b2lkICAg
49+ICAKCgpbIF0gQWRkIGxvZ2dpbmc/ClsgXSBJTkkgZmlsZT8KWyBdIGRlZmluaXRpb25zLnR4dApb
50+IF0gSW50ZWdyYXRlIGluZmVyZW5jZQpbIF0gY29tbWFuZCB0byAocmUtKXJ1biB3aXRoIHRyYWNl
51+ClsgXSBCYWNrdGltZSBidXR0b24/CgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
52+LS0tLS0tLS0tClsyMyAxOF0gICBbdW5pdCBpXQoKc3FyICBmb28gPT0gdW5jb25zIG11bAoKIHN3
53+YWFjawoKIG92ZXIgW1tbbmVnXSBkdXBkaXAgc3FyIDRdIGRpcGQgKiAqIC0gc3FydCBwbV0gZGlw
54+IDIgKiBbL10gY29ucyBhcHAyCgo1IHNxcnQgMiAvIDAuNSArCjUgc3FydCAxICsgMiAvCnBoaSA9
55+PSA1IHNxcnQgKysgMiAvCnBoaSA9PSAxLjYxODAzMzk4ODc0OTg5NQooQnV0IHRoaXMgaXMgTGFt
56+YmRhIEFic3RhY3Rpb24gc25lYWtpbmcgaW4gdGhlIGJhY2sgZG9vci4pCj0KY2xlYXIKCihuMSBu
57+MiAtLSDimK8pCgoyMDE4IDIwIDE4IDIwIDIzIDAuNQo0NzIgODMgLyAtNwoxMDAKCjEwMCAqIGZs
58+b29yIDEwMCAvICBzaG93X2xvZwoKWzIgM10gW3N3YXAgdHJ1ZWRpdl0gaW5mcmEKCmR1cCBpbmZy
59+YSBrZXlfYmluZGluZ3MgZGl2bW9kCgogIDEgW2R1cCAxIDw8XSBtYWtlX2dlbmVyYXRvciAgIDIz
60+IFt4IHBvcGRdIHRpbWVzIGZpcnN0CgptY2M5MSA9PSBbMTAwID5dIFsxMCAtXSBbMTEgKyBtY2M5
61+MSBtY2M5MV0gaWZ0ZQogICAgICA9PSBbMTAwID5dIFsxMCAtXSBbMTEgKyBbbWNjOTFdIFttY2M5
62+MV0gYl0gaWZ0ZQogICAgICA9PSBbMTAwID5dIFsxMCAtXSBbMTEgKyBbbWNjOTFdIGR1cCBiXSBp
63+ZnRlCm1jYzkxID09IFsxMDAgPl0gWzEwIC1dIFsxMSArXSBbZHVwIGJdIGdlbnJlYwoKMjc5ODQx
64+IDIwIDIwIDIwIDIwMjMxOCAyNzk4NDEgMjc5ODQxIDI3OTg0MTI3OTg0MTIwMjAyMzE4CgppbnNj
65+cmliZQoKcm91bmRfdG9fY2VudHMgPT0gMTAwICogKysgZmxvb3IgMTAwIC8KCgogICAgWzEyIDE4
66+XSBbW3BtXSBpbmZyYV0gbWFrZV9nZW5lcmF0b3IKCiAgICBbMTIgMThdIFtbWytdIFszIC9dIGZv
67+cmsgcG9wb3BkZF0gaW5mcmFdIG1ha2VfZ2VuZXJhdG9yCgogICBbc3RhY2tdIFtwb3BdIHdoaWxl
68+CgoKClBLAwQUAAAAAABAQfVM5+RkR1EBAABRAQAABwAAAGxvZy50eHRKb3lweSAtIENvcHlyaWdo
69+dCDCqSAyMDE4IFNpbW9uIEZvcm1hbgpUaGlzIHByb2dyYW0gY29tZXMgd2l0aCBBQlNPTFVURUxZ
70+IE5PIFdBUlJBTlRZOyBmb3IgZGV0YWlscyByaWdodC1jbGljayAid2FycmFudHkiLiBUaGlzIGlz
71+IGZyZWUgc29mdHdhcmUsIGFuZCB5b3UgYXJlIHdlbGNvbWUgdG8gcmVkaXN0cmlidXRlIGl0IHVu
72+ZGVyIGNlcnRhaW4gY29uZGl0aW9uczsgcmlnaHQtY2xpY2sgInNoYXJpbmciIGZvciBkZXRhaWxz
73+LiBSaWdodC1jbGljayBvbiB0aGVzZSBjb21tYW5kcyB0byBzZWUgZG9jcyBvbiBVSSBjb21tYW5k
74+czoga2V5X2JpbmRpbmdzIG1vdXNlX2JpbmRpbmdzCgogPC0KUEsDBBQAAAAAAEFB9Ux3f5peAwAA
75+AAMAAAAMAAAAc3RhY2sucGlja2xlKHQuUEsDBBQAAAAAAHy09ExY7AlUJgUAACYFAAALAAAAdGh1
76+bi5jb25maWcKW2tleSBiaW5kaW5nc10KPEY1PiA9IHN3YXAKPEY2PiA9IGR1cAo8U2hpZnQtRjU+
77+ID0gcm9sbDwKPFNoaWZ0LUY2PiA9IHJvbGw+CjxGNz4gPSBvdmVyCjxTaGlmdC1GNz4gPSB0dWNr
78+CjxGOD4gPSBwYXJzZQo8RjEyPiA9IHdvcmRzCjxGMT4gPSByZXNldF9sb2cgc2hvd19sb2cKPEVz
79+Y2FwZT4gPSBjbGVhciByZXNldF9sb2cgc2hvd19sb2cKPENvbnRyb2wtRGVsZXRlPiA9IHBvcAo8
80+Q29udHJvbC1pPiA9IGkKCgpbRGVmaW5pdGlvbnNdCm9mID0gc3dhcCBhdApwcm9kdWN0ID0gMSBz
81+d2FwIFsqXSBzdGVwCmZsYXR0ZW4gPSBbXSBzd2FwIFtjb25jYXRdIHN0ZXAKcXVvdGVkID0gW3Vu
82+aXRdIGRpcAp1bnF1b3RlZCA9IFtpXSBkaXAKZW5zdGFja2VuID0gc3RhY2sgW2NsZWFyXSBkaXAK
83+PyA9IGR1cCB0cnV0aHkKZGlzZW5zdGFja2VuID0gPyBbdW5jb25zID9dIGxvb3AgcG9wCmRpbmZy
84+aXJzdCA9IGRpcCBpbmZyYSBmaXJzdApudWxsYXJ5ID0gW3N0YWNrXSBkaW5mcmlyc3QKdW5hcnkg
85+PSBudWxsYXJ5IHBvcGQKYmluYXJ5ID0gbnVsbGFyeSBbcG9wb3BdIGRpcAp0ZXJuYXJ5ID0gdW5h
86+cnkgW3BvcG9wXSBkaXAKcGFtID0gW2ldIG1hcApydW4gPSBbXSBzd2FwIGluZnJhCnNxciA9IGR1
87+cCBtdWwKc2l6ZSA9IDAgc3dhcCBbcG9wICsrXSBzdGVwCmZvcmsgPSBbaV0gYXBwMgpjbGVhdmUg
88+PSBmb3JrIFtwb3BkXSBkaXAKYXZlcmFnZSA9IFtzdW0gMS4wICpdIFtzaXplXSBjbGVhdmUgLwpn
89+Y2QgPSAxIFt0dWNrIG1vZHVsdXMgZHVwIDAgPl0gbG9vcCBwb3AKbGVhc3RfZnJhY3Rpb24gPSBk
90+dXAgW2djZF0gaW5mcmEgW2Rpdl0gY29uY2F0IG1hcAoqZnJhY3Rpb24gPSBbdW5jb25zXSBkaXAg
91+dW5jb25zIFtzd2FwXSBkaXAgY29uY2F0IFsqXSBpbmZyYSBbKl0gZGlwIGNvbnMKKmZyYWN0aW9u
92+MCA9IGNvbmNhdCBbW3N3YXBdIGRpcCAqIFsqXSBkaXBdIGluZnJhCmRvd25fdG9femVybyA9IFsw
93+ID5dIFtkdXAgLS1dIHdoaWxlCnJhbmdlX3RvX3plcm8gPSB1bml0IFtkb3duX3RvX3plcm9dIGlu
94+ZnJhCmFuYW1vcnBoaXNtID0gW3BvcCBbXV0gc3dhcCBbZGlwIHN3b25zXSBnZW5yZWMKcmFuZ2Ug
95+PSBbMCA8PV0gWzEgLSBkdXBdIGFuYW1vcnBoaXNtCndoaWxlID0gc3dhcCBbbnVsbGFyeV0gY29u
96+cyBkdXAgZGlwZCBjb25jYXQgbG9vcApkdXBkaXBkID0gZHVwIGRpcGQKcHJpbXJlYyA9IFtpXSBn
97+ZW5yZWMKc3RlcF96ZXJvID0gMCByb2xsPiBzdGVwCmNvZGlyZWNvID0gY29ucyBkaXAgcmVzdCBj
98+b25zCm1ha2VfZ2VuZXJhdG9yID0gW2NvZGlyZWNvXSBjY29ucwppZnRlID0gW251bGxhcnkgbm90
99+XSBkaXBkIGJyYW5jaAoKUEsDBBQAAAAAAEK0k0yW6MvDbQMAAG0DAAAPAAAAZGVmaW5pdGlvbnMu
100+dHh0c2VlX3N0YWNrID09IGdvb2Rfdmlld2VyX2xvY2F0aW9uIG9wZW5fc3RhY2sKc2VlX3Jlc291
101+cmNlcyA9PSBsaXN0X3Jlc291cmNlcyBnb29kX3ZpZXdlcl9sb2NhdGlvbiBvcGVuX3ZpZXdlcgpv
102+cGVuX3Jlc291cmNlX2F0X2dvb2RfbG9jYXRpb24gPT0gZ29vZF92aWV3ZXJfbG9jYXRpb24gb3Bl
103+bl9yZXNvdXJjZQpzZWVfbG9nID09ICJsb2cudHh0IiBvcGVuX3Jlc291cmNlX2F0X2dvb2RfbG9j
104+YXRpb24Kc2VlX2RlZmluaXRpb25zID09ICJkZWZpbml0aW9ucy50eHQiIG9wZW5fcmVzb3VyY2Vf
105+YXRfZ29vZF9sb2NhdGlvbgpyb3VuZF90b19jZW50cyA9PSAxMDAgKiArKyBmbG9vciAxMDAgLwpy
106+ZXNldF9sb2cgPT0gImRlbCBsb2cubGluZXNbMTpdIDsgbG9nLmF0X2xpbmUgPSAwIiBldmFsdWF0
107+ZQpzZWVfbWVudSA9PSAibWVudS50eHQiIGdvb2Rfdmlld2VyX2xvY2F0aW9uIG9wZW5fcmVzb3Vy
108+Y2UKCiMgT3JkZXJlZCBCaW5hcnkgVHJlZSBkYXRhc3RydWN0dXJlIGZ1bmN0aW9ucy4KQlRyZWUt
109+bmV3ID09IHN3YXAgW1tdIFtdXSBjb25zIGNvbnMKIF9CVHJlZS1QID09IG92ZXIgW3BvcG9wIHBv
110+cG9wIGZpcnN0XSBudWxsYXJ5CiBfQlRyZWUtVD4gPT0gW2NvbnMgY29ucyBkaXBkZF0gY29ucyBj
111+b25zIGNvbnMgaW5mcmEKIF9CVHJlZS1UPCA9PSBbY29ucyBjb25zIGRpcGRdIGNvbnMgY29ucyBj
112+b25zIGluZnJhCiBfQlRyZWUtRSA9PSBwb3Agc3dhcCByb2xsPCByZXN0IHJlc3QgY29ucyBjb25z
113+CiBfQlRyZWUtcmVjdXIgPT0gX0JUcmVlLVAgW19CVHJlZS1UPl0gW19CVHJlZS1FXSBbX0JUcmVl
114+LVQ8XSBjbXAKQlRyZWUtYWRkID09IFtwb3BvcCBub3RdIFtbcG9wXSBkaXBkIEJUcmVlLW5ld10g
115+W10gW19CVHJlZS1yZWN1cl0gZ2VucmVjClBLAQIUAxQAAAAAAKW29EyLEfLTUQgAAFEIAAALAAAA
116+AAAAAAAAAACAgQAAAABzY3JhdGNoLnR4dFBLAQIUAxQAAAAAAEBB9Uzn5GRHUQEAAFEBAAAHAAAA
117+AAAAAAAAAACAgXoIAABsb2cudHh0UEsBAhQDFAAAAAAAQUH1THd/ml4DAAAAAwAAAAwAAAAAAAAA
118+AAAAAICB8AkAAHN0YWNrLnBpY2tsZVBLAQIUAxQAAAAAAHy09ExY7AlUJgUAACYFAAALAAAAAAAA
119+AAAAAAC0gR0KAAB0aHVuLmNvbmZpZ1BLAQIUAxQAAAAAAEK0k0yW6MvDbQMAAG0DAAAPAAAAAAAA
120+AAAAAAC0gWwPAABkZWZpbml0aW9ucy50eHRQSwUGAAAAAAUABQAeAQAABhMAAAAA''')))
121+
122+
123+if __name__ == '__main__':
124+ print create_data()
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/main.py
--- a/joy/gui/main.py Fri Jul 20 12:33:06 2018 -0700
+++ b/joy/gui/main.py Sat Jul 21 17:56:53 2018 -0700
@@ -8,15 +8,16 @@
88 ' right-click "sharing" for details.'
99 ' Right-click on these commands to see docs on UI commands: key_bindings mouse_bindings')
1010 import logging, os, pickle, sys
11+from textwrap import dedent
12+from ConfigParser import RawConfigParser
13+
14+from joy.gui.utils import init_home, argparser, FileFaker
15+
16+args = argparser.parse_args()
17+JOY_HOME = args.joy_home
18+
1119
1220 _log = logging.getLogger(__name__)
13-
14-from textwrap import dedent
15-
16-from joy.gui.utils import init_home, FileFaker
17-
18-JOY_HOME, repo = init_home()
19-
2021 logging.basicConfig(
2122 format='%(asctime)-15s %(levelname)s %(name)s %(message)s',
2223 filename=os.path.join(JOY_HOME, 'thun.log'),
@@ -24,12 +25,24 @@
2425 )
2526
2627
28+repo = init_home(JOY_HOME)
29+
30+
2731 from joy.gui.textwidget import TextViewerWidget, tk, get_font, TEXT_BINDINGS
2832 from joy.gui.world import StackDisplayWorld
2933 from joy.library import initialize
3034 from joy.utils.stack import stack_to_string
3135
3236
37+cp = RawConfigParser()
38+cp.optionxform = str # Don't mess with uppercase.
39+with open(os.path.join(args.joy_home, 'thun.config')) as f:
40+ cp.readfp(f)
41+
42+
43+GLOBAL_COMMANDS = dict(cp.items('key bindings'))
44+
45+
3346 tb = TEXT_BINDINGS.copy()
3447 tb.update({
3548 '<F3>': lambda tv: tv.copy_selection_to_stack,
@@ -40,21 +53,6 @@
4053 defaults = dict(text_bindings=tb, width=80, height=25)
4154
4255
43-GLOBAL_COMMANDS = {
44- '<F5>': 'swap',
45- '<F6>': 'dup',
46- '<Shift-F5>': 'roll<',
47- '<Shift-F6>': 'roll>',
48- '<F7>': 'over',
49- '<Shift-F7>': 'tuck',
50- '<F8>': 'parse',
51- '<F12>': 'words',
52- '<F1>': 'reset_log show_log',
53- '<Escape>': 'clear reset_log show_log',
54- '<Control-Delete>': 'pop',
55- }
56-
57-
5856 def repo_relative_path(path):
5957 return os.path.relpath(
6058 path,
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/gui/utils.py
--- a/joy/gui/utils.py Fri Jul 20 12:33:06 2018 -0700
+++ b/joy/gui/utils.py Sat Jul 21 17:56:53 2018 -0700
@@ -1,35 +1,81 @@
1-import os
1+import argparse, os, sys
2+from os import listdir, mkdir
3+from os.path import abspath, exists, expanduser, isfile, join
24
35 from dulwich.errors import NotGitRepository
46 from dulwich.repo import Repo
57
68
7-def init_home():
8- '''
9- Find and initialize the Joy home directory and repository.
10- '''
11- JOY_HOME = os.environ.get('JOY_HOME')
12- if JOY_HOME is None:
13- JOY_HOME = os.path.expanduser('~/.joypy')
14- if not os.path.isabs(JOY_HOME):
15- JOY_HOME = os.path.abspath('./JOY_HOME')
16- #print 'JOY_HOME=' + JOY_HOME
9+COMMITTER = 'Joy <auto-commit@example.com>'
10+DEFAULT_JOY_HOME = '~/.joypy'
1711
18- if not os.path.exists(JOY_HOME):
19- #print 'creating...'
20- os.makedirs(JOY_HOME, 0700)
21- #print 'initializing git repository...'
22- repo = Repo.init(JOY_HOME)
2312
24- else: # path does exist
25- try:
26- repo = Repo(JOY_HOME)
27- except NotGitRepository:
28- #print 'initializing git repository...'
29- repo = Repo.init(JOY_HOME)
30- #else:
31- #print 'opened git repository.'
32- return JOY_HOME, repo
13+def home_dir(path):
14+ '''Return the absolute path of an existing directory.'''
15+
16+ fullpath = expanduser(path) if path.startswith('~') else abspath(path)
17+
18+ if not exists(fullpath):
19+ if path == DEFAULT_JOY_HOME:
20+ print 'Creating JOY_HOME', repr(fullpath)
21+ mkdir(fullpath, 0700)
22+ else:
23+ print >> sys.stderr, repr(fullpath), "doesn't exist."
24+ raise ValueError(path)
25+
26+ return fullpath
27+
28+
29+def init_home(fullpath):
30+ '''
31+ Open or create the Repo.
32+ If there are contents in the dir but it's not a git repo, quit.
33+ '''
34+ try:
35+ repo = Repo(fullpath)
36+ except NotGitRepository:
37+ print >> sys.stderr, repr(fullpath), "no repository"
38+
39+ if listdir(fullpath):
40+ print >> sys.stderr, repr(fullpath), "has contents\nQUIT."
41+ sys.exit(2)
42+
43+ print 'Initializing repository in', fullpath
44+ repo = init_repo(fullpath)
45+
46+ print 'Using repository in', fullpath
47+ return repo
48+
49+
50+def init_repo(repo_dir):
51+ '''
52+ Create a repo, load the initial content, and make the first commit.
53+ Return the Repo object.
54+ '''
55+ repo = Repo.init(repo_dir)
56+ import joy.gui.init_joy_home
57+ joy.gui.init_joy_home.initialize(repo_dir)
58+ repo.stage([
59+ fn
60+ for fn in listdir(repo_dir)
61+ if isfile(join(repo_dir, fn))
62+ ])
63+ repo.do_commit('Initial commit.', committer=COMMITTER)
64+ return repo
65+
66+
67+argparser = argparse.ArgumentParser(
68+ description='Experimental Brutalist UI for Joy.',
69+ )
70+
71+
72+argparser.add_argument(
73+ '-j', '--joy-home',
74+ help='Use a directory other than %s as JOY_HOME' % DEFAULT_JOY_HOME,
75+ default=DEFAULT_JOY_HOME,
76+ dest='joy_home',
77+ type=home_dir,
78+ )
3379
3480
3581 class FileFaker(object):
diff -r 8ea49c3dec9f -r 1f58e8050272 joy/utils/types.py
--- a/joy/utils/types.py Fri Jul 20 12:33:06 2018 -0700
+++ b/joy/utils/types.py Sat Jul 21 17:56:53 2018 -0700
@@ -1,4 +1,22 @@
11 # -*- coding: utf_8
2+#
3+# Copyright © 2018 Simon Forman
4+#
5+# This file is part of Thun
6+#
7+# Thun is free software: you can redistribute it and/or modify
8+# it under the terms of the GNU General Public License as published by
9+# the Free Software Foundation, either version 3 of the License, or
10+# (at your option) any later version.
11+#
12+# Thun is distributed in the hope that it will be useful,
13+# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+# GNU General Public License for more details.
16+#
17+# You should have received a copy of the GNU General Public License
18+# along with Thun. If not see <http://www.gnu.org/licenses/>.
19+#
220 from logging import getLogger, addLevelName
321
422 _log = getLogger(__name__)
Show on old repository browser