README.org
September 8, 2025 ยท View on GitHub
-
hurl-mode An Emacs major mode for [[https://hurl.dev/][hurl]], a cli tool for sending HTTP requests (using cURL under the hood) in plain text format similar to [[https://github.com/pashky/restclient.el][restclient.el]] (now archived), but can be used outside emacs and also has some additional testing utilities built in.
-
Usage
- =C-c x= will execute the hurl request at point in a temporary file created using the same directory as the original.
- =C-c X= will execute the entire hurl file.
- =C-c T= will execute the hurl file in test mode. Executing any of the commands with a prefix arg will prompt for additional hurl switches.
** Variables
If a hurl variable file, hurl-variable-file (default is =.hurl-variables=) exists in the same directory as the .hurl file we're executing, the variables will automatically be added to the request.
Any captures made in the request will also automatically be appended to the hurl-variables-file.
** Secrets
If a hurl-secrets-file exists then hurl-mode will automatically add a --secret option for each secret specified in the file.
The format of this should be the same as value provided to the hurl --secret option i.e.
#+begin_example API_KEY=secret OTHER_API_KEY=other_secret #+end_example
It's recommended that this file be encrypted in some way. Currently only GPG is supported (since Emacs supports it natively).
TODO: allow users to insert their own decryption hook to read the secrets for other non-gpg encryption methods.
** Org Babel Integration Simple org babel implementation that passes the src block vars into the --variable option for the cli command. Secrets can also be added via =:secret= header, although not sure how useful that would be.
Simple example: #+begin_example ,#+begin_src hurl :results output :var host="https://httpbin.org/post" :secret token="mytoken" POST {{host}} ,#+end_src #+end_example
** Response Output
Will try to format using jSon-pretty-print with font-locking by json-mode.
If json-pretty-print fails we'll fall back to using =jq= if its available.
In my effort to extract the response so I can do some formatting, I've trimmed down some of verbosity of the output from hurl. You can find the buffer that contains all the verbose output by searching for some sort of "*hurl-" buffer.
There's a separate mode for the hurl response buffer. Outline-minor-mode is automatically enabled in the response buffer with some custom outline methods. This makes it easy to navigate and see all the responses from the very-verbose output.
*** Image output If we detect an image content type, we'll try to parse it and display it in the response buffer.
To output the image to a file as well. #+begin_src hurl [Options] output: outputfile #+end_src
** Screenshot | [[file:screenshots/dark.png]] | [[file:screenshots/light.png]] |
- Customization
hurl-secrets-fileChange the secrets file hurl mode will use to send secrets via the --secret option.
hurl-variables-file Change the default variables file used in hurl requests made by hurl-mode. Defaults to ".hurl-variables"
hurl-mode-use-netrc-file If this is t, hurl-mode will automatically include the --netrc-file option, using hurl-mode-netrc-file. Defaults to nil.
hurl-mode-netrc-file Change the netrc file used in requests amde by hurl-mode.
hurl-mode-use-json-ts-mode If this is t, try and fontify =json= request bodies using json-ts-mode, otherwise hurl-mode will try to use =json-mode=. Regardless, if neither of these are available, no fontification will be done on the body. Defaults to t.
hurl-use-fast-process-settings If this is t, tunes read-process-output-max process-adaptive-read-buffering to make the hurl process a little faster. Defaults to t.
- Installation With emacs 29 we have built in package-vc-install and use-package now #+begin_src elisp (package-vc-install "https://github.com/JasZhe/hurl-mode") (use-package hurl-mode :mode "\.hurl\'") #+end_src
With straight: #+begin_src elisp (straight-use-package '(hurl-mode :type git :host github :repo "jaszhe/hurl-mode")) #+end_src
With doom: #+begin_src elisp (package! hurl-mode :recipe (:host github :repo "jaszhe/hurl-mode" :files ("*.el"))) #+end_src
Add to auto mode alist #+begin_src elisp (add-to-list 'auto-mode-alist '("\.hurl\'" . hurl-mode)) #+end_src
- Motivation Hurl does have an existing mode included [[https://github.com/Orange-OpenSource/hurl/tree/master/contrib/emacs][here]] but it was lacking some QOL features that I wanted like body highlighting depending on what language the body was in i.e. json/graphql
I created this repo so that it would be easier for me to incorporate requested changes from the emacs community.
Prior to this I was using the excellent [[https://github.com/pashky/restclient.el][restclient.el]] but I liked hurl because it's a little more portable than sharing curl scripts to non-emacs users (albeit they need to have hurl installed)
Lastly, I also used this as an exercise to learn more about emacs lisp and how major modes are structured and as a way to give back to this wonderful editor known as emacs.
- Contributing I'm mostly using this as a nice text-based replacement for postman, hence maybe I'm not really using =hurl= to its fullest. I'm open to any issues for those who use some of the other features of =hurl= that are lacking in this little package of mine.
I mostly wrote this for two reasons, one to have some basic font locking and stuff for hurl (and also org babel integration where I find it most useful actually) and to learn a bit more elisp.
I won't stop people from making PR's but given the above, I would actually like to tackle any issues myself first :) if you would bear with my inexperience. Pointers and advice in the issues would also be appreciated for the same reason.
- Acknowledgements Took a lot of inspiration for the extend region function from [[https://github.com/nex3/haml-mode][haml-mode]] (no longer using extend region, instead sort of using the same hackyish method that org babel uses)
Also found this example very useful for [[https://stackoverflow.com/questions/9452615/emacs-is-there-a-clear-example-of-multi-line-font-locking][multi line font locking]]
Another good resource [[https://www.omarpolo.com/post/writing-a-major-mode.html][here]]
The code in org for fontifying src blocks was also very useful, more info in the code. Also found [[https://fuco1.github.io/2017-06-01-The-absolute-awesomeness-of-anchored-font-lock-matchers.html][this]] pretty useful for demystifying how the anchored [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Search_002dbased-Fontification.html][search-based fontification]] worked.