index.md (5945B)
1 # Dunlin - a extensible Fennel-based web browser 2 3 <img src="dunlin.png" data-align="right" style="width: 33%" /> 4 5 > The dunlin (Calidris alpina) is a small wader. It is a circumpolar 6 > breeder in Arctic or subarctic regions. Birds that breed in northern 7 > Europe and Asia are long-distance migrants, wintering south to Africa, 8 > southeast Asia and the Middle East. Birds that breed in Alaska and the 9 > Canadian Arctic migrate short distances to the Pacific and Atlantic 10 > coasts of North America, although those nesting in northern Alaska 11 > overwinter in Asia. 12 13 Dunlin is a GTK-based Webkit browser which can be extended in (indeed, 14 is mostly written in) [Fennel](https://www.fennel-lang.org). 15 16 ## Why does the world need another half-assed Webkit browser? 17 18 It doesn't, really. But me, personally, I think I do. I want 19 a browser that lets me easily customize it to do things 20 like: 21 22 * watch a local html file and reload when it changes 23 * find the open tab for my home Fediverse instance (or open one if 24 needed) and post a message/share a link to what I'm looking at 25 * search the {Lua reference, Ruby docs, GTK docs} for a given term 26 instead of wading through the SEO cesspool that is the internet in 27 2022 28 * search in previously "liked" pages for the thing I found three weeks 29 ago, instead of ... ditto 30 * find the tab that's playing music and pause the player (instead of 31 muting it) 32 * more stuff I haven't thought of 33 34 Full disclosure: Dunlin today can do none of these things - or much of 35 anything else either, right now - but if I borrow enough design 36 decisions from Emacs, I hope some day it will. 37 38 ## Installation and getting started 39 40 If you're using Nix, you can run `nix-shell` to pull all the 41 dependencies. Otherwise ... apt-get and Luarocks? Refer to 42 `default.nix` and `shell.nix`, and obtain: 43 44 * All Lua packages listed in any `lua5_3.withPackages` stanza 45 * All system packages listed in any `buildInputs` or `nativeBuildInputs` 46 stanzas. 47 48 To run the browser, 49 50 ```sh 51 $ fennel dunlin.fnl 52 ``` 53 54 Dunlin will open a socket in `$XDG_RUNTIME_DIR` to allow communication 55 with a Fennel REPL. You can run the `repl.sh` script to connect to it 56 with [socat](http://www.dest-unreach.org/socat/). 57 58 ### Running tests 59 60 Tests are in `test/*.fnl`. The test coverage is not 100% nor will it 61 ever be, probably: tests exist only for the bits that were hard to 62 write (algorithmically complex) and easy to test (not full of UI). 63 64 `make watch` will watch the filesystem in this directory and run the 65 tests whenever something changes. 66 67 ### Running everything 68 69 There's a `Procfile` that starts the test runner and a Fennel repl and 70 probably in time some other useful things. I use it with [Overmind](https://github.com/DarthSim/overmind#readme) - `overmind start -D; overmind connect` 71 to create a tmux session. 72 73 ## Customizing 74 75 _This is all quite fluid right now and I reserve the right to change 76 things_. In particular, I anticipate the need to bind to non-key events 77 (mouse events, on-screen buttons, touch gestures) 78 79 (Among) the concepts you need to know here are "commands" and "bindings". 80 81 * A "command" is a chunk of code that may be invoked interactively, 82 plus a descrition of the parameters it needs and their default values. 83 For example, `visit-location` needs a `url` parameter for the location 84 and a `buffer` parameter that says which tab should visit it. 85 86 * A "binding" is a sequence of keystrokes which map to a command: it 87 may supply zero or more parameter values to the command. For example, 88 (as of git commit cde0b8cd56d; YMMV if you're reading this significantly 89 before or after 2022-12-23) the `g` binding invokes `visit-location` 90 with the `buffer` parameter set to `main`, and the `url` parameter 91 unset. 92 93 When a command is invoked without all parameter values, Dunlin will 94 prompt for each missing parameter in the "commander" text entry widget. 95 A command with no binding may be invoked by pressing `M-x` (hold down 96 the "meta" or "alt" key and press `x`) and then typing the command name. 97 98 To see how commands are implemented, read the code in `command.fnl`. 99 There is a simple keymap in `dunlin.fnl`, and you can see the details 100 of how keymaps work in `keymap.fnl` 101 102 When writing key bindings or printing errors, Dunlin assumes that the 103 key producing "Mod 1" (often labelled Alt) is the Meta key, and the 104 key producing "Mod 4" (on a PC, typically the key with the Windows logo) 105 is the Super key. For me this matches how Emacs does it, but I would 106 welcome reports of machines/setups that don't act ths way 107 108 109 ## Fennel style 110 111 https://fennel-lang.org/style is my style bible, although there are 112 places I have departed from it. In particular, I have used CamelCase 113 to name several modules which act as classes, so that I can 114 distinguish `buffer` (an object which represents a buffer, and 115 understands messages like `visit` or `name` or `location`) from 116 `Buffer` (the factory which instantiates `buffer` objects). There is 117 probably a nicer way to do this, but I haven't found it yet. 118 119 120 ## Contributing 121 122 If you like (or see the potential in) Dunlin enough to want to 123 contribute to it, that is awesome and you have just made my day! 124 125 However, I need to point out that it's under active development: 126 my vision for how it'll end up is indefinite in some places and 127 poorly articulated in others. So, please, don't send me code 128 that you're personally invested in and would be disappointed if 129 I reject/ignore it because it doesn't fit some plan that you 130 didn't know about when you wrote it. 131 132 You can checkout Dunlin from https://gti.telent.net/dan/dunlin. I 133 haven't put it on Github because I have uneasy feelings about the 134 ongoing centralisation of Open Source, but certainly don't let that 135 stop you. You can [email me your change](mailto:dan@telent.net) as a 136 patch, or you can point me at code on your preferred source code 137 hosting service - whatever works for you. I reserve the right to be 138 less flexible in future if I start drowning in changes.