[{"data":1,"prerenderedAt":225},["ShallowReactive",2],{"$f3mzwx8w9qkp2c":3},{"title":4,"date":5,"tags":6,"categories":10,"cover_image":11,"draft":12,"_id":13,"slug":14,"path":15,"document":16,"excerpt":223,"readingTimeMinutes":224},"Impressions of Fennel with Hammerspoon","2023-10-22T00:00:00.000Z",[7,8,9],"lisp","hammerspoon","fennel",[7],"\u002Fimages\u002Fdall-e-fennel-hammer.jpeg",false,"content:blog:fennel-initial-exploration","fennel-initial-exploration","\u002Fblog\u002Ffennel-initial-exploration",{"frontmatter":17,"meta":18,"nodes":19},{},{},[20,24,28,47,52,60,64,81,100,107,122,131,135,151,156,162,170,175,180,187,191,194,202,208,211,213,215,217,219,221],[21,22,23],"p",{},"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.",[25,26,27],null,{},"more",[21,29,30,31,36,37,41,42,46],{},"The ",[32,33,35],"a",{"href":34},"https:\u002F\u002Ffennel-lang.org\u002F","Fennel"," programming language is a dialect of Lisp that boasts compatibility with\nLua, and it just so happens that two of my favorite applications are configured with\nexactly that language: ",[32,38,40],{"href":39},"https:\u002F\u002Fwww.hammerspoon.org\u002F","Hammerspoon",", and ",[32,43,45],{"href":44},"https:\u002F\u002Fneovim.io\u002F","Neovim",".",[48,49,51],"h2",{"id":50},"initial-observations","Initial Observations",[21,53,54,55,59],{},"To initially explore Fennel, I wanted to start small. My Hammerspoon configuration\nconsists of 7 ",[32,56,58],{"href":57},"https:\u002F\u002Fgithub.com\u002Fcmpadden\u002Fdotfiles\u002Ftree\u002F795749fa17e1310bb001bb7deaa22be8689f0027\u002Fhammerspoon\u002F.hammerspoon\u002Fmodules","modules"," that I use for operations such as: launching applications,\nmanaging windows, keeping my computer from going to sleep, and general operating system\nautomation. So the plan is to translate these modules into Fennel, while maintaining\nwithout breaking the existing functionality. However, at this point, I wasn't even sure\nhow to embed Fennel into my project...",[48,61,63],{"id":62},"integrating-fennel-with-hammerspoon","Integrating Fennel with Hammerspoon",[21,65,66,67,71,72,76,77,80],{},"While official documentation exists describing how to ",[32,68,70],{"href":69},"https:\u002F\u002Ffennel-lang.org\u002Fsetup#embedding-fennel","embed fennel"," into your\nproject; it didn't provide me with enough clarity to know my next steps on integrating\nit with Hammerspoon. I found a few resources online demonstrating how to extend the\n",[73,74,75],"code",{},"package.path"," and ",[73,78,79],{},"package.cpath"," properties in Lua, but I was unable to get this to\nwork.",[82,83,84,90,95],"ul",{},[85,86,87],"li",{},[32,88,89],{"href":89},"https:\u002F\u002Fblog.exupero.org\u002Fhammerspoon-with-fennel\u002F",[85,91,92],{},[32,93,94],{"href":94},"https:\u002F\u002Fgithub.com\u002FHammerspoon\u002Fhammerspoon\u002Fissues\u002F2377#issuecomment-636331435",[85,96,97],{},[32,98,99],{"href":99},"https:\u002F\u002Fgithub.com\u002Fagzam\u002Fspacehammer\u002Fblob\u002Fmaster\u002Finit.lua",[21,101,102,103,106],{},"Ultimately, I opted to include the ",[73,104,105],{},"fennel.lua"," file to my Hammerspoon configuration,\nand while not ideal, it does make the configuration nicely self-contained. I'll leave it\nas a future task to include the module installed with LuaRocks.",[21,108,109,110,113,114,117,118,121],{},"With Fennel now included in my Hammerspoon configuration, all I need to do is configure\nthe ",[73,111,112],{},"fennel.path"," to point to the ",[73,115,116],{},"*.fnl"," files in the ",[73,119,120],{},".hammerspoon\u002F"," directory, and\nttranslating these modules can begin!",[123,124,127],"pre",{"language":125,"class":126},"lua","shiki dark:tokyo-night",[73,128,130],{"class":129},"language-lua","-- init.lua\n\nlocal fennel = require('fennel')\n\nfennel.path = package.path .. \";\" .. os.getenv(\"HOME\") .. \"\u002F.hammerspoon\u002F?.fnl\"\n\ntable.insert(package.loaders or package.searchers, fennel.searcher)\n\nrequire 'main'",[48,132,134],{"id":133},"translating-lua-to-fennel","Translating Lua to Fennel",[21,136,137,138,142,143,146,147,150],{},"As a Fennel novice, I was happy to see that the Fennel project provides an online\ncross-compiler for Lua and Fennel called ",[32,139,141],{"href":140},"https:\u002F\u002Ffennel-lang.org\u002Fsee","anti-fennel",", and while it can generate some\nstrange-looking Fennel code, it was an extremely useful tool for me to get\nup-and-running right away. For example, by pasting the simple ",[73,144,145],{},"sleep"," function\nfrom the ",[73,148,149],{},"helpers"," module into the compiler:",[123,152,153],{"language":125,"class":126},[73,154,155],{"class":129},"function sleep(ms)\n    os.execute(\"sleep \" .. tonumber(ms) \u002F 1000)\nend",[123,157,158],{"language":7,"class":126},[73,159,161],{"class":160},"language-lisp","(fn sleep [ms]\n  (os.execute (.. \"sleep \" (\u002F (tonumber ms) 1000))))",[21,163,164,165,169],{},"As another example, here is the output for my ",[166,167,168],"em",{},"caffeine"," toggle:",[123,171,172],{"language":125,"class":126},[73,173,174],{"class":129},"hs.hotkey.bind(HYPER, \"0\", function()\n  hs.caffeinate.toggle(\"displayIdle\")\n  if hs.caffeinate.get(\"displayIdle\") then\n    helpers:show(\"Caffeine Enabled\", nil, helpers.styles.success, helpers.assets.check)\n  else\n    helpers:show(\"Caffeine Disabled\", nil, helpers.styles.error, helpers.assets.ban)\n  end\nend)",[123,176,177],{"language":7,"class":126},[73,178,179],{"class":160},"(hs.hotkey.bind HYPER :0\n  (fn [] (hs.caffeinate.toggle :displayIdle)\n    (if (hs.caffeinate.get :displayIdle)\n      (helpers:show \"Caffeine Enabled\" nil helpers.styles.success helpers.assets.check)\n      (helpers:show \"Caffeine Disabled\" nil helpers.styles.error helpers.assets.ban))))\t",[21,181,182,183,186],{},"This was especially helpful for more gnarly modules like the ",[73,184,185],{},"window"," module used for\nwindow management, and seeing the Lua and Fennel code side-by-side was a kick starter in\nlearning the language!",[48,188,190],{"id":189},"next-steps","Next Steps",[21,192,193],{},"While my Fennel Hammerspoon configuration now works with parity to its Lua counterpart,\nI have not yet added new features or modules. I look forward to writing new Fennel code,\nand deepen my understanding of Lisp and the Fennel programming language.",[21,195,196,197,201],{},"Additionally, before beginning this endeavor, I was already aware of projects like\n",[32,198,200],{"href":199},"https:\u002F\u002Fgithub.com\u002Fagzam\u002Fspacehammer","spacehammer","; a wildly impressive Hammerspoon configuration written in Fennel, but,\nI wanted to start small and learn the integration myself. However, with the basics out\nof the way, I hope to explore this project further, and seek lessons-learned for the\nconfiguration of my own.",[21,203,204,205],{},"The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be\nfound here: ",[32,206,207],{"href":207},"https:\u002F\u002Fgithub.com\u002Fcmpadden\u002Fdotfiles\u002Fpull\u002F19\u002Ffiles",[209,210],"component",{},[209,212],{},[209,214],{},[209,216],{},[209,218],{},[209,220],{},[209,222],{},"A while back I read an introductory book on Lisp programming titled, \"The Little Schemer\". This book opened my mind to new (to me) programming paradigms, and left me with a strong desire to find a way to incorporate Lisp programming into my every day life. It took some time, but I believe I've found what I've been looking for: Fennel.",3,1790648870266]